mirror of
https://github.com/raspberrypi/linux.git
synced 2025-12-07 18:40:10 +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_param(perdev_minors, int, 0444);
|
||||||
MODULE_PARM_DESC(perdev_minors, "Minors numbers to allocate per device");
|
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,
|
static inline int mmc_blk_part_switch(struct mmc_card *card,
|
||||||
unsigned int part_type);
|
unsigned int part_type);
|
||||||
|
|
||||||
@@ -2904,6 +2911,7 @@ static int mmc_blk_probe(struct mmc_card *card)
|
|||||||
{
|
{
|
||||||
struct mmc_blk_data *md, *part_md;
|
struct mmc_blk_data *md, *part_md;
|
||||||
char cap_str[10];
|
char cap_str[10];
|
||||||
|
char quirk_str[24];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check that the card supports the command class(es) we need.
|
* Check that the card supports the command class(es) we need.
|
||||||
@@ -2911,6 +2919,15 @@ static int mmc_blk_probe(struct mmc_card *card)
|
|||||||
if (!(card->csd.cmdclass & CCC_BLOCK_READ))
|
if (!(card->csd.cmdclass & CCC_BLOCK_READ))
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
|
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);
|
mmc_fixup_device(card, mmc_blk_fixups);
|
||||||
|
|
||||||
card->complete_wq = alloc_workqueue("mmc_complete",
|
card->complete_wq = alloc_workqueue("mmc_complete",
|
||||||
@@ -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,
|
string_get_size((u64)get_capacity(md->disk), 512, STRING_UNITS_2,
|
||||||
cap_str, sizeof(cap_str));
|
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),
|
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))
|
if (mmc_blk_alloc_parts(card, md))
|
||||||
goto out;
|
goto out;
|
||||||
|
|||||||
@@ -1920,7 +1920,8 @@ EXPORT_SYMBOL(mmc_erase);
|
|||||||
int mmc_can_erase(struct mmc_card *card)
|
int mmc_can_erase(struct mmc_card *card)
|
||||||
{
|
{
|
||||||
if ((card->host->caps & MMC_CAP_ERASE) &&
|
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 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -400,15 +400,30 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
|
|||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
struct mmc_host *host;
|
struct mmc_host *host;
|
||||||
|
int id;
|
||||||
|
|
||||||
host = kzalloc(sizeof(struct mmc_host) + extra, GFP_KERNEL);
|
host = kzalloc(sizeof(struct mmc_host) + extra, GFP_KERNEL);
|
||||||
if (!host)
|
if (!host)
|
||||||
return NULL;
|
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 */
|
/* scanning will be enabled when we're ready */
|
||||||
host->rescan_disable = 1;
|
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) {
|
if (err < 0) {
|
||||||
kfree(host);
|
kfree(host);
|
||||||
return NULL;
|
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_FIXUP("V10016", CID_MANFID_KINGSTON, CID_OEMID_ANY, add_quirk_mmc,
|
||||||
MMC_QUIRK_TRIM_BROKEN),
|
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
|
END_FIXUP
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,35 @@
|
|||||||
|
|
||||||
comment "MMC/SD/SDIO Host Controller Drivers"
|
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
|
config MMC_DEBUG
|
||||||
bool "MMC host drivers debugging"
|
bool "MMC host drivers debugging"
|
||||||
depends on MMC != n
|
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_F_SDH30) += sdhci_f_sdh30.o
|
||||||
obj-$(CONFIG_MMC_SDHCI_SPEAR) += sdhci-spear.o
|
obj-$(CONFIG_MMC_SDHCI_SPEAR) += sdhci-spear.o
|
||||||
obj-$(CONFIG_MMC_SDHCI_AM654) += sdhci_am654.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_WBSD) += wbsd.o
|
||||||
obj-$(CONFIG_MMC_AU1X) += au1xmmc.o
|
obj-$(CONFIG_MMC_AU1X) += au1xmmc.o
|
||||||
obj-$(CONFIG_MMC_ALCOR) += alcor.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_TRIM_BROKEN (1<<12) /* Skip trim */
|
||||||
#define MMC_QUIRK_BROKEN_HPI (1<<13) /* Disable broken HPI support */
|
#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 */
|
bool reenable_cmdq; /* Re-enable Command Queue */
|
||||||
|
|
||||||
unsigned int erase_size; /* erase size in sectors */
|
unsigned int erase_size; /* erase size in sectors */
|
||||||
|
|||||||
Reference in New Issue
Block a user