mirror of
https://github.com/raspberrypi/linux.git
synced 2025-12-06 01:49:46 +00:00
MMC: added alternative MMC driver
mmc: Disable CMD23 transfers on all cards Pending wire-level investigation of these types of transfers and associated errors on bcm2835-mmc, disable for now. Fallback of CMD18/CMD25 transfers will be used automatically by the MMC layer. Reported/Tested-by: Gellert Weisz <gellert@raspberrypi.org> mmc: bcm2835-mmc: enable DT support for all architectures Both ARCH_BCM2835 and ARCH_BCM270x are built with OF now. Enable Device Tree support for all architectures. Signed-off-by: Noralf Trønnes <noralf@tronnes.org> mmc: bcm2835-mmc: fix probe error handling Probe error handling is broken in several places. Simplify error handling by using device managed functions. Replace pr_{err,info} with dev_{err,info}. Signed-off-by: Noralf Trønnes <noralf@tronnes.org> bcm2835-mmc: Add locks when accessing sdhost registers bcm2835-mmc: Add range of debug options for slowing things down bcm2835-mmc: Add option to disable some delays bcm2835-mmc: Add option to disable MMC_QUIRK_BLK_NO_CMD23 bcm2835-mmc: Default to disabling MMC_QUIRK_BLK_NO_CMD23 bcm2835-mmc: Adding overclocking option Allow a different clock speed to be substitued for a requested 50MHz. This option is exposed using the "overclock_50" DT parameter. Note that the mmc interface is restricted to EVEN integer divisions of 250MHz, and the highest sensible option is 63 (250/4 = 62.5), the next being 125 (250/2) which is much too high. Use at your own risk. bcm2835-mmc: Round up the overclock, so 62 works for 62.5Mhz Also only warn once for each overclock setting. mmc: bcm2835-mmc: Make available on ARCH_BCM2835 Make the bcm2835-mmc driver available for use on ARCH_BCM2835. Signed-off-by: Noralf Trønnes <noralf@tronnes.org> BCM270x_DT: add bcm2835-mmc entry Add Device Tree entry for bcm2835-mmc. In non-DT mode, don't add the device in the board file. Signed-off-by: Noralf Trønnes <noralf@tronnes.org> bcm2835-mmc: Don't overwrite MMC capabilities from DT bcm2835-mmc: Don't override bus width capabilities from devicetree Take out the force setting of the MMC_CAP_4_BIT_DATA host capability so that the result read from devicetree via mmc_of_parse() is preserved. bcm2835-mmc: Only claim one DMA channel With both MMC controllers enabled there are few DMA channels left. The bcm2835-mmc driver only uses DMA in one direction at a time, so it doesn't need to claim two channels. See: https://github.com/raspberrypi/linux/issues/1327 Signed-off-by: Phil Elwell <phil@raspberrypi.org> bcm2835-mmc: New timer API mmc: bcm2835-mmc: Support underclocking Support underclocking of the SD bus using the max-frequency DT property (which currently has no DT parameter). The sd_overclock parameter already provides another way to achieve the same thing which should be equivalent in end result, but it is a bug not to support max-frequency as well. See: https://github.com/raspberrypi/linux/issues/2350 Signed-off-by: Phil Elwell <phil@raspberrypi.org> mmc/bcm2835: Recover from MMC_SEND_EXT_CSD If the user issues an "mmc extcsd read", the SD controller receives what it thinks is a SEND_IF_COND command with an unexpected data block. The resulting operations leave the FSM stuck in READWAIT, a state which persists until the MMC framework resets the controller, by which point the root filesystem is likely to have been unmounted. A less heavyweight solution is to detect the condition and nudge the FSM by asserting the (self-clearing) FORCE_DATA_MODE bit. N.B. This workaround was essentially discovered by accident and without a full understanding the inner workings of the controller, so it is fortunate that the "fix" only modifies error paths. See: https://github.com/raspberrypi/linux/issues/2728 Signed-off-by: Phil Elwell <phil@raspberrypi.org> bcm2835-mmc: Fix DMA channel leak The BCM2835 MMC host driver requests a DMA channel on probe but neglects to release the channel in the probe error path and on driver unbind. I'm seeing this happen on every boot of the Compute Module 3: On first driver probe, DMA channel 2 is allocated and then leaked with a "could not get clk, deferring probe" message. On second driver probe, channel 4 is allocated. Fix it. Signed-off-by: Lukas Wunner <lukas@wunner.de> Cc: Frank Pavlic <f.pavlic@kunbus.de> bcm2835-mmc: Fix struct mmc_host leak on probe The BCM2835 MMC host driver requests the bus address of the host's register map on probe. If that fails, the driver leaks the struct mmc_host allocated earlier. Fix it. Signed-off-by: Lukas Wunner <lukas@wunner.de> Cc: Frank Pavlic <f.pavlic@kunbus.de> bcm2835-mmc: Fix duplicate free_irq() on remove The BCM2835 MMC host driver requests its interrupt as a device-managed resource, so the interrupt is automatically freed after the driver is unbound. However on driver unbind, bcm2835_mmc_remove() frees the interrupt explicitly to avoid invocation of the interrupt handler after driver structures have been torn down. The interrupt is thus freed twice, leading to a WARN splat in __free_irq(). Fix by not requesting the interrupt as a device-managed resource. Signed-off-by: Lukas Wunner <lukas@wunner.de> Cc: Frank Pavlic <f.pavlic@kunbus.de> bcm2835-mmc: Handle mmc_add_host() errors The BCM2835 MMC host driver calls mmc_add_host() but doesn't check its return value. Errors occurring in that function are therefore not handled. Fix it. Signed-off-by: Lukas Wunner <lukas@wunner.de> Cc: Frank Pavlic <f.pavlic@kunbus.de> bcm2835-mmc: Deduplicate reset of driver data on remove The BCM2835 MMC host driver sets the device's driver data pointer to NULL on ->remove() even though the driver core subsequently does the same in __device_release_driver(). Drop the duplicate assignment. Signed-off-by: Lukas Wunner <lukas@wunner.de> Cc: Frank Pavlic <f.pavlic@kunbus.de>
This commit is contained in:
@@ -166,6 +166,13 @@ static DEFINE_MUTEX(open_lock);
|
||||
module_param(perdev_minors, int, 0444);
|
||||
MODULE_PARM_DESC(perdev_minors, "Minors numbers to allocate per device");
|
||||
|
||||
/*
|
||||
* Allow quirks to be overridden for the current card
|
||||
*/
|
||||
static char *card_quirks;
|
||||
module_param(card_quirks, charp, 0644);
|
||||
MODULE_PARM_DESC(card_quirks, "Force the use of the indicated quirks (a bitfield)");
|
||||
|
||||
static inline int mmc_blk_part_switch(struct mmc_card *card,
|
||||
unsigned int part_type);
|
||||
|
||||
@@ -2904,6 +2911,7 @@ static int mmc_blk_probe(struct mmc_card *card)
|
||||
{
|
||||
struct mmc_blk_data *md, *part_md;
|
||||
char cap_str[10];
|
||||
char quirk_str[24];
|
||||
|
||||
/*
|
||||
* Check that the card supports the command class(es) we need.
|
||||
@@ -2911,7 +2919,16 @@ static int mmc_blk_probe(struct mmc_card *card)
|
||||
if (!(card->csd.cmdclass & CCC_BLOCK_READ))
|
||||
return -ENODEV;
|
||||
|
||||
mmc_fixup_device(card, mmc_blk_fixups);
|
||||
if (card_quirks) {
|
||||
unsigned long quirks;
|
||||
if (kstrtoul(card_quirks, 0, &quirks) == 0)
|
||||
card->quirks = (unsigned int)quirks;
|
||||
else
|
||||
pr_err("mmc_block: Invalid card_quirks parameter '%s'\n",
|
||||
card_quirks);
|
||||
}
|
||||
else
|
||||
mmc_fixup_device(card, mmc_blk_fixups);
|
||||
|
||||
card->complete_wq = alloc_workqueue("mmc_complete",
|
||||
WQ_MEM_RECLAIM | WQ_HIGHPRI, 0);
|
||||
@@ -2926,9 +2943,14 @@ static int mmc_blk_probe(struct mmc_card *card)
|
||||
|
||||
string_get_size((u64)get_capacity(md->disk), 512, STRING_UNITS_2,
|
||||
cap_str, sizeof(cap_str));
|
||||
pr_info("%s: %s %s %s %s\n",
|
||||
if (card->quirks)
|
||||
snprintf(quirk_str, sizeof(quirk_str),
|
||||
" (quirks 0x%08x)", card->quirks);
|
||||
else
|
||||
quirk_str[0] = '\0';
|
||||
pr_info("%s: %s %s %s%s%s\n",
|
||||
md->disk->disk_name, mmc_card_id(card), mmc_card_name(card),
|
||||
cap_str, md->read_only ? "(ro)" : "");
|
||||
cap_str, md->read_only ? " (ro)" : "", quirk_str);
|
||||
|
||||
if (mmc_blk_alloc_parts(card, md))
|
||||
goto out;
|
||||
|
||||
@@ -1920,7 +1920,8 @@ EXPORT_SYMBOL(mmc_erase);
|
||||
int mmc_can_erase(struct mmc_card *card)
|
||||
{
|
||||
if ((card->host->caps & MMC_CAP_ERASE) &&
|
||||
(card->csd.cmdclass & CCC_ERASE) && card->erase_size)
|
||||
(card->csd.cmdclass & CCC_ERASE) && card->erase_size &&
|
||||
!(card->quirks & MMC_QUIRK_ERASE_BROKEN))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -400,15 +400,30 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
|
||||
{
|
||||
int err;
|
||||
struct mmc_host *host;
|
||||
int id;
|
||||
|
||||
host = kzalloc(sizeof(struct mmc_host) + extra, GFP_KERNEL);
|
||||
if (!host)
|
||||
return NULL;
|
||||
|
||||
/* If OF aliases exist, start dynamic assignment after highest */
|
||||
id = of_alias_get_highest_id("mmc");
|
||||
id = (id < 0) ? 0 : id + 1;
|
||||
|
||||
/* If this devices has OF node, maybe it has an alias */
|
||||
if (dev->of_node) {
|
||||
int of_id = of_alias_get_id(dev->of_node, "mmc");
|
||||
|
||||
if (of_id < 0)
|
||||
dev_warn(dev, "/aliases ID not available\n");
|
||||
else
|
||||
id = of_id;
|
||||
}
|
||||
|
||||
/* scanning will be enabled when we're ready */
|
||||
host->rescan_disable = 1;
|
||||
|
||||
err = ida_simple_get(&mmc_host_ida, 0, 0, GFP_KERNEL);
|
||||
err = ida_simple_get(&mmc_host_ida, id, 0, GFP_KERNEL);
|
||||
if (err < 0) {
|
||||
kfree(host);
|
||||
return NULL;
|
||||
|
||||
@@ -99,6 +99,14 @@ static const struct mmc_fixup mmc_blk_fixups[] = {
|
||||
MMC_FIXUP("V10016", CID_MANFID_KINGSTON, CID_OEMID_ANY, add_quirk_mmc,
|
||||
MMC_QUIRK_TRIM_BROKEN),
|
||||
|
||||
/*
|
||||
* On some Kingston SD cards, multiple erases of less than 64
|
||||
* sectors can cause corruption.
|
||||
*/
|
||||
MMC_FIXUP("SD16G", 0x41, 0x3432, add_quirk, MMC_QUIRK_ERASE_BROKEN),
|
||||
MMC_FIXUP("SD32G", 0x41, 0x3432, add_quirk, MMC_QUIRK_ERASE_BROKEN),
|
||||
MMC_FIXUP("SD64G", 0x41, 0x3432, add_quirk, MMC_QUIRK_ERASE_BROKEN),
|
||||
|
||||
END_FIXUP
|
||||
};
|
||||
|
||||
|
||||
@@ -5,6 +5,35 @@
|
||||
|
||||
comment "MMC/SD/SDIO Host Controller Drivers"
|
||||
|
||||
config MMC_BCM2835_MMC
|
||||
tristate "MMC support on BCM2835"
|
||||
depends on MACH_BCM2708 || MACH_BCM2709 || ARCH_BCM2835
|
||||
help
|
||||
This selects the MMC Interface on BCM2835.
|
||||
|
||||
If you have a controller with this interface, say Y or M here.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
config MMC_BCM2835_DMA
|
||||
bool "DMA support on BCM2835 Arasan controller"
|
||||
depends on MMC_BCM2835_MMC
|
||||
help
|
||||
Enable DMA support on the Arasan SDHCI controller in Broadcom 2708
|
||||
based chips.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
config MMC_BCM2835_PIO_DMA_BARRIER
|
||||
int "Block count limit for PIO transfers"
|
||||
depends on MMC_BCM2835_MMC && MMC_BCM2835_DMA
|
||||
range 0 256
|
||||
default 2
|
||||
help
|
||||
The inclusive limit in bytes under which PIO will be used instead of DMA
|
||||
|
||||
If unsure, say 2 here.
|
||||
|
||||
config MMC_DEBUG
|
||||
bool "MMC host drivers debugging"
|
||||
depends on MMC != n
|
||||
|
||||
@@ -23,6 +23,7 @@ obj-$(CONFIG_MMC_SDHCI_SIRF) += sdhci-sirf.o
|
||||
obj-$(CONFIG_MMC_SDHCI_F_SDH30) += sdhci_f_sdh30.o
|
||||
obj-$(CONFIG_MMC_SDHCI_SPEAR) += sdhci-spear.o
|
||||
obj-$(CONFIG_MMC_SDHCI_AM654) += sdhci_am654.o
|
||||
obj-$(CONFIG_MMC_BCM2835_MMC) += bcm2835-mmc.o
|
||||
obj-$(CONFIG_MMC_WBSD) += wbsd.o
|
||||
obj-$(CONFIG_MMC_AU1X) += au1xmmc.o
|
||||
obj-$(CONFIG_MMC_ALCOR) += alcor.o
|
||||
|
||||
1585
drivers/mmc/host/bcm2835-mmc.c
Normal file
1585
drivers/mmc/host/bcm2835-mmc.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -270,6 +270,8 @@ struct mmc_card {
|
||||
#define MMC_QUIRK_TRIM_BROKEN (1<<12) /* Skip trim */
|
||||
#define MMC_QUIRK_BROKEN_HPI (1<<13) /* Disable broken HPI support */
|
||||
|
||||
#define MMC_QUIRK_ERASE_BROKEN (1<<31) /* Skip erase */
|
||||
|
||||
bool reenable_cmdq; /* Re-enable Command Queue */
|
||||
|
||||
unsigned int erase_size; /* erase size in sectors */
|
||||
|
||||
Reference in New Issue
Block a user