diff options
| -rw-r--r-- | drivers/mmc/card/block.c | 8 | ||||
| -rw-r--r-- | drivers/mmc/core/core.c | 98 | ||||
| -rw-r--r-- | drivers/mmc/core/mmc.c | 12 | ||||
| -rw-r--r-- | drivers/mmc/host/mxcmmc.c | 1 | ||||
| -rw-r--r-- | drivers/mmc/host/omap_hsmmc.c | 7 | ||||
| -rw-r--r-- | drivers/mmc/host/sdhci-cns3xxx.c | 1 | ||||
| -rw-r--r-- | drivers/mmc/host/sdhci-s3c.c | 2 | ||||
| -rw-r--r-- | drivers/mmc/host/sh_mmcif.c | 2 | ||||
| -rw-r--r-- | drivers/mmc/host/tmio_mmc_pio.c | 2 | ||||
| -rw-r--r-- | include/linux/mmc/card.h | 6 |
10 files changed, 95 insertions, 44 deletions
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index a1cb21f95302..1e0e27cbe987 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c | |||
| @@ -1606,6 +1606,14 @@ static const struct mmc_fixup blk_fixups[] = | |||
| 1606 | MMC_QUIRK_BLK_NO_CMD23), | 1606 | MMC_QUIRK_BLK_NO_CMD23), |
| 1607 | MMC_FIXUP("MMC32G", 0x11, CID_OEMID_ANY, add_quirk_mmc, | 1607 | MMC_FIXUP("MMC32G", 0x11, CID_OEMID_ANY, add_quirk_mmc, |
| 1608 | MMC_QUIRK_BLK_NO_CMD23), | 1608 | MMC_QUIRK_BLK_NO_CMD23), |
| 1609 | |||
| 1610 | /* | ||
| 1611 | * Some Micron MMC cards needs longer data read timeout than | ||
| 1612 | * indicated in CSD. | ||
| 1613 | */ | ||
| 1614 | MMC_FIXUP(CID_NAME_ANY, 0x13, 0x200, add_quirk_mmc, | ||
| 1615 | MMC_QUIRK_LONG_READ_TIME), | ||
| 1616 | |||
| 1609 | END_FIXUP | 1617 | END_FIXUP |
| 1610 | }; | 1618 | }; |
| 1611 | 1619 | ||
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 5278ffb20e74..950b97d7412a 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c | |||
| @@ -529,6 +529,18 @@ void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card) | |||
| 529 | data->timeout_clks = 0; | 529 | data->timeout_clks = 0; |
| 530 | } | 530 | } |
| 531 | } | 531 | } |
| 532 | |||
| 533 | /* | ||
| 534 | * Some cards require longer data read timeout than indicated in CSD. | ||
| 535 | * Address this by setting the read timeout to a "reasonably high" | ||
| 536 | * value. For the cards tested, 300ms has proven enough. If necessary, | ||
| 537 | * this value can be increased if other problematic cards require this. | ||
| 538 | */ | ||
| 539 | if (mmc_card_long_read_time(card) && data->flags & MMC_DATA_READ) { | ||
| 540 | data->timeout_ns = 300000000; | ||
| 541 | data->timeout_clks = 0; | ||
| 542 | } | ||
| 543 | |||
| 532 | /* | 544 | /* |
| 533 | * Some cards need very high timeouts if driven in SPI mode. | 545 | * Some cards need very high timeouts if driven in SPI mode. |
| 534 | * The worst observed timeout was 900ms after writing a | 546 | * The worst observed timeout was 900ms after writing a |
| @@ -1213,6 +1225,46 @@ void mmc_set_driver_type(struct mmc_host *host, unsigned int drv_type) | |||
| 1213 | mmc_host_clk_release(host); | 1225 | mmc_host_clk_release(host); |
| 1214 | } | 1226 | } |
| 1215 | 1227 | ||
| 1228 | static void mmc_poweroff_notify(struct mmc_host *host) | ||
| 1229 | { | ||
| 1230 | struct mmc_card *card; | ||
| 1231 | unsigned int timeout; | ||
| 1232 | unsigned int notify_type = EXT_CSD_NO_POWER_NOTIFICATION; | ||
| 1233 | int err = 0; | ||
| 1234 | |||
| 1235 | card = host->card; | ||
| 1236 | |||
| 1237 | /* | ||
| 1238 | * Send power notify command only if card | ||
| 1239 | * is mmc and notify state is powered ON | ||
| 1240 | */ | ||
| 1241 | if (card && mmc_card_mmc(card) && | ||
| 1242 | (card->poweroff_notify_state == MMC_POWERED_ON)) { | ||
| 1243 | |||
| 1244 | if (host->power_notify_type == MMC_HOST_PW_NOTIFY_SHORT) { | ||
| 1245 | notify_type = EXT_CSD_POWER_OFF_SHORT; | ||
| 1246 | timeout = card->ext_csd.generic_cmd6_time; | ||
| 1247 | card->poweroff_notify_state = MMC_POWEROFF_SHORT; | ||
| 1248 | } else { | ||
| 1249 | notify_type = EXT_CSD_POWER_OFF_LONG; | ||
| 1250 | timeout = card->ext_csd.power_off_longtime; | ||
| 1251 | card->poweroff_notify_state = MMC_POWEROFF_LONG; | ||
| 1252 | } | ||
| 1253 | |||
| 1254 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, | ||
| 1255 | EXT_CSD_POWER_OFF_NOTIFICATION, | ||
| 1256 | notify_type, timeout); | ||
| 1257 | |||
| 1258 | if (err && err != -EBADMSG) | ||
| 1259 | pr_err("Device failed to respond within %d poweroff " | ||
| 1260 | "time. Forcefully powering down the device\n", | ||
| 1261 | timeout); | ||
| 1262 | |||
| 1263 | /* Set the card state to no notification after the poweroff */ | ||
| 1264 | card->poweroff_notify_state = MMC_NO_POWER_NOTIFICATION; | ||
| 1265 | } | ||
| 1266 | } | ||
| 1267 | |||
| 1216 | /* | 1268 | /* |
| 1217 | * Apply power to the MMC stack. This is a two-stage process. | 1269 | * Apply power to the MMC stack. This is a two-stage process. |
| 1218 | * First, we enable power to the card without the clock running. | 1270 | * First, we enable power to the card without the clock running. |
| @@ -1269,42 +1321,12 @@ static void mmc_power_up(struct mmc_host *host) | |||
| 1269 | 1321 | ||
| 1270 | void mmc_power_off(struct mmc_host *host) | 1322 | void mmc_power_off(struct mmc_host *host) |
| 1271 | { | 1323 | { |
| 1272 | struct mmc_card *card; | ||
| 1273 | unsigned int notify_type; | ||
| 1274 | unsigned int timeout; | ||
| 1275 | int err; | ||
| 1276 | |||
| 1277 | mmc_host_clk_hold(host); | 1324 | mmc_host_clk_hold(host); |
| 1278 | 1325 | ||
| 1279 | card = host->card; | ||
| 1280 | host->ios.clock = 0; | 1326 | host->ios.clock = 0; |
| 1281 | host->ios.vdd = 0; | 1327 | host->ios.vdd = 0; |
| 1282 | 1328 | ||
| 1283 | if (card && mmc_card_mmc(card) && | 1329 | mmc_poweroff_notify(host); |
| 1284 | (card->poweroff_notify_state == MMC_POWERED_ON)) { | ||
| 1285 | |||
| 1286 | if (host->power_notify_type == MMC_HOST_PW_NOTIFY_SHORT) { | ||
| 1287 | notify_type = EXT_CSD_POWER_OFF_SHORT; | ||
| 1288 | timeout = card->ext_csd.generic_cmd6_time; | ||
| 1289 | card->poweroff_notify_state = MMC_POWEROFF_SHORT; | ||
| 1290 | } else { | ||
| 1291 | notify_type = EXT_CSD_POWER_OFF_LONG; | ||
| 1292 | timeout = card->ext_csd.power_off_longtime; | ||
| 1293 | card->poweroff_notify_state = MMC_POWEROFF_LONG; | ||
| 1294 | } | ||
| 1295 | |||
| 1296 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, | ||
| 1297 | EXT_CSD_POWER_OFF_NOTIFICATION, | ||
| 1298 | notify_type, timeout); | ||
| 1299 | |||
| 1300 | if (err && err != -EBADMSG) | ||
| 1301 | pr_err("Device failed to respond within %d poweroff " | ||
| 1302 | "time. Forcefully powering down the device\n", | ||
| 1303 | timeout); | ||
| 1304 | |||
| 1305 | /* Set the card state to no notification after the poweroff */ | ||
| 1306 | card->poweroff_notify_state = MMC_NO_POWER_NOTIFICATION; | ||
| 1307 | } | ||
| 1308 | 1330 | ||
| 1309 | /* | 1331 | /* |
| 1310 | * Reset ocr mask to be the highest possible voltage supported for | 1332 | * Reset ocr mask to be the highest possible voltage supported for |
| @@ -2196,7 +2218,7 @@ int mmc_card_sleep(struct mmc_host *host) | |||
| 2196 | 2218 | ||
| 2197 | mmc_bus_get(host); | 2219 | mmc_bus_get(host); |
| 2198 | 2220 | ||
| 2199 | if (host->bus_ops && !host->bus_dead && host->bus_ops->awake) | 2221 | if (host->bus_ops && !host->bus_dead && host->bus_ops->sleep) |
| 2200 | err = host->bus_ops->sleep(host); | 2222 | err = host->bus_ops->sleep(host); |
| 2201 | 2223 | ||
| 2202 | mmc_bus_put(host); | 2224 | mmc_bus_put(host); |
| @@ -2302,8 +2324,17 @@ int mmc_suspend_host(struct mmc_host *host) | |||
| 2302 | * pre-claim the host. | 2324 | * pre-claim the host. |
| 2303 | */ | 2325 | */ |
| 2304 | if (mmc_try_claim_host(host)) { | 2326 | if (mmc_try_claim_host(host)) { |
| 2305 | if (host->bus_ops->suspend) | 2327 | if (host->bus_ops->suspend) { |
| 2328 | /* | ||
| 2329 | * For eMMC 4.5 device send notify command | ||
| 2330 | * before sleep, because in sleep state eMMC 4.5 | ||
| 2331 | * devices respond to only RESET and AWAKE cmd | ||
| 2332 | */ | ||
| 2333 | mmc_poweroff_notify(host); | ||
| 2306 | err = host->bus_ops->suspend(host); | 2334 | err = host->bus_ops->suspend(host); |
| 2335 | } | ||
| 2336 | mmc_do_release_host(host); | ||
| 2337 | |||
| 2307 | if (err == -ENOSYS || !host->bus_ops->resume) { | 2338 | if (err == -ENOSYS || !host->bus_ops->resume) { |
| 2308 | /* | 2339 | /* |
| 2309 | * We simply "remove" the card in this case. | 2340 | * We simply "remove" the card in this case. |
| @@ -2318,7 +2349,6 @@ int mmc_suspend_host(struct mmc_host *host) | |||
| 2318 | host->pm_flags = 0; | 2349 | host->pm_flags = 0; |
| 2319 | err = 0; | 2350 | err = 0; |
| 2320 | } | 2351 | } |
| 2321 | mmc_do_release_host(host); | ||
| 2322 | } else { | 2352 | } else { |
| 2323 | err = -EBUSY; | 2353 | err = -EBUSY; |
| 2324 | } | 2354 | } |
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index dbf421a6279c..d240427c1246 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c | |||
| @@ -876,17 +876,21 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, | |||
| 876 | * set the notification byte in the ext_csd register of device | 876 | * set the notification byte in the ext_csd register of device |
| 877 | */ | 877 | */ |
| 878 | if ((host->caps2 & MMC_CAP2_POWEROFF_NOTIFY) && | 878 | if ((host->caps2 & MMC_CAP2_POWEROFF_NOTIFY) && |
| 879 | (card->poweroff_notify_state == MMC_NO_POWER_NOTIFICATION)) { | 879 | (card->ext_csd.rev >= 6)) { |
| 880 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, | 880 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, |
| 881 | EXT_CSD_POWER_OFF_NOTIFICATION, | 881 | EXT_CSD_POWER_OFF_NOTIFICATION, |
| 882 | EXT_CSD_POWER_ON, | 882 | EXT_CSD_POWER_ON, |
| 883 | card->ext_csd.generic_cmd6_time); | 883 | card->ext_csd.generic_cmd6_time); |
| 884 | if (err && err != -EBADMSG) | 884 | if (err && err != -EBADMSG) |
| 885 | goto free_card; | 885 | goto free_card; |
| 886 | } | ||
| 887 | 886 | ||
| 888 | if (!err) | 887 | /* |
| 889 | card->poweroff_notify_state = MMC_POWERED_ON; | 888 | * The err can be -EBADMSG or 0, |
| 889 | * so check for success and update the flag | ||
| 890 | */ | ||
| 891 | if (!err) | ||
| 892 | card->poweroff_notify_state = MMC_POWERED_ON; | ||
| 893 | } | ||
| 890 | 894 | ||
| 891 | /* | 895 | /* |
| 892 | * Activate high speed (if supported) | 896 | * Activate high speed (if supported) |
diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c index 325ea61e12d3..8e0fbe994047 100644 --- a/drivers/mmc/host/mxcmmc.c +++ b/drivers/mmc/host/mxcmmc.c | |||
| @@ -732,6 +732,7 @@ static void mxcmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
| 732 | "failed to config DMA channel. Falling back to PIO\n"); | 732 | "failed to config DMA channel. Falling back to PIO\n"); |
| 733 | dma_release_channel(host->dma); | 733 | dma_release_channel(host->dma); |
| 734 | host->do_dma = 0; | 734 | host->do_dma = 0; |
| 735 | host->dma = NULL; | ||
| 735 | } | 736 | } |
| 736 | } | 737 | } |
| 737 | 738 | ||
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 101cd31c8220..d5fe43d53c51 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c | |||
| @@ -1010,6 +1010,7 @@ static void omap_hsmmc_dma_cleanup(struct omap_hsmmc_host *host, int errno) | |||
| 1010 | host->data->sg_len, | 1010 | host->data->sg_len, |
| 1011 | omap_hsmmc_get_dma_dir(host, host->data)); | 1011 | omap_hsmmc_get_dma_dir(host, host->data)); |
| 1012 | omap_free_dma(dma_ch); | 1012 | omap_free_dma(dma_ch); |
| 1013 | host->data->host_cookie = 0; | ||
| 1013 | } | 1014 | } |
| 1014 | host->data = NULL; | 1015 | host->data = NULL; |
| 1015 | } | 1016 | } |
| @@ -1575,8 +1576,10 @@ static void omap_hsmmc_post_req(struct mmc_host *mmc, struct mmc_request *mrq, | |||
| 1575 | struct mmc_data *data = mrq->data; | 1576 | struct mmc_data *data = mrq->data; |
| 1576 | 1577 | ||
| 1577 | if (host->use_dma) { | 1578 | if (host->use_dma) { |
| 1578 | dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len, | 1579 | if (data->host_cookie) |
| 1579 | omap_hsmmc_get_dma_dir(host, data)); | 1580 | dma_unmap_sg(mmc_dev(host->mmc), data->sg, |
| 1581 | data->sg_len, | ||
| 1582 | omap_hsmmc_get_dma_dir(host, data)); | ||
| 1580 | data->host_cookie = 0; | 1583 | data->host_cookie = 0; |
| 1581 | } | 1584 | } |
| 1582 | } | 1585 | } |
diff --git a/drivers/mmc/host/sdhci-cns3xxx.c b/drivers/mmc/host/sdhci-cns3xxx.c index 4b920b7621cf..87b6f079b6e0 100644 --- a/drivers/mmc/host/sdhci-cns3xxx.c +++ b/drivers/mmc/host/sdhci-cns3xxx.c | |||
| @@ -15,6 +15,7 @@ | |||
| 15 | #include <linux/delay.h> | 15 | #include <linux/delay.h> |
| 16 | #include <linux/device.h> | 16 | #include <linux/device.h> |
| 17 | #include <linux/mmc/host.h> | 17 | #include <linux/mmc/host.h> |
| 18 | #include <linux/module.h> | ||
| 18 | #include <mach/cns3xxx.h> | 19 | #include <mach/cns3xxx.h> |
| 19 | #include "sdhci-pltfm.h" | 20 | #include "sdhci-pltfm.h" |
| 20 | 21 | ||
diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c index 3d00e722efc9..cb60c4197e0a 100644 --- a/drivers/mmc/host/sdhci-s3c.c +++ b/drivers/mmc/host/sdhci-s3c.c | |||
| @@ -644,8 +644,6 @@ static int sdhci_s3c_resume(struct platform_device *dev) | |||
| 644 | static struct platform_driver sdhci_s3c_driver = { | 644 | static struct platform_driver sdhci_s3c_driver = { |
| 645 | .probe = sdhci_s3c_probe, | 645 | .probe = sdhci_s3c_probe, |
| 646 | .remove = __devexit_p(sdhci_s3c_remove), | 646 | .remove = __devexit_p(sdhci_s3c_remove), |
| 647 | .suspend = sdhci_s3c_suspend, | ||
| 648 | .resume = sdhci_s3c_resume, | ||
| 649 | .driver = { | 647 | .driver = { |
| 650 | .owner = THIS_MODULE, | 648 | .owner = THIS_MODULE, |
| 651 | .name = "s3c-sdhci", | 649 | .name = "s3c-sdhci", |
diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c index 369366c8e205..d5505f3fe2a1 100644 --- a/drivers/mmc/host/sh_mmcif.c +++ b/drivers/mmc/host/sh_mmcif.c | |||
| @@ -908,7 +908,7 @@ static void sh_mmcif_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
| 908 | if (host->power) { | 908 | if (host->power) { |
| 909 | pm_runtime_put(&host->pd->dev); | 909 | pm_runtime_put(&host->pd->dev); |
| 910 | host->power = false; | 910 | host->power = false; |
| 911 | if (p->down_pwr) | 911 | if (p->down_pwr && ios->power_mode == MMC_POWER_OFF) |
| 912 | p->down_pwr(host->pd); | 912 | p->down_pwr(host->pd); |
| 913 | } | 913 | } |
| 914 | host->state = STATE_IDLE; | 914 | host->state = STATE_IDLE; |
diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c index d85a60cda167..4208b3958069 100644 --- a/drivers/mmc/host/tmio_mmc_pio.c +++ b/drivers/mmc/host/tmio_mmc_pio.c | |||
| @@ -798,7 +798,7 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
| 798 | /* start bus clock */ | 798 | /* start bus clock */ |
| 799 | tmio_mmc_clk_start(host); | 799 | tmio_mmc_clk_start(host); |
| 800 | } else if (ios->power_mode != MMC_POWER_UP) { | 800 | } else if (ios->power_mode != MMC_POWER_UP) { |
| 801 | if (host->set_pwr) | 801 | if (host->set_pwr && ios->power_mode == MMC_POWER_OFF) |
| 802 | host->set_pwr(host->pdev, 0); | 802 | host->set_pwr(host->pdev, 0); |
| 803 | if ((pdata->flags & TMIO_MMC_HAS_COLD_CD) && | 803 | if ((pdata->flags & TMIO_MMC_HAS_COLD_CD) && |
| 804 | pdata->power) { | 804 | pdata->power) { |
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 415f2db414e1..c8ef9bc54d50 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h | |||
| @@ -218,6 +218,7 @@ struct mmc_card { | |||
| 218 | #define MMC_QUIRK_INAND_CMD38 (1<<6) /* iNAND devices have broken CMD38 */ | 218 | #define MMC_QUIRK_INAND_CMD38 (1<<6) /* iNAND devices have broken CMD38 */ |
| 219 | #define MMC_QUIRK_BLK_NO_CMD23 (1<<7) /* Avoid CMD23 for regular multiblock */ | 219 | #define MMC_QUIRK_BLK_NO_CMD23 (1<<7) /* Avoid CMD23 for regular multiblock */ |
| 220 | #define MMC_QUIRK_BROKEN_BYTE_MODE_512 (1<<8) /* Avoid sending 512 bytes in */ | 220 | #define MMC_QUIRK_BROKEN_BYTE_MODE_512 (1<<8) /* Avoid sending 512 bytes in */ |
| 221 | #define MMC_QUIRK_LONG_READ_TIME (1<<9) /* Data read time > CSD says */ | ||
| 221 | /* byte mode */ | 222 | /* byte mode */ |
| 222 | unsigned int poweroff_notify_state; /* eMMC4.5 notify feature */ | 223 | unsigned int poweroff_notify_state; /* eMMC4.5 notify feature */ |
| 223 | #define MMC_NO_POWER_NOTIFICATION 0 | 224 | #define MMC_NO_POWER_NOTIFICATION 0 |
| @@ -433,6 +434,11 @@ static inline int mmc_card_broken_byte_mode_512(const struct mmc_card *c) | |||
| 433 | return c->quirks & MMC_QUIRK_BROKEN_BYTE_MODE_512; | 434 | return c->quirks & MMC_QUIRK_BROKEN_BYTE_MODE_512; |
| 434 | } | 435 | } |
| 435 | 436 | ||
| 437 | static inline int mmc_card_long_read_time(const struct mmc_card *c) | ||
| 438 | { | ||
| 439 | return c->quirks & MMC_QUIRK_LONG_READ_TIME; | ||
| 440 | } | ||
| 441 | |||
| 436 | #define mmc_card_name(c) ((c)->cid.prod_name) | 442 | #define mmc_card_name(c) ((c)->cid.prod_name) |
| 437 | #define mmc_card_id(c) (dev_name(&(c)->dev)) | 443 | #define mmc_card_id(c) (dev_name(&(c)->dev)) |
| 438 | 444 | ||
