diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-01-26 11:00:41 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-01-26 11:00:41 -0800 |
commit | ccc039d65f24172eebab5e0160462d3417799af5 (patch) | |
tree | c02513223bebadd57da5b6648a497f99684111e2 /drivers/mmc/core | |
parent | 1c2948380b699dfdbb25a7de740392dd9e6f0613 (diff) | |
parent | 945be38caa287b177b8c17ffaae7754cab6a658f (diff) |
Merge tag 'mmc-updates-for-3.14-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/cjb/mmc
Pull MMC updates from Chris Ball:
"MMC highlights for 3.14:
Core:
- Avoid get_cd() on cards marked nonremovable
Drivers:
- arasan: New driver for controllers found in e.g. Xilinx Zynq SoC
- dwmmc: Support Hisilicon K3 SoC controllers
- esdhc-imx: Support for HS200 mode, DDR modes on MX6, runtime PM
- sdhci-pci: Support O2Micro/BayHubTech controllers used in laptops
like Lenovo ThinkPad W540, Dell Latitude E5440, Dell Latitude E6540
- tegra: Support Tegra124 SoCs"
* tag 'mmc-updates-for-3.14-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/cjb/mmc: (55 commits)
mmc: sdhci-pci: Fix possibility of chip->fixes being null
mmc: sdhci-pci: Fix BYT sd card getting stuck in runtime suspend
mmc: sdhci: Allow for long command timeouts
mmc: sdio: add a quirk for broken SDIO_CCCR_INTx polling
mmc: sdhci: fix lockdep error in tuning routine
mmc: dw_mmc: k3: remove clk_table
mmc: dw_mmc: fix dw_mci_get_cd
mmc: dw_mmc: fix sparse non static symbol warning
mmc: sdhci-esdhc-imx: fix warning during module remove function
mmc: sdhci-esdhc-imx: fix access hardirq-unsafe lock in atomic context
mmc: core: sd: implement proper support for sd3.0 au sizes
mmc: atmel-mci: add vmmc-supply support
mmc: sdhci-pci: add broken HS200 quirk for Intel Merrifield
mmc: sdhci: add quirk for broken HS200 support
mmc: arasan: Add driver for Arasan SDHCI
mmc: dw_mmc: add dw_mmc-k3 for k3 platform
mmc: dw_mmc: use slot-gpio to handle cd pin
mmc: sdhci-pci: add support of O2Micro/BayHubTech SD hosts
mmc: sdhci-pci: break out definitions to header file
mmc: tmio: fixup compile error
...
Conflicts:
MAINTAINERS
Diffstat (limited to 'drivers/mmc/core')
-rw-r--r-- | drivers/mmc/core/core.c | 3 | ||||
-rw-r--r-- | drivers/mmc/core/mmc.c | 8 | ||||
-rw-r--r-- | drivers/mmc/core/quirks.c | 8 | ||||
-rw-r--r-- | drivers/mmc/core/sd.c | 37 | ||||
-rw-r--r-- | drivers/mmc/core/sdio_irq.c | 11 |
5 files changed, 45 insertions, 22 deletions
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 57a2b403bf8e..098374b1ab2b 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -2460,7 +2460,8 @@ void mmc_rescan(struct work_struct *work) */ mmc_bus_put(host); - if (host->ops->get_cd && host->ops->get_cd(host) == 0) { + if (!(host->caps & MMC_CAP_NONREMOVABLE) && host->ops->get_cd && + host->ops->get_cd(host) == 0) { mmc_claim_host(host); mmc_power_off(host); mmc_release_host(host); diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index f631f5a9bf79..98e9eb0f6643 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -1119,14 +1119,10 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, */ if (mmc_card_highspeed(card)) { if ((card->ext_csd.card_type & EXT_CSD_CARD_TYPE_DDR_1_8V) - && ((host->caps & (MMC_CAP_1_8V_DDR | - MMC_CAP_UHS_DDR50)) - == (MMC_CAP_1_8V_DDR | MMC_CAP_UHS_DDR50))) + && (host->caps & MMC_CAP_1_8V_DDR)) ddr = MMC_1_8V_DDR_MODE; else if ((card->ext_csd.card_type & EXT_CSD_CARD_TYPE_DDR_1_2V) - && ((host->caps & (MMC_CAP_1_2V_DDR | - MMC_CAP_UHS_DDR50)) - == (MMC_CAP_1_2V_DDR | MMC_CAP_UHS_DDR50))) + && (host->caps & MMC_CAP_1_2V_DDR)) ddr = MMC_1_2V_DDR_MODE; } diff --git a/drivers/mmc/core/quirks.c b/drivers/mmc/core/quirks.c index 06ee1aeaacec..6c36fccaa1ec 100644 --- a/drivers/mmc/core/quirks.c +++ b/drivers/mmc/core/quirks.c @@ -13,6 +13,7 @@ #include <linux/kernel.h> #include <linux/export.h> #include <linux/mmc/card.h> +#include <linux/mmc/sdio_ids.h> #ifndef SDIO_VENDOR_ID_TI #define SDIO_VENDOR_ID_TI 0x0097 @@ -30,6 +31,10 @@ #define SDIO_DEVICE_ID_STE_CW1200 0x2280 #endif +#ifndef SDIO_DEVICE_ID_MARVELL_8797_F0 +#define SDIO_DEVICE_ID_MARVELL_8797_F0 0x9128 +#endif + /* * This hook just adds a quirk for all sdio devices */ @@ -58,6 +63,9 @@ static const struct mmc_fixup mmc_fixup_methods[] = { SDIO_FIXUP(SDIO_VENDOR_ID_STE, SDIO_DEVICE_ID_STE_CW1200, add_quirk, MMC_QUIRK_BROKEN_BYTE_MODE_512), + SDIO_FIXUP(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8797_F0, + add_quirk, MMC_QUIRK_BROKEN_IRQ_POLLING), + END_FIXUP }; diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index 6f42050b7ccc..692fdb177294 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c @@ -11,6 +11,7 @@ */ #include <linux/err.h> +#include <linux/sizes.h> #include <linux/slab.h> #include <linux/stat.h> #include <linux/pm_runtime.h> @@ -45,6 +46,13 @@ static const unsigned int tacc_mant[] = { 35, 40, 45, 50, 55, 60, 70, 80, }; +static const unsigned int sd_au_size[] = { + 0, SZ_16K / 512, SZ_32K / 512, SZ_64K / 512, + SZ_128K / 512, SZ_256K / 512, SZ_512K / 512, SZ_1M / 512, + SZ_2M / 512, SZ_4M / 512, SZ_8M / 512, (SZ_8M + SZ_4M) / 512, + SZ_16M / 512, (SZ_16M + SZ_8M) / 512, SZ_32M / 512, SZ_64M / 512, +}; + #define UNSTUFF_BITS(resp,start,size) \ ({ \ const int __size = size; \ @@ -216,7 +224,7 @@ static int mmc_decode_scr(struct mmc_card *card) static int mmc_read_ssr(struct mmc_card *card) { unsigned int au, es, et, eo; - int err, i, max_au; + int err, i; u32 *ssr; if (!(card->csd.cmdclass & CCC_APP_SPEC)) { @@ -240,26 +248,25 @@ static int mmc_read_ssr(struct mmc_card *card) for (i = 0; i < 16; i++) ssr[i] = be32_to_cpu(ssr[i]); - /* SD3.0 increases max AU size to 64MB (0xF) from 4MB (0x9) */ - max_au = card->scr.sda_spec3 ? 0xF : 0x9; - /* * UNSTUFF_BITS only works with four u32s so we have to offset the * bitfield positions accordingly. */ au = UNSTUFF_BITS(ssr, 428 - 384, 4); - if (au > 0 && au <= max_au) { - card->ssr.au = 1 << (au + 4); - es = UNSTUFF_BITS(ssr, 408 - 384, 16); - et = UNSTUFF_BITS(ssr, 402 - 384, 6); - eo = UNSTUFF_BITS(ssr, 400 - 384, 2); - if (es && et) { - card->ssr.erase_timeout = (et * 1000) / es; - card->ssr.erase_offset = eo * 1000; + if (au) { + if (au <= 9 || card->scr.sda_spec3) { + card->ssr.au = sd_au_size[au]; + es = UNSTUFF_BITS(ssr, 408 - 384, 16); + et = UNSTUFF_BITS(ssr, 402 - 384, 6); + if (es && et) { + eo = UNSTUFF_BITS(ssr, 400 - 384, 2); + card->ssr.erase_timeout = (et * 1000) / es; + card->ssr.erase_offset = eo * 1000; + } + } else { + pr_warning("%s: SD Status: Invalid Allocation Unit size.\n", + mmc_hostname(card->host)); } - } else { - pr_warning("%s: SD Status: Invalid Allocation Unit " - "size.\n", mmc_hostname(card->host)); } out: kfree(ssr); diff --git a/drivers/mmc/core/sdio_irq.c b/drivers/mmc/core/sdio_irq.c index 3d8ceb4084de..aaa90460ed23 100644 --- a/drivers/mmc/core/sdio_irq.c +++ b/drivers/mmc/core/sdio_irq.c @@ -53,6 +53,17 @@ static int process_sdio_pending_irqs(struct mmc_host *host) return ret; } + if (pending && mmc_card_broken_irq_polling(card) && + !(host->caps & MMC_CAP_SDIO_IRQ)) { + unsigned char dummy; + + /* A fake interrupt could be created when we poll SDIO_CCCR_INTx + * register with a Marvell SD8797 card. A dummy CMD52 read to + * function 0 register 0xff can avoid this. + */ + mmc_io_rw_direct(card, 0, 0, 0xff, 0, &dummy); + } + count = 0; for (i = 1; i <= 7; i++) { if (pending & (1 << i)) { |