diff options
Diffstat (limited to 'drivers/mmc')
28 files changed, 175 insertions, 157 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/card/mmc_test.c b/drivers/mmc/card/mmc_test.c index b038c4a9468b..e99bdc18002d 100644 --- a/drivers/mmc/card/mmc_test.c +++ b/drivers/mmc/card/mmc_test.c | |||
@@ -2949,7 +2949,7 @@ static void mmc_test_free_dbgfs_file(struct mmc_card *card) | |||
2949 | } | 2949 | } |
2950 | 2950 | ||
2951 | static int __mmc_test_register_dbgfs_file(struct mmc_card *card, | 2951 | static int __mmc_test_register_dbgfs_file(struct mmc_card *card, |
2952 | const char *name, mode_t mode, const struct file_operations *fops) | 2952 | const char *name, umode_t mode, const struct file_operations *fops) |
2953 | { | 2953 | { |
2954 | struct dentry *file = NULL; | 2954 | struct dentry *file = NULL; |
2955 | struct mmc_test_dbgfs_file *df; | 2955 | struct mmc_test_dbgfs_file *df; |
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/host.c b/drivers/mmc/core/host.c index e8a5eb38748b..d31c78b72b0f 100644 --- a/drivers/mmc/core/host.c +++ b/drivers/mmc/core/host.c | |||
@@ -302,17 +302,6 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev) | |||
302 | host->max_blk_size = 512; | 302 | host->max_blk_size = 512; |
303 | host->max_blk_count = PAGE_CACHE_SIZE / 512; | 303 | host->max_blk_count = PAGE_CACHE_SIZE / 512; |
304 | 304 | ||
305 | /* | ||
306 | * Enable runtime power management by default. This flag was added due | ||
307 | * to runtime power management causing disruption for some users, but | ||
308 | * the power on/off code has been improved since then. | ||
309 | * | ||
310 | * We'll enable this flag by default as an experiment, and if no | ||
311 | * problems are reported, we will follow up later and remove the flag | ||
312 | * altogether. | ||
313 | */ | ||
314 | host->caps = MMC_CAP_POWER_OFF_CARD; | ||
315 | |||
316 | return host; | 305 | return host; |
317 | 306 | ||
318 | free: | 307 | free: |
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/at91_mci.c b/drivers/mmc/host/at91_mci.c index a8b4d2aa18e5..f437c3e6f3aa 100644 --- a/drivers/mmc/host/at91_mci.c +++ b/drivers/mmc/host/at91_mci.c | |||
@@ -741,7 +741,7 @@ static void at91_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
741 | at91_mci_write(host, AT91_MCI_MR, (at91_mci_read(host, AT91_MCI_MR) & ~AT91_MCI_CLKDIV) | clkdiv); | 741 | at91_mci_write(host, AT91_MCI_MR, (at91_mci_read(host, AT91_MCI_MR) & ~AT91_MCI_CLKDIV) | clkdiv); |
742 | 742 | ||
743 | /* maybe switch power to the card */ | 743 | /* maybe switch power to the card */ |
744 | if (host->board->vcc_pin) { | 744 | if (gpio_is_valid(host->board->vcc_pin)) { |
745 | switch (ios->power_mode) { | 745 | switch (ios->power_mode) { |
746 | case MMC_POWER_OFF: | 746 | case MMC_POWER_OFF: |
747 | gpio_set_value(host->board->vcc_pin, 0); | 747 | gpio_set_value(host->board->vcc_pin, 0); |
@@ -897,7 +897,7 @@ static int at91_mci_get_ro(struct mmc_host *mmc) | |||
897 | { | 897 | { |
898 | struct at91mci_host *host = mmc_priv(mmc); | 898 | struct at91mci_host *host = mmc_priv(mmc); |
899 | 899 | ||
900 | if (host->board->wp_pin) | 900 | if (gpio_is_valid(host->board->wp_pin)) |
901 | return !!gpio_get_value(host->board->wp_pin); | 901 | return !!gpio_get_value(host->board->wp_pin); |
902 | /* | 902 | /* |
903 | * Board doesn't support read only detection; let the mmc core | 903 | * Board doesn't support read only detection; let the mmc core |
@@ -991,21 +991,21 @@ static int __init at91_mci_probe(struct platform_device *pdev) | |||
991 | * Reserve GPIOs ... board init code makes sure these pins are set | 991 | * Reserve GPIOs ... board init code makes sure these pins are set |
992 | * up as GPIOs with the right direction (input, except for vcc) | 992 | * up as GPIOs with the right direction (input, except for vcc) |
993 | */ | 993 | */ |
994 | if (host->board->det_pin) { | 994 | if (gpio_is_valid(host->board->det_pin)) { |
995 | ret = gpio_request(host->board->det_pin, "mmc_detect"); | 995 | ret = gpio_request(host->board->det_pin, "mmc_detect"); |
996 | if (ret < 0) { | 996 | if (ret < 0) { |
997 | dev_dbg(&pdev->dev, "couldn't claim card detect pin\n"); | 997 | dev_dbg(&pdev->dev, "couldn't claim card detect pin\n"); |
998 | goto fail4b; | 998 | goto fail4b; |
999 | } | 999 | } |
1000 | } | 1000 | } |
1001 | if (host->board->wp_pin) { | 1001 | if (gpio_is_valid(host->board->wp_pin)) { |
1002 | ret = gpio_request(host->board->wp_pin, "mmc_wp"); | 1002 | ret = gpio_request(host->board->wp_pin, "mmc_wp"); |
1003 | if (ret < 0) { | 1003 | if (ret < 0) { |
1004 | dev_dbg(&pdev->dev, "couldn't claim wp sense pin\n"); | 1004 | dev_dbg(&pdev->dev, "couldn't claim wp sense pin\n"); |
1005 | goto fail4; | 1005 | goto fail4; |
1006 | } | 1006 | } |
1007 | } | 1007 | } |
1008 | if (host->board->vcc_pin) { | 1008 | if (gpio_is_valid(host->board->vcc_pin)) { |
1009 | ret = gpio_request(host->board->vcc_pin, "mmc_vcc"); | 1009 | ret = gpio_request(host->board->vcc_pin, "mmc_vcc"); |
1010 | if (ret < 0) { | 1010 | if (ret < 0) { |
1011 | dev_dbg(&pdev->dev, "couldn't claim vcc switch pin\n"); | 1011 | dev_dbg(&pdev->dev, "couldn't claim vcc switch pin\n"); |
@@ -1057,7 +1057,7 @@ static int __init at91_mci_probe(struct platform_device *pdev) | |||
1057 | /* | 1057 | /* |
1058 | * Add host to MMC layer | 1058 | * Add host to MMC layer |
1059 | */ | 1059 | */ |
1060 | if (host->board->det_pin) { | 1060 | if (gpio_is_valid(host->board->det_pin)) { |
1061 | host->present = !gpio_get_value(host->board->det_pin); | 1061 | host->present = !gpio_get_value(host->board->det_pin); |
1062 | } | 1062 | } |
1063 | else | 1063 | else |
@@ -1068,7 +1068,7 @@ static int __init at91_mci_probe(struct platform_device *pdev) | |||
1068 | /* | 1068 | /* |
1069 | * monitor card insertion/removal if we can | 1069 | * monitor card insertion/removal if we can |
1070 | */ | 1070 | */ |
1071 | if (host->board->det_pin) { | 1071 | if (gpio_is_valid(host->board->det_pin)) { |
1072 | ret = request_irq(gpio_to_irq(host->board->det_pin), | 1072 | ret = request_irq(gpio_to_irq(host->board->det_pin), |
1073 | at91_mmc_det_irq, 0, mmc_hostname(mmc), host); | 1073 | at91_mmc_det_irq, 0, mmc_hostname(mmc), host); |
1074 | if (ret) | 1074 | if (ret) |
@@ -1087,13 +1087,13 @@ fail0: | |||
1087 | fail1: | 1087 | fail1: |
1088 | clk_put(host->mci_clk); | 1088 | clk_put(host->mci_clk); |
1089 | fail2: | 1089 | fail2: |
1090 | if (host->board->vcc_pin) | 1090 | if (gpio_is_valid(host->board->vcc_pin)) |
1091 | gpio_free(host->board->vcc_pin); | 1091 | gpio_free(host->board->vcc_pin); |
1092 | fail3: | 1092 | fail3: |
1093 | if (host->board->wp_pin) | 1093 | if (gpio_is_valid(host->board->wp_pin)) |
1094 | gpio_free(host->board->wp_pin); | 1094 | gpio_free(host->board->wp_pin); |
1095 | fail4: | 1095 | fail4: |
1096 | if (host->board->det_pin) | 1096 | if (gpio_is_valid(host->board->det_pin)) |
1097 | gpio_free(host->board->det_pin); | 1097 | gpio_free(host->board->det_pin); |
1098 | fail4b: | 1098 | fail4b: |
1099 | if (host->buffer) | 1099 | if (host->buffer) |
@@ -1125,7 +1125,7 @@ static int __exit at91_mci_remove(struct platform_device *pdev) | |||
1125 | dma_free_coherent(&pdev->dev, MCI_BUFSIZE, | 1125 | dma_free_coherent(&pdev->dev, MCI_BUFSIZE, |
1126 | host->buffer, host->physical_address); | 1126 | host->buffer, host->physical_address); |
1127 | 1127 | ||
1128 | if (host->board->det_pin) { | 1128 | if (gpio_is_valid(host->board->det_pin)) { |
1129 | if (device_can_wakeup(&pdev->dev)) | 1129 | if (device_can_wakeup(&pdev->dev)) |
1130 | free_irq(gpio_to_irq(host->board->det_pin), host); | 1130 | free_irq(gpio_to_irq(host->board->det_pin), host); |
1131 | device_init_wakeup(&pdev->dev, 0); | 1131 | device_init_wakeup(&pdev->dev, 0); |
@@ -1140,9 +1140,9 @@ static int __exit at91_mci_remove(struct platform_device *pdev) | |||
1140 | clk_disable(host->mci_clk); /* Disable the peripheral clock */ | 1140 | clk_disable(host->mci_clk); /* Disable the peripheral clock */ |
1141 | clk_put(host->mci_clk); | 1141 | clk_put(host->mci_clk); |
1142 | 1142 | ||
1143 | if (host->board->vcc_pin) | 1143 | if (gpio_is_valid(host->board->vcc_pin)) |
1144 | gpio_free(host->board->vcc_pin); | 1144 | gpio_free(host->board->vcc_pin); |
1145 | if (host->board->wp_pin) | 1145 | if (gpio_is_valid(host->board->wp_pin)) |
1146 | gpio_free(host->board->wp_pin); | 1146 | gpio_free(host->board->wp_pin); |
1147 | 1147 | ||
1148 | iounmap(host->baseaddr); | 1148 | iounmap(host->baseaddr); |
@@ -1163,7 +1163,7 @@ static int at91_mci_suspend(struct platform_device *pdev, pm_message_t state) | |||
1163 | struct at91mci_host *host = mmc_priv(mmc); | 1163 | struct at91mci_host *host = mmc_priv(mmc); |
1164 | int ret = 0; | 1164 | int ret = 0; |
1165 | 1165 | ||
1166 | if (host->board->det_pin && device_may_wakeup(&pdev->dev)) | 1166 | if (gpio_is_valid(host->board->det_pin) && device_may_wakeup(&pdev->dev)) |
1167 | enable_irq_wake(host->board->det_pin); | 1167 | enable_irq_wake(host->board->det_pin); |
1168 | 1168 | ||
1169 | if (mmc) | 1169 | if (mmc) |
@@ -1178,7 +1178,7 @@ static int at91_mci_resume(struct platform_device *pdev) | |||
1178 | struct at91mci_host *host = mmc_priv(mmc); | 1178 | struct at91mci_host *host = mmc_priv(mmc); |
1179 | int ret = 0; | 1179 | int ret = 0; |
1180 | 1180 | ||
1181 | if (host->board->det_pin && device_may_wakeup(&pdev->dev)) | 1181 | if (gpio_is_valid(host->board->det_pin) && device_may_wakeup(&pdev->dev)) |
1182 | disable_irq_wake(host->board->det_pin); | 1182 | disable_irq_wake(host->board->det_pin); |
1183 | 1183 | ||
1184 | if (mmc) | 1184 | if (mmc) |
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 50b5f9926f64..fa8dd2fda4b2 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c | |||
@@ -675,7 +675,8 @@ mmci_data_irq(struct mmci_host *host, struct mmc_data *data, | |||
675 | unsigned int status) | 675 | unsigned int status) |
676 | { | 676 | { |
677 | /* First check for errors */ | 677 | /* First check for errors */ |
678 | if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_TXUNDERRUN|MCI_RXOVERRUN)) { | 678 | if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_STARTBITERR| |
679 | MCI_TXUNDERRUN|MCI_RXOVERRUN)) { | ||
679 | u32 remain, success; | 680 | u32 remain, success; |
680 | 681 | ||
681 | /* Terminate the DMA transfer */ | 682 | /* Terminate the DMA transfer */ |
@@ -754,8 +755,12 @@ mmci_cmd_irq(struct mmci_host *host, struct mmc_command *cmd, | |||
754 | } | 755 | } |
755 | 756 | ||
756 | if (!cmd->data || cmd->error) { | 757 | if (!cmd->data || cmd->error) { |
757 | if (host->data) | 758 | if (host->data) { |
759 | /* Terminate the DMA transfer */ | ||
760 | if (dma_inprogress(host)) | ||
761 | mmci_dma_data_error(host); | ||
758 | mmci_stop_data(host); | 762 | mmci_stop_data(host); |
763 | } | ||
759 | mmci_request_end(host, cmd->mrq); | 764 | mmci_request_end(host, cmd->mrq); |
760 | } else if (!(cmd->data->flags & MMC_DATA_READ)) { | 765 | } else if (!(cmd->data->flags & MMC_DATA_READ)) { |
761 | mmci_start_data(host, cmd->data); | 766 | mmci_start_data(host, cmd->data); |
@@ -955,8 +960,9 @@ static irqreturn_t mmci_irq(int irq, void *dev_id) | |||
955 | dev_dbg(mmc_dev(host->mmc), "irq0 (data+cmd) %08x\n", status); | 960 | dev_dbg(mmc_dev(host->mmc), "irq0 (data+cmd) %08x\n", status); |
956 | 961 | ||
957 | data = host->data; | 962 | data = host->data; |
958 | if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_TXUNDERRUN| | 963 | if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_STARTBITERR| |
959 | MCI_RXOVERRUN|MCI_DATAEND|MCI_DATABLOCKEND) && data) | 964 | MCI_TXUNDERRUN|MCI_RXOVERRUN|MCI_DATAEND| |
965 | MCI_DATABLOCKEND) && data) | ||
960 | mmci_data_irq(host, data, status); | 966 | mmci_data_irq(host, data, status); |
961 | 967 | ||
962 | cmd = host->cmd; | 968 | cmd = host->cmd; |
@@ -1496,6 +1502,8 @@ static struct amba_id mmci_ids[] = { | |||
1496 | { 0, 0 }, | 1502 | { 0, 0 }, |
1497 | }; | 1503 | }; |
1498 | 1504 | ||
1505 | MODULE_DEVICE_TABLE(amba, mmci_ids); | ||
1506 | |||
1499 | static struct amba_driver mmci_driver = { | 1507 | static struct amba_driver mmci_driver = { |
1500 | .drv = { | 1508 | .drv = { |
1501 | .name = DRIVER_NAME, | 1509 | .name = DRIVER_NAME, |
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.c b/drivers/mmc/host/omap.c index 2dba999caf2c..887c0e598cf3 100644 --- a/drivers/mmc/host/omap.c +++ b/drivers/mmc/host/omap.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * linux/drivers/mmc/host/omap.c | 2 | * linux/drivers/mmc/host/omap.c |
3 | * | 3 | * |
4 | * Copyright (C) 2004 Nokia Corporation | 4 | * Copyright (C) 2004 Nokia Corporation |
5 | * Written by Tuukka Tikkanen and Juha Yrjölä<juha.yrjola@nokia.com> | 5 | * Written by Tuukka Tikkanen and Juha Yrjölä<juha.yrjola@nokia.com> |
6 | * Misc hacks here and there by Tony Lindgren <tony@atomide.com> | 6 | * Misc hacks here and there by Tony Lindgren <tony@atomide.com> |
7 | * Other hacks (DMA, SD, etc) by David Brownell | 7 | * Other hacks (DMA, SD, etc) by David Brownell |
8 | * | 8 | * |
@@ -1634,4 +1634,4 @@ module_exit(mmc_omap_exit); | |||
1634 | MODULE_DESCRIPTION("OMAP Multimedia Card driver"); | 1634 | MODULE_DESCRIPTION("OMAP Multimedia Card driver"); |
1635 | MODULE_LICENSE("GPL"); | 1635 | MODULE_LICENSE("GPL"); |
1636 | MODULE_ALIAS("platform:" DRIVER_NAME); | 1636 | MODULE_ALIAS("platform:" DRIVER_NAME); |
1637 | MODULE_AUTHOR("Juha Yrjölä"); | 1637 | MODULE_AUTHOR("Juha Yrjölä"); |
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..b4257e700617 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 | ||
@@ -108,13 +109,10 @@ static struct platform_driver sdhci_cns3xxx_driver = { | |||
108 | .driver = { | 109 | .driver = { |
109 | .name = "sdhci-cns3xxx", | 110 | .name = "sdhci-cns3xxx", |
110 | .owner = THIS_MODULE, | 111 | .owner = THIS_MODULE, |
112 | .pm = SDHCI_PLTFM_PMOPS, | ||
111 | }, | 113 | }, |
112 | .probe = sdhci_cns3xxx_probe, | 114 | .probe = sdhci_cns3xxx_probe, |
113 | .remove = __devexit_p(sdhci_cns3xxx_remove), | 115 | .remove = __devexit_p(sdhci_cns3xxx_remove), |
114 | #ifdef CONFIG_PM | ||
115 | .suspend = sdhci_pltfm_suspend, | ||
116 | .resume = sdhci_pltfm_resume, | ||
117 | #endif | ||
118 | }; | 116 | }; |
119 | 117 | ||
120 | static int __init sdhci_cns3xxx_init(void) | 118 | static int __init sdhci_cns3xxx_init(void) |
diff --git a/drivers/mmc/host/sdhci-dove.c b/drivers/mmc/host/sdhci-dove.c index f2d29dca4420..a81312c91f70 100644 --- a/drivers/mmc/host/sdhci-dove.c +++ b/drivers/mmc/host/sdhci-dove.c | |||
@@ -82,13 +82,10 @@ static struct platform_driver sdhci_dove_driver = { | |||
82 | .driver = { | 82 | .driver = { |
83 | .name = "sdhci-dove", | 83 | .name = "sdhci-dove", |
84 | .owner = THIS_MODULE, | 84 | .owner = THIS_MODULE, |
85 | .pm = SDHCI_PLTFM_PMOPS, | ||
85 | }, | 86 | }, |
86 | .probe = sdhci_dove_probe, | 87 | .probe = sdhci_dove_probe, |
87 | .remove = __devexit_p(sdhci_dove_remove), | 88 | .remove = __devexit_p(sdhci_dove_remove), |
88 | #ifdef CONFIG_PM | ||
89 | .suspend = sdhci_pltfm_suspend, | ||
90 | .resume = sdhci_pltfm_resume, | ||
91 | #endif | ||
92 | }; | 89 | }; |
93 | 90 | ||
94 | static int __init sdhci_dove_init(void) | 91 | static int __init sdhci_dove_init(void) |
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index 4b976f00ea85..38ebc4ea259f 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c | |||
@@ -599,14 +599,11 @@ static struct platform_driver sdhci_esdhc_imx_driver = { | |||
599 | .name = "sdhci-esdhc-imx", | 599 | .name = "sdhci-esdhc-imx", |
600 | .owner = THIS_MODULE, | 600 | .owner = THIS_MODULE, |
601 | .of_match_table = imx_esdhc_dt_ids, | 601 | .of_match_table = imx_esdhc_dt_ids, |
602 | .pm = SDHCI_PLTFM_PMOPS, | ||
602 | }, | 603 | }, |
603 | .id_table = imx_esdhc_devtype, | 604 | .id_table = imx_esdhc_devtype, |
604 | .probe = sdhci_esdhc_imx_probe, | 605 | .probe = sdhci_esdhc_imx_probe, |
605 | .remove = __devexit_p(sdhci_esdhc_imx_remove), | 606 | .remove = __devexit_p(sdhci_esdhc_imx_remove), |
606 | #ifdef CONFIG_PM | ||
607 | .suspend = sdhci_pltfm_suspend, | ||
608 | .resume = sdhci_pltfm_resume, | ||
609 | #endif | ||
610 | }; | 607 | }; |
611 | 608 | ||
612 | static int __init sdhci_esdhc_imx_init(void) | 609 | static int __init sdhci_esdhc_imx_init(void) |
diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c index 59e9d003e589..01e5f627e0f0 100644 --- a/drivers/mmc/host/sdhci-of-esdhc.c +++ b/drivers/mmc/host/sdhci-of-esdhc.c | |||
@@ -125,13 +125,10 @@ static struct platform_driver sdhci_esdhc_driver = { | |||
125 | .name = "sdhci-esdhc", | 125 | .name = "sdhci-esdhc", |
126 | .owner = THIS_MODULE, | 126 | .owner = THIS_MODULE, |
127 | .of_match_table = sdhci_esdhc_of_match, | 127 | .of_match_table = sdhci_esdhc_of_match, |
128 | .pm = SDHCI_PLTFM_PMOPS, | ||
128 | }, | 129 | }, |
129 | .probe = sdhci_esdhc_probe, | 130 | .probe = sdhci_esdhc_probe, |
130 | .remove = __devexit_p(sdhci_esdhc_remove), | 131 | .remove = __devexit_p(sdhci_esdhc_remove), |
131 | #ifdef CONFIG_PM | ||
132 | .suspend = sdhci_pltfm_suspend, | ||
133 | .resume = sdhci_pltfm_resume, | ||
134 | #endif | ||
135 | }; | 132 | }; |
136 | 133 | ||
137 | static int __init sdhci_esdhc_init(void) | 134 | static int __init sdhci_esdhc_init(void) |
diff --git a/drivers/mmc/host/sdhci-of-hlwd.c b/drivers/mmc/host/sdhci-of-hlwd.c index 9b0d794a4f69..3619adc7d9fc 100644 --- a/drivers/mmc/host/sdhci-of-hlwd.c +++ b/drivers/mmc/host/sdhci-of-hlwd.c | |||
@@ -87,13 +87,10 @@ static struct platform_driver sdhci_hlwd_driver = { | |||
87 | .name = "sdhci-hlwd", | 87 | .name = "sdhci-hlwd", |
88 | .owner = THIS_MODULE, | 88 | .owner = THIS_MODULE, |
89 | .of_match_table = sdhci_hlwd_of_match, | 89 | .of_match_table = sdhci_hlwd_of_match, |
90 | .pm = SDHCI_PLTFM_PMOPS, | ||
90 | }, | 91 | }, |
91 | .probe = sdhci_hlwd_probe, | 92 | .probe = sdhci_hlwd_probe, |
92 | .remove = __devexit_p(sdhci_hlwd_remove), | 93 | .remove = __devexit_p(sdhci_hlwd_remove), |
93 | #ifdef CONFIG_PM | ||
94 | .suspend = sdhci_pltfm_suspend, | ||
95 | .resume = sdhci_pltfm_resume, | ||
96 | #endif | ||
97 | }; | 94 | }; |
98 | 95 | ||
99 | static int __init sdhci_hlwd_init(void) | 96 | static int __init sdhci_hlwd_init(void) |
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c index d833d9c2f7e3..6878a94626bc 100644 --- a/drivers/mmc/host/sdhci-pci.c +++ b/drivers/mmc/host/sdhci-pci.c | |||
@@ -54,8 +54,7 @@ struct sdhci_pci_fixes { | |||
54 | int (*probe_slot) (struct sdhci_pci_slot *); | 54 | int (*probe_slot) (struct sdhci_pci_slot *); |
55 | void (*remove_slot) (struct sdhci_pci_slot *, int); | 55 | void (*remove_slot) (struct sdhci_pci_slot *, int); |
56 | 56 | ||
57 | int (*suspend) (struct sdhci_pci_chip *, | 57 | int (*suspend) (struct sdhci_pci_chip *); |
58 | pm_message_t); | ||
59 | int (*resume) (struct sdhci_pci_chip *); | 58 | int (*resume) (struct sdhci_pci_chip *); |
60 | }; | 59 | }; |
61 | 60 | ||
@@ -549,7 +548,7 @@ static void jmicron_remove_slot(struct sdhci_pci_slot *slot, int dead) | |||
549 | jmicron_enable_mmc(slot->host, 0); | 548 | jmicron_enable_mmc(slot->host, 0); |
550 | } | 549 | } |
551 | 550 | ||
552 | static int jmicron_suspend(struct sdhci_pci_chip *chip, pm_message_t state) | 551 | static int jmicron_suspend(struct sdhci_pci_chip *chip) |
553 | { | 552 | { |
554 | int i; | 553 | int i; |
555 | 554 | ||
@@ -993,8 +992,9 @@ static struct sdhci_ops sdhci_pci_ops = { | |||
993 | 992 | ||
994 | #ifdef CONFIG_PM | 993 | #ifdef CONFIG_PM |
995 | 994 | ||
996 | static int sdhci_pci_suspend(struct pci_dev *pdev, pm_message_t state) | 995 | static int sdhci_pci_suspend(struct device *dev) |
997 | { | 996 | { |
997 | struct pci_dev *pdev = to_pci_dev(dev); | ||
998 | struct sdhci_pci_chip *chip; | 998 | struct sdhci_pci_chip *chip; |
999 | struct sdhci_pci_slot *slot; | 999 | struct sdhci_pci_slot *slot; |
1000 | mmc_pm_flag_t slot_pm_flags; | 1000 | mmc_pm_flag_t slot_pm_flags; |
@@ -1010,7 +1010,7 @@ static int sdhci_pci_suspend(struct pci_dev *pdev, pm_message_t state) | |||
1010 | if (!slot) | 1010 | if (!slot) |
1011 | continue; | 1011 | continue; |
1012 | 1012 | ||
1013 | ret = sdhci_suspend_host(slot->host, state); | 1013 | ret = sdhci_suspend_host(slot->host); |
1014 | 1014 | ||
1015 | if (ret) { | 1015 | if (ret) { |
1016 | for (i--; i >= 0; i--) | 1016 | for (i--; i >= 0; i--) |
@@ -1026,7 +1026,7 @@ static int sdhci_pci_suspend(struct pci_dev *pdev, pm_message_t state) | |||
1026 | } | 1026 | } |
1027 | 1027 | ||
1028 | if (chip->fixes && chip->fixes->suspend) { | 1028 | if (chip->fixes && chip->fixes->suspend) { |
1029 | ret = chip->fixes->suspend(chip, state); | 1029 | ret = chip->fixes->suspend(chip); |
1030 | if (ret) { | 1030 | if (ret) { |
1031 | for (i = chip->num_slots - 1; i >= 0; i--) | 1031 | for (i = chip->num_slots - 1; i >= 0; i--) |
1032 | sdhci_resume_host(chip->slots[i]->host); | 1032 | sdhci_resume_host(chip->slots[i]->host); |
@@ -1042,16 +1042,17 @@ static int sdhci_pci_suspend(struct pci_dev *pdev, pm_message_t state) | |||
1042 | } | 1042 | } |
1043 | pci_set_power_state(pdev, PCI_D3hot); | 1043 | pci_set_power_state(pdev, PCI_D3hot); |
1044 | } else { | 1044 | } else { |
1045 | pci_enable_wake(pdev, pci_choose_state(pdev, state), 0); | 1045 | pci_enable_wake(pdev, PCI_D3hot, 0); |
1046 | pci_disable_device(pdev); | 1046 | pci_disable_device(pdev); |
1047 | pci_set_power_state(pdev, pci_choose_state(pdev, state)); | 1047 | pci_set_power_state(pdev, PCI_D3hot); |
1048 | } | 1048 | } |
1049 | 1049 | ||
1050 | return 0; | 1050 | return 0; |
1051 | } | 1051 | } |
1052 | 1052 | ||
1053 | static int sdhci_pci_resume(struct pci_dev *pdev) | 1053 | static int sdhci_pci_resume(struct device *dev) |
1054 | { | 1054 | { |
1055 | struct pci_dev *pdev = to_pci_dev(dev); | ||
1055 | struct sdhci_pci_chip *chip; | 1056 | struct sdhci_pci_chip *chip; |
1056 | struct sdhci_pci_slot *slot; | 1057 | struct sdhci_pci_slot *slot; |
1057 | int i, ret; | 1058 | int i, ret; |
@@ -1099,7 +1100,6 @@ static int sdhci_pci_runtime_suspend(struct device *dev) | |||
1099 | struct pci_dev *pdev = container_of(dev, struct pci_dev, dev); | 1100 | struct pci_dev *pdev = container_of(dev, struct pci_dev, dev); |
1100 | struct sdhci_pci_chip *chip; | 1101 | struct sdhci_pci_chip *chip; |
1101 | struct sdhci_pci_slot *slot; | 1102 | struct sdhci_pci_slot *slot; |
1102 | pm_message_t state = { .event = PM_EVENT_SUSPEND }; | ||
1103 | int i, ret; | 1103 | int i, ret; |
1104 | 1104 | ||
1105 | chip = pci_get_drvdata(pdev); | 1105 | chip = pci_get_drvdata(pdev); |
@@ -1121,7 +1121,7 @@ static int sdhci_pci_runtime_suspend(struct device *dev) | |||
1121 | } | 1121 | } |
1122 | 1122 | ||
1123 | if (chip->fixes && chip->fixes->suspend) { | 1123 | if (chip->fixes && chip->fixes->suspend) { |
1124 | ret = chip->fixes->suspend(chip, state); | 1124 | ret = chip->fixes->suspend(chip); |
1125 | if (ret) { | 1125 | if (ret) { |
1126 | for (i = chip->num_slots - 1; i >= 0; i--) | 1126 | for (i = chip->num_slots - 1; i >= 0; i--) |
1127 | sdhci_runtime_resume_host(chip->slots[i]->host); | 1127 | sdhci_runtime_resume_host(chip->slots[i]->host); |
@@ -1176,6 +1176,8 @@ static int sdhci_pci_runtime_idle(struct device *dev) | |||
1176 | #endif | 1176 | #endif |
1177 | 1177 | ||
1178 | static const struct dev_pm_ops sdhci_pci_pm_ops = { | 1178 | static const struct dev_pm_ops sdhci_pci_pm_ops = { |
1179 | .suspend = sdhci_pci_suspend, | ||
1180 | .resume = sdhci_pci_resume, | ||
1179 | .runtime_suspend = sdhci_pci_runtime_suspend, | 1181 | .runtime_suspend = sdhci_pci_runtime_suspend, |
1180 | .runtime_resume = sdhci_pci_runtime_resume, | 1182 | .runtime_resume = sdhci_pci_runtime_resume, |
1181 | .runtime_idle = sdhci_pci_runtime_idle, | 1183 | .runtime_idle = sdhci_pci_runtime_idle, |
@@ -1428,8 +1430,6 @@ static struct pci_driver sdhci_driver = { | |||
1428 | .id_table = pci_ids, | 1430 | .id_table = pci_ids, |
1429 | .probe = sdhci_pci_probe, | 1431 | .probe = sdhci_pci_probe, |
1430 | .remove = __devexit_p(sdhci_pci_remove), | 1432 | .remove = __devexit_p(sdhci_pci_remove), |
1431 | .suspend = sdhci_pci_suspend, | ||
1432 | .resume = sdhci_pci_resume, | ||
1433 | .driver = { | 1433 | .driver = { |
1434 | .pm = &sdhci_pci_pm_ops | 1434 | .pm = &sdhci_pci_pm_ops |
1435 | }, | 1435 | }, |
diff --git a/drivers/mmc/host/sdhci-pltfm.c b/drivers/mmc/host/sdhci-pltfm.c index a9e12ea05583..03970bcb3495 100644 --- a/drivers/mmc/host/sdhci-pltfm.c +++ b/drivers/mmc/host/sdhci-pltfm.c | |||
@@ -194,21 +194,25 @@ int sdhci_pltfm_unregister(struct platform_device *pdev) | |||
194 | EXPORT_SYMBOL_GPL(sdhci_pltfm_unregister); | 194 | EXPORT_SYMBOL_GPL(sdhci_pltfm_unregister); |
195 | 195 | ||
196 | #ifdef CONFIG_PM | 196 | #ifdef CONFIG_PM |
197 | int sdhci_pltfm_suspend(struct platform_device *dev, pm_message_t state) | 197 | static int sdhci_pltfm_suspend(struct device *dev) |
198 | { | 198 | { |
199 | struct sdhci_host *host = platform_get_drvdata(dev); | 199 | struct sdhci_host *host = dev_get_drvdata(dev); |
200 | 200 | ||
201 | return sdhci_suspend_host(host, state); | 201 | return sdhci_suspend_host(host); |
202 | } | 202 | } |
203 | EXPORT_SYMBOL_GPL(sdhci_pltfm_suspend); | ||
204 | 203 | ||
205 | int sdhci_pltfm_resume(struct platform_device *dev) | 204 | static int sdhci_pltfm_resume(struct device *dev) |
206 | { | 205 | { |
207 | struct sdhci_host *host = platform_get_drvdata(dev); | 206 | struct sdhci_host *host = dev_get_drvdata(dev); |
208 | 207 | ||
209 | return sdhci_resume_host(host); | 208 | return sdhci_resume_host(host); |
210 | } | 209 | } |
211 | EXPORT_SYMBOL_GPL(sdhci_pltfm_resume); | 210 | |
211 | const struct dev_pm_ops sdhci_pltfm_pmops = { | ||
212 | .suspend = sdhci_pltfm_suspend, | ||
213 | .resume = sdhci_pltfm_resume, | ||
214 | }; | ||
215 | EXPORT_SYMBOL_GPL(sdhci_pltfm_pmops); | ||
212 | #endif /* CONFIG_PM */ | 216 | #endif /* CONFIG_PM */ |
213 | 217 | ||
214 | static int __init sdhci_pltfm_drv_init(void) | 218 | static int __init sdhci_pltfm_drv_init(void) |
diff --git a/drivers/mmc/host/sdhci-pltfm.h b/drivers/mmc/host/sdhci-pltfm.h index 3a9fc3f40840..37e0e184a0bb 100644 --- a/drivers/mmc/host/sdhci-pltfm.h +++ b/drivers/mmc/host/sdhci-pltfm.h | |||
@@ -99,8 +99,10 @@ extern int sdhci_pltfm_register(struct platform_device *pdev, | |||
99 | extern int sdhci_pltfm_unregister(struct platform_device *pdev); | 99 | extern int sdhci_pltfm_unregister(struct platform_device *pdev); |
100 | 100 | ||
101 | #ifdef CONFIG_PM | 101 | #ifdef CONFIG_PM |
102 | extern int sdhci_pltfm_suspend(struct platform_device *dev, pm_message_t state); | 102 | extern const struct dev_pm_ops sdhci_pltfm_pmops; |
103 | extern int sdhci_pltfm_resume(struct platform_device *dev); | 103 | #define SDHCI_PLTFM_PMOPS (&sdhci_pltfm_pmops) |
104 | #else | ||
105 | #define SDHCI_PLTFM_PMOPS NULL | ||
104 | #endif | 106 | #endif |
105 | 107 | ||
106 | #endif /* _DRIVERS_MMC_SDHCI_PLTFM_H */ | 108 | #endif /* _DRIVERS_MMC_SDHCI_PLTFM_H */ |
diff --git a/drivers/mmc/host/sdhci-pxav2.c b/drivers/mmc/host/sdhci-pxav2.c index d4bf6d30c7ba..7a039c3cb1f1 100644 --- a/drivers/mmc/host/sdhci-pxav2.c +++ b/drivers/mmc/host/sdhci-pxav2.c | |||
@@ -218,13 +218,10 @@ static struct platform_driver sdhci_pxav2_driver = { | |||
218 | .driver = { | 218 | .driver = { |
219 | .name = "sdhci-pxav2", | 219 | .name = "sdhci-pxav2", |
220 | .owner = THIS_MODULE, | 220 | .owner = THIS_MODULE, |
221 | .pm = SDHCI_PLTFM_PMOPS, | ||
221 | }, | 222 | }, |
222 | .probe = sdhci_pxav2_probe, | 223 | .probe = sdhci_pxav2_probe, |
223 | .remove = __devexit_p(sdhci_pxav2_remove), | 224 | .remove = __devexit_p(sdhci_pxav2_remove), |
224 | #ifdef CONFIG_PM | ||
225 | .suspend = sdhci_pltfm_suspend, | ||
226 | .resume = sdhci_pltfm_resume, | ||
227 | #endif | ||
228 | }; | 225 | }; |
229 | static int __init sdhci_pxav2_init(void) | 226 | static int __init sdhci_pxav2_init(void) |
230 | { | 227 | { |
diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c index cff4ad3e7a59..15673a7ee6a5 100644 --- a/drivers/mmc/host/sdhci-pxav3.c +++ b/drivers/mmc/host/sdhci-pxav3.c | |||
@@ -264,13 +264,10 @@ static struct platform_driver sdhci_pxav3_driver = { | |||
264 | .driver = { | 264 | .driver = { |
265 | .name = "sdhci-pxav3", | 265 | .name = "sdhci-pxav3", |
266 | .owner = THIS_MODULE, | 266 | .owner = THIS_MODULE, |
267 | .pm = SDHCI_PLTFM_PMOPS, | ||
267 | }, | 268 | }, |
268 | .probe = sdhci_pxav3_probe, | 269 | .probe = sdhci_pxav3_probe, |
269 | .remove = __devexit_p(sdhci_pxav3_remove), | 270 | .remove = __devexit_p(sdhci_pxav3_remove), |
270 | #ifdef CONFIG_PM | ||
271 | .suspend = sdhci_pltfm_suspend, | ||
272 | .resume = sdhci_pltfm_resume, | ||
273 | #endif | ||
274 | }; | 271 | }; |
275 | static int __init sdhci_pxav3_init(void) | 272 | static int __init sdhci_pxav3_init(void) |
276 | { | 273 | { |
diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c index 3d00e722efc9..9a20d1f55bb7 100644 --- a/drivers/mmc/host/sdhci-s3c.c +++ b/drivers/mmc/host/sdhci-s3c.c | |||
@@ -435,14 +435,11 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev) | |||
435 | 435 | ||
436 | for (clks = 0, ptr = 0; ptr < MAX_BUS_CLK; ptr++) { | 436 | for (clks = 0, ptr = 0; ptr < MAX_BUS_CLK; ptr++) { |
437 | struct clk *clk; | 437 | struct clk *clk; |
438 | char *name = pdata->clocks[ptr]; | 438 | char name[14]; |
439 | |||
440 | if (name == NULL) | ||
441 | continue; | ||
442 | 439 | ||
440 | snprintf(name, 14, "mmc_busclk.%d", ptr); | ||
443 | clk = clk_get(dev, name); | 441 | clk = clk_get(dev, name); |
444 | if (IS_ERR(clk)) { | 442 | if (IS_ERR(clk)) { |
445 | dev_err(dev, "failed to get clock %s\n", name); | ||
446 | continue; | 443 | continue; |
447 | } | 444 | } |
448 | 445 | ||
@@ -622,33 +619,38 @@ static int __devexit sdhci_s3c_remove(struct platform_device *pdev) | |||
622 | 619 | ||
623 | #ifdef CONFIG_PM | 620 | #ifdef CONFIG_PM |
624 | 621 | ||
625 | static int sdhci_s3c_suspend(struct platform_device *dev, pm_message_t pm) | 622 | static int sdhci_s3c_suspend(struct device *dev) |
626 | { | 623 | { |
627 | struct sdhci_host *host = platform_get_drvdata(dev); | 624 | struct sdhci_host *host = dev_get_drvdata(dev); |
628 | 625 | ||
629 | return sdhci_suspend_host(host, pm); | 626 | return sdhci_suspend_host(host); |
630 | } | 627 | } |
631 | 628 | ||
632 | static int sdhci_s3c_resume(struct platform_device *dev) | 629 | static int sdhci_s3c_resume(struct device *dev) |
633 | { | 630 | { |
634 | struct sdhci_host *host = platform_get_drvdata(dev); | 631 | struct sdhci_host *host = dev_get_drvdata(dev); |
635 | 632 | ||
636 | return sdhci_resume_host(host); | 633 | return sdhci_resume_host(host); |
637 | } | 634 | } |
638 | 635 | ||
636 | static const struct dev_pm_ops sdhci_s3c_pmops = { | ||
637 | .suspend = sdhci_s3c_suspend, | ||
638 | .resume = sdhci_s3c_resume, | ||
639 | }; | ||
640 | |||
641 | #define SDHCI_S3C_PMOPS (&sdhci_s3c_pmops) | ||
642 | |||
639 | #else | 643 | #else |
640 | #define sdhci_s3c_suspend NULL | 644 | #define SDHCI_S3C_PMOPS NULL |
641 | #define sdhci_s3c_resume NULL | ||
642 | #endif | 645 | #endif |
643 | 646 | ||
644 | static struct platform_driver sdhci_s3c_driver = { | 647 | static struct platform_driver sdhci_s3c_driver = { |
645 | .probe = sdhci_s3c_probe, | 648 | .probe = sdhci_s3c_probe, |
646 | .remove = __devexit_p(sdhci_s3c_remove), | 649 | .remove = __devexit_p(sdhci_s3c_remove), |
647 | .suspend = sdhci_s3c_suspend, | ||
648 | .resume = sdhci_s3c_resume, | ||
649 | .driver = { | 650 | .driver = { |
650 | .owner = THIS_MODULE, | 651 | .owner = THIS_MODULE, |
651 | .name = "s3c-sdhci", | 652 | .name = "s3c-sdhci", |
653 | .pm = SDHCI_S3C_PMOPS, | ||
652 | }, | 654 | }, |
653 | }; | 655 | }; |
654 | 656 | ||
diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c index 89699e861fc1..e2e18d3f949c 100644 --- a/drivers/mmc/host/sdhci-tegra.c +++ b/drivers/mmc/host/sdhci-tegra.c | |||
@@ -318,13 +318,10 @@ static struct platform_driver sdhci_tegra_driver = { | |||
318 | .name = "sdhci-tegra", | 318 | .name = "sdhci-tegra", |
319 | .owner = THIS_MODULE, | 319 | .owner = THIS_MODULE, |
320 | .of_match_table = sdhci_tegra_dt_match, | 320 | .of_match_table = sdhci_tegra_dt_match, |
321 | .pm = SDHCI_PLTFM_PMOPS, | ||
321 | }, | 322 | }, |
322 | .probe = sdhci_tegra_probe, | 323 | .probe = sdhci_tegra_probe, |
323 | .remove = __devexit_p(sdhci_tegra_remove), | 324 | .remove = __devexit_p(sdhci_tegra_remove), |
324 | #ifdef CONFIG_PM | ||
325 | .suspend = sdhci_pltfm_suspend, | ||
326 | .resume = sdhci_pltfm_resume, | ||
327 | #endif | ||
328 | }; | 325 | }; |
329 | 326 | ||
330 | static int __init sdhci_tegra_init(void) | 327 | static int __init sdhci_tegra_init(void) |
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 6d8eea323541..19ed580f2cab 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c | |||
@@ -2327,7 +2327,7 @@ out: | |||
2327 | 2327 | ||
2328 | #ifdef CONFIG_PM | 2328 | #ifdef CONFIG_PM |
2329 | 2329 | ||
2330 | int sdhci_suspend_host(struct sdhci_host *host, pm_message_t state) | 2330 | int sdhci_suspend_host(struct sdhci_host *host) |
2331 | { | 2331 | { |
2332 | int ret; | 2332 | int ret; |
2333 | 2333 | ||
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index 0a5b65460d8a..a04d4d0c6fd2 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h | |||
@@ -374,7 +374,7 @@ extern int sdhci_add_host(struct sdhci_host *host); | |||
374 | extern void sdhci_remove_host(struct sdhci_host *host, int dead); | 374 | extern void sdhci_remove_host(struct sdhci_host *host, int dead); |
375 | 375 | ||
376 | #ifdef CONFIG_PM | 376 | #ifdef CONFIG_PM |
377 | extern int sdhci_suspend_host(struct sdhci_host *host, pm_message_t state); | 377 | extern int sdhci_suspend_host(struct sdhci_host *host); |
378 | extern int sdhci_resume_host(struct sdhci_host *host); | 378 | extern int sdhci_resume_host(struct sdhci_host *host); |
379 | extern void sdhci_enable_irq_wakeups(struct sdhci_host *host); | 379 | extern void sdhci_enable_irq_wakeups(struct sdhci_host *host); |
380 | #endif | 380 | #endif |
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/drivers/mmc/host/ushc.c b/drivers/mmc/host/ushc.c index f08f944ac53c..c0105a2e269a 100644 --- a/drivers/mmc/host/ushc.c +++ b/drivers/mmc/host/ushc.c | |||
@@ -562,17 +562,7 @@ static struct usb_driver ushc_driver = { | |||
562 | .disconnect = ushc_disconnect, | 562 | .disconnect = ushc_disconnect, |
563 | }; | 563 | }; |
564 | 564 | ||
565 | static int __init ushc_init(void) | 565 | module_usb_driver(ushc_driver); |
566 | { | ||
567 | return usb_register(&ushc_driver); | ||
568 | } | ||
569 | module_init(ushc_init); | ||
570 | |||
571 | static void __exit ushc_exit(void) | ||
572 | { | ||
573 | usb_deregister(&ushc_driver); | ||
574 | } | ||
575 | module_exit(ushc_exit); | ||
576 | 566 | ||
577 | MODULE_DESCRIPTION("USB SD Host Controller driver"); | 567 | MODULE_DESCRIPTION("USB SD Host Controller driver"); |
578 | MODULE_AUTHOR("David Vrabel <david.vrabel@csr.com>"); | 568 | MODULE_AUTHOR("David Vrabel <david.vrabel@csr.com>"); |
diff --git a/drivers/mmc/host/vub300.c b/drivers/mmc/host/vub300.c index e8f6e65183d7..2ec978bc32ba 100644 --- a/drivers/mmc/host/vub300.c +++ b/drivers/mmc/host/vub300.c | |||
@@ -259,7 +259,7 @@ static int firmware_rom_wait_states = 0x04; | |||
259 | static int firmware_rom_wait_states = 0x1C; | 259 | static int firmware_rom_wait_states = 0x1C; |
260 | #endif | 260 | #endif |
261 | 261 | ||
262 | module_param(firmware_rom_wait_states, bool, 0644); | 262 | module_param(firmware_rom_wait_states, int, 0644); |
263 | MODULE_PARM_DESC(firmware_rom_wait_states, | 263 | MODULE_PARM_DESC(firmware_rom_wait_states, |
264 | "ROM wait states byte=RRRIIEEE (Reserved Internal External)"); | 264 | "ROM wait states byte=RRRIIEEE (Reserved Internal External)"); |
265 | 265 | ||