diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-07-10 14:16:00 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-07-10 14:16:00 -0400 |
commit | bfffbea1aaeeb1eb6500c83ff9653416daa5b490 (patch) | |
tree | 1325ecb176b7a3d04924d6a1563b15ad6085d36a /drivers/mmc/core | |
parent | 34ae0a6f05aee9f51fca17001b4a90703d434ae1 (diff) | |
parent | 01ebea1b411aafc8eab440bf1d2037f01bbed99b (diff) |
Merge tag 'mmc-updates-for-3.11-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/cjb/mmc
Pull MMC updates from Chris Ball:
"MMC highlights for 3.11:
Core:
- Add support for eMMC 5.1 devices
- Add MMC_CAP_AGGRESSIVE_PM capability for aggressive power
management of eMMC/SD between requests, using runtime PM
- Add an ioctl to perform the eMMC 4.5 Sanitize command. Sample code
at:
git://git.kernel.org/pub/scm/linux/kernel/git/cjb/mmc-utils.git
Drivers:
- dw_mmc: Add support for Rockchip's Cortex-A9 SoCs
- dw_mmc: Add support for Altera SoCFPGAs
- sdhci-esdhc-imx: Add support for 8-bit bus width, non-removable
cards
- sdhci-bcm-kona: New driver for Broadcom Kona (281xx) SoCs
- sdhi/tmio: Add DT DMA support"
* tag 'mmc-updates-for-3.11-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/cjb/mmc: (87 commits)
mmc: bcm281xx SDHCI driver
mmc: sdhci: add card_event callback to sdhci
mmc: core: Fixup Oops for SDIO shutdown
mmc: sdhci-pci: add another device id
mmc: esdhc: Fix bug when writing to SDHCI_HOST_CONTROL register
mmc: esdhc: Add support for 8-bit bus width and non-removable card
mmc: core: production year for eMMC 4.41 and later
mmc: omap: remove unnecessary #if 0's
mmc: sdhci: fix ctrl_2 on super-speed selection
mmc: dw_mmc-pltfm: add Rockchip variant
mmc: dw_mmc-pltfm: move probe and remove below dt match table
mmc: dw_mmc-pltfm: remove static from dw_mci_pltfm_remove
mmc: sdhci-acpi: add support for eMMC hardware reset for HID 80860F14
mmc: sdhci-pci: add support for eMMC hardware reset for BYT eMMC.
mmc: dw_mmc: Add support DW SD/MMC driver on SOCFPGA
mmc: sdhci: fix caps2 for HS200
sdhci-pxav3: Fix runtime PM initialization
mmc: core: Add DT-bindings for MMC_CAP2_FULL_PWR_CYCLE
mmc: core: Invent MMC_CAP2_FULL_PWR_CYCLE
mmc: core: Enable power_off_notify for eMMC shutdown sequence
...
Diffstat (limited to 'drivers/mmc/core')
-rw-r--r-- | drivers/mmc/core/bus.c | 52 | ||||
-rw-r--r-- | drivers/mmc/core/core.c | 200 | ||||
-rw-r--r-- | drivers/mmc/core/core.h | 7 | ||||
-rw-r--r-- | drivers/mmc/core/debugfs.c | 8 | ||||
-rw-r--r-- | drivers/mmc/core/host.c | 32 | ||||
-rw-r--r-- | drivers/mmc/core/mmc.c | 249 | ||||
-rw-r--r-- | drivers/mmc/core/mmc_ops.c | 36 | ||||
-rw-r--r-- | drivers/mmc/core/mmc_ops.h | 1 | ||||
-rw-r--r-- | drivers/mmc/core/sd.c | 68 | ||||
-rw-r--r-- | drivers/mmc/core/sdio.c | 76 |
10 files changed, 457 insertions, 272 deletions
diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c index 9d5c71125576..704bf66f5873 100644 --- a/drivers/mmc/core/bus.c +++ b/drivers/mmc/core/bus.c | |||
@@ -122,15 +122,39 @@ static int mmc_bus_remove(struct device *dev) | |||
122 | return 0; | 122 | return 0; |
123 | } | 123 | } |
124 | 124 | ||
125 | static void mmc_bus_shutdown(struct device *dev) | ||
126 | { | ||
127 | struct mmc_driver *drv = to_mmc_driver(dev->driver); | ||
128 | struct mmc_card *card = mmc_dev_to_card(dev); | ||
129 | struct mmc_host *host = card->host; | ||
130 | int ret; | ||
131 | |||
132 | if (dev->driver && drv->shutdown) | ||
133 | drv->shutdown(card); | ||
134 | |||
135 | if (host->bus_ops->shutdown) { | ||
136 | ret = host->bus_ops->shutdown(host); | ||
137 | if (ret) | ||
138 | pr_warn("%s: error %d during shutdown\n", | ||
139 | mmc_hostname(host), ret); | ||
140 | } | ||
141 | } | ||
142 | |||
125 | #ifdef CONFIG_PM_SLEEP | 143 | #ifdef CONFIG_PM_SLEEP |
126 | static int mmc_bus_suspend(struct device *dev) | 144 | static int mmc_bus_suspend(struct device *dev) |
127 | { | 145 | { |
128 | struct mmc_driver *drv = to_mmc_driver(dev->driver); | 146 | struct mmc_driver *drv = to_mmc_driver(dev->driver); |
129 | struct mmc_card *card = mmc_dev_to_card(dev); | 147 | struct mmc_card *card = mmc_dev_to_card(dev); |
130 | int ret = 0; | 148 | struct mmc_host *host = card->host; |
149 | int ret; | ||
131 | 150 | ||
132 | if (dev->driver && drv->suspend) | 151 | if (dev->driver && drv->suspend) { |
133 | ret = drv->suspend(card); | 152 | ret = drv->suspend(card); |
153 | if (ret) | ||
154 | return ret; | ||
155 | } | ||
156 | |||
157 | ret = host->bus_ops->suspend(host); | ||
134 | return ret; | 158 | return ret; |
135 | } | 159 | } |
136 | 160 | ||
@@ -138,10 +162,17 @@ static int mmc_bus_resume(struct device *dev) | |||
138 | { | 162 | { |
139 | struct mmc_driver *drv = to_mmc_driver(dev->driver); | 163 | struct mmc_driver *drv = to_mmc_driver(dev->driver); |
140 | struct mmc_card *card = mmc_dev_to_card(dev); | 164 | struct mmc_card *card = mmc_dev_to_card(dev); |
141 | int ret = 0; | 165 | struct mmc_host *host = card->host; |
166 | int ret; | ||
167 | |||
168 | ret = host->bus_ops->resume(host); | ||
169 | if (ret) | ||
170 | pr_warn("%s: error %d during resume (card was removed?)\n", | ||
171 | mmc_hostname(host), ret); | ||
142 | 172 | ||
143 | if (dev->driver && drv->resume) | 173 | if (dev->driver && drv->resume) |
144 | ret = drv->resume(card); | 174 | ret = drv->resume(card); |
175 | |||
145 | return ret; | 176 | return ret; |
146 | } | 177 | } |
147 | #endif | 178 | #endif |
@@ -151,15 +182,25 @@ static int mmc_bus_resume(struct device *dev) | |||
151 | static int mmc_runtime_suspend(struct device *dev) | 182 | static int mmc_runtime_suspend(struct device *dev) |
152 | { | 183 | { |
153 | struct mmc_card *card = mmc_dev_to_card(dev); | 184 | struct mmc_card *card = mmc_dev_to_card(dev); |
185 | struct mmc_host *host = card->host; | ||
186 | int ret = 0; | ||
187 | |||
188 | if (host->bus_ops->runtime_suspend) | ||
189 | ret = host->bus_ops->runtime_suspend(host); | ||
154 | 190 | ||
155 | return mmc_power_save_host(card->host); | 191 | return ret; |
156 | } | 192 | } |
157 | 193 | ||
158 | static int mmc_runtime_resume(struct device *dev) | 194 | static int mmc_runtime_resume(struct device *dev) |
159 | { | 195 | { |
160 | struct mmc_card *card = mmc_dev_to_card(dev); | 196 | struct mmc_card *card = mmc_dev_to_card(dev); |
197 | struct mmc_host *host = card->host; | ||
198 | int ret = 0; | ||
199 | |||
200 | if (host->bus_ops->runtime_resume) | ||
201 | ret = host->bus_ops->runtime_resume(host); | ||
161 | 202 | ||
162 | return mmc_power_restore_host(card->host); | 203 | return ret; |
163 | } | 204 | } |
164 | 205 | ||
165 | static int mmc_runtime_idle(struct device *dev) | 206 | static int mmc_runtime_idle(struct device *dev) |
@@ -182,6 +223,7 @@ static struct bus_type mmc_bus_type = { | |||
182 | .uevent = mmc_bus_uevent, | 223 | .uevent = mmc_bus_uevent, |
183 | .probe = mmc_bus_probe, | 224 | .probe = mmc_bus_probe, |
184 | .remove = mmc_bus_remove, | 225 | .remove = mmc_bus_remove, |
226 | .shutdown = mmc_bus_shutdown, | ||
185 | .pm = &mmc_bus_pm_ops, | 227 | .pm = &mmc_bus_pm_ops, |
186 | }; | 228 | }; |
187 | 229 | ||
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index c40396f23202..49a5bca418bd 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c | |||
@@ -402,6 +402,7 @@ static int mmc_wait_for_data_req_done(struct mmc_host *host, | |||
402 | context_info->is_done_rcv = false; | 402 | context_info->is_done_rcv = false; |
403 | context_info->is_new_req = false; | 403 | context_info->is_new_req = false; |
404 | cmd = mrq->cmd; | 404 | cmd = mrq->cmd; |
405 | |||
405 | if (!cmd->error || !cmd->retries || | 406 | if (!cmd->error || !cmd->retries || |
406 | mmc_card_removed(host->card)) { | 407 | mmc_card_removed(host->card)) { |
407 | err = host->areq->err_check(host->card, | 408 | err = host->areq->err_check(host->card, |
@@ -436,6 +437,24 @@ static void mmc_wait_for_req_done(struct mmc_host *host, | |||
436 | wait_for_completion(&mrq->completion); | 437 | wait_for_completion(&mrq->completion); |
437 | 438 | ||
438 | cmd = mrq->cmd; | 439 | cmd = mrq->cmd; |
440 | |||
441 | /* | ||
442 | * If host has timed out waiting for the sanitize | ||
443 | * to complete, card might be still in programming state | ||
444 | * so let's try to bring the card out of programming | ||
445 | * state. | ||
446 | */ | ||
447 | if (cmd->sanitize_busy && cmd->error == -ETIMEDOUT) { | ||
448 | if (!mmc_interrupt_hpi(host->card)) { | ||
449 | pr_warning("%s: %s: Interrupted sanitize\n", | ||
450 | mmc_hostname(host), __func__); | ||
451 | cmd->error = 0; | ||
452 | break; | ||
453 | } else { | ||
454 | pr_err("%s: %s: Failed to interrupt sanitize\n", | ||
455 | mmc_hostname(host), __func__); | ||
456 | } | ||
457 | } | ||
439 | if (!cmd->error || !cmd->retries || | 458 | if (!cmd->error || !cmd->retries || |
440 | mmc_card_removed(host->card)) | 459 | mmc_card_removed(host->card)) |
441 | break; | 460 | break; |
@@ -952,6 +971,29 @@ void mmc_release_host(struct mmc_host *host) | |||
952 | EXPORT_SYMBOL(mmc_release_host); | 971 | EXPORT_SYMBOL(mmc_release_host); |
953 | 972 | ||
954 | /* | 973 | /* |
974 | * This is a helper function, which fetches a runtime pm reference for the | ||
975 | * card device and also claims the host. | ||
976 | */ | ||
977 | void mmc_get_card(struct mmc_card *card) | ||
978 | { | ||
979 | pm_runtime_get_sync(&card->dev); | ||
980 | mmc_claim_host(card->host); | ||
981 | } | ||
982 | EXPORT_SYMBOL(mmc_get_card); | ||
983 | |||
984 | /* | ||
985 | * This is a helper function, which releases the host and drops the runtime | ||
986 | * pm reference for the card device. | ||
987 | */ | ||
988 | void mmc_put_card(struct mmc_card *card) | ||
989 | { | ||
990 | mmc_release_host(card->host); | ||
991 | pm_runtime_mark_last_busy(&card->dev); | ||
992 | pm_runtime_put_autosuspend(&card->dev); | ||
993 | } | ||
994 | EXPORT_SYMBOL(mmc_put_card); | ||
995 | |||
996 | /* | ||
955 | * Internal function that does the actual ios call to the host driver, | 997 | * Internal function that does the actual ios call to the host driver, |
956 | * optionally printing some debug output. | 998 | * optionally printing some debug output. |
957 | */ | 999 | */ |
@@ -1459,7 +1501,7 @@ void mmc_set_driver_type(struct mmc_host *host, unsigned int drv_type) | |||
1459 | * If a host does all the power sequencing itself, ignore the | 1501 | * If a host does all the power sequencing itself, ignore the |
1460 | * initial MMC_POWER_UP stage. | 1502 | * initial MMC_POWER_UP stage. |
1461 | */ | 1503 | */ |
1462 | static void mmc_power_up(struct mmc_host *host) | 1504 | void mmc_power_up(struct mmc_host *host) |
1463 | { | 1505 | { |
1464 | int bit; | 1506 | int bit; |
1465 | 1507 | ||
@@ -2325,14 +2367,13 @@ int mmc_detect_card_removed(struct mmc_host *host) | |||
2325 | * The card will be considered unchanged unless we have been asked to | 2367 | * The card will be considered unchanged unless we have been asked to |
2326 | * detect a change or host requires polling to provide card detection. | 2368 | * detect a change or host requires polling to provide card detection. |
2327 | */ | 2369 | */ |
2328 | if (!host->detect_change && !(host->caps & MMC_CAP_NEEDS_POLL) && | 2370 | if (!host->detect_change && !(host->caps & MMC_CAP_NEEDS_POLL)) |
2329 | !(host->caps2 & MMC_CAP2_DETECT_ON_ERR)) | ||
2330 | return ret; | 2371 | return ret; |
2331 | 2372 | ||
2332 | host->detect_change = 0; | 2373 | host->detect_change = 0; |
2333 | if (!ret) { | 2374 | if (!ret) { |
2334 | ret = _mmc_detect_card_removed(host); | 2375 | ret = _mmc_detect_card_removed(host); |
2335 | if (ret && (host->caps2 & MMC_CAP2_DETECT_ON_ERR)) { | 2376 | if (ret && (host->caps & MMC_CAP_NEEDS_POLL)) { |
2336 | /* | 2377 | /* |
2337 | * Schedule a detect work as soon as possible to let a | 2378 | * Schedule a detect work as soon as possible to let a |
2338 | * rescan handle the card removal. | 2379 | * rescan handle the card removal. |
@@ -2442,9 +2483,7 @@ void mmc_stop_host(struct mmc_host *host) | |||
2442 | mmc_bus_get(host); | 2483 | mmc_bus_get(host); |
2443 | if (host->bus_ops && !host->bus_dead) { | 2484 | if (host->bus_ops && !host->bus_dead) { |
2444 | /* Calling bus_ops->remove() with a claimed host can deadlock */ | 2485 | /* Calling bus_ops->remove() with a claimed host can deadlock */ |
2445 | if (host->bus_ops->remove) | 2486 | host->bus_ops->remove(host); |
2446 | host->bus_ops->remove(host); | ||
2447 | |||
2448 | mmc_claim_host(host); | 2487 | mmc_claim_host(host); |
2449 | mmc_detach_bus(host); | 2488 | mmc_detach_bus(host); |
2450 | mmc_power_off(host); | 2489 | mmc_power_off(host); |
@@ -2509,52 +2548,6 @@ int mmc_power_restore_host(struct mmc_host *host) | |||
2509 | } | 2548 | } |
2510 | EXPORT_SYMBOL(mmc_power_restore_host); | 2549 | EXPORT_SYMBOL(mmc_power_restore_host); |
2511 | 2550 | ||
2512 | int mmc_card_awake(struct mmc_host *host) | ||
2513 | { | ||
2514 | int err = -ENOSYS; | ||
2515 | |||
2516 | if (host->caps2 & MMC_CAP2_NO_SLEEP_CMD) | ||
2517 | return 0; | ||
2518 | |||
2519 | mmc_bus_get(host); | ||
2520 | |||
2521 | if (host->bus_ops && !host->bus_dead && host->bus_ops->awake) | ||
2522 | err = host->bus_ops->awake(host); | ||
2523 | |||
2524 | mmc_bus_put(host); | ||
2525 | |||
2526 | return err; | ||
2527 | } | ||
2528 | EXPORT_SYMBOL(mmc_card_awake); | ||
2529 | |||
2530 | int mmc_card_sleep(struct mmc_host *host) | ||
2531 | { | ||
2532 | int err = -ENOSYS; | ||
2533 | |||
2534 | if (host->caps2 & MMC_CAP2_NO_SLEEP_CMD) | ||
2535 | return 0; | ||
2536 | |||
2537 | mmc_bus_get(host); | ||
2538 | |||
2539 | if (host->bus_ops && !host->bus_dead && host->bus_ops->sleep) | ||
2540 | err = host->bus_ops->sleep(host); | ||
2541 | |||
2542 | mmc_bus_put(host); | ||
2543 | |||
2544 | return err; | ||
2545 | } | ||
2546 | EXPORT_SYMBOL(mmc_card_sleep); | ||
2547 | |||
2548 | int mmc_card_can_sleep(struct mmc_host *host) | ||
2549 | { | ||
2550 | struct mmc_card *card = host->card; | ||
2551 | |||
2552 | if (card && mmc_card_mmc(card) && card->ext_csd.rev >= 3) | ||
2553 | return 1; | ||
2554 | return 0; | ||
2555 | } | ||
2556 | EXPORT_SYMBOL(mmc_card_can_sleep); | ||
2557 | |||
2558 | /* | 2551 | /* |
2559 | * Flush the cache to the non-volatile storage. | 2552 | * Flush the cache to the non-volatile storage. |
2560 | */ | 2553 | */ |
@@ -2626,48 +2619,9 @@ EXPORT_SYMBOL(mmc_cache_ctrl); | |||
2626 | */ | 2619 | */ |
2627 | int mmc_suspend_host(struct mmc_host *host) | 2620 | int mmc_suspend_host(struct mmc_host *host) |
2628 | { | 2621 | { |
2629 | int err = 0; | 2622 | /* This function is deprecated */ |
2630 | 2623 | return 0; | |
2631 | cancel_delayed_work(&host->detect); | ||
2632 | mmc_flush_scheduled_work(); | ||
2633 | |||
2634 | mmc_bus_get(host); | ||
2635 | if (host->bus_ops && !host->bus_dead) { | ||
2636 | if (host->bus_ops->suspend) { | ||
2637 | if (mmc_card_doing_bkops(host->card)) { | ||
2638 | err = mmc_stop_bkops(host->card); | ||
2639 | if (err) | ||
2640 | goto out; | ||
2641 | } | ||
2642 | err = host->bus_ops->suspend(host); | ||
2643 | } | ||
2644 | |||
2645 | if (err == -ENOSYS || !host->bus_ops->resume) { | ||
2646 | /* | ||
2647 | * We simply "remove" the card in this case. | ||
2648 | * It will be redetected on resume. (Calling | ||
2649 | * bus_ops->remove() with a claimed host can | ||
2650 | * deadlock.) | ||
2651 | */ | ||
2652 | if (host->bus_ops->remove) | ||
2653 | host->bus_ops->remove(host); | ||
2654 | mmc_claim_host(host); | ||
2655 | mmc_detach_bus(host); | ||
2656 | mmc_power_off(host); | ||
2657 | mmc_release_host(host); | ||
2658 | host->pm_flags = 0; | ||
2659 | err = 0; | ||
2660 | } | ||
2661 | } | ||
2662 | mmc_bus_put(host); | ||
2663 | |||
2664 | if (!err && !mmc_card_keep_power(host)) | ||
2665 | mmc_power_off(host); | ||
2666 | |||
2667 | out: | ||
2668 | return err; | ||
2669 | } | 2624 | } |
2670 | |||
2671 | EXPORT_SYMBOL(mmc_suspend_host); | 2625 | EXPORT_SYMBOL(mmc_suspend_host); |
2672 | 2626 | ||
2673 | /** | 2627 | /** |
@@ -2676,39 +2630,8 @@ EXPORT_SYMBOL(mmc_suspend_host); | |||
2676 | */ | 2630 | */ |
2677 | int mmc_resume_host(struct mmc_host *host) | 2631 | int mmc_resume_host(struct mmc_host *host) |
2678 | { | 2632 | { |
2679 | int err = 0; | 2633 | /* This function is deprecated */ |
2680 | 2634 | return 0; | |
2681 | mmc_bus_get(host); | ||
2682 | if (host->bus_ops && !host->bus_dead) { | ||
2683 | if (!mmc_card_keep_power(host)) { | ||
2684 | mmc_power_up(host); | ||
2685 | mmc_select_voltage(host, host->ocr); | ||
2686 | /* | ||
2687 | * Tell runtime PM core we just powered up the card, | ||
2688 | * since it still believes the card is powered off. | ||
2689 | * Note that currently runtime PM is only enabled | ||
2690 | * for SDIO cards that are MMC_CAP_POWER_OFF_CARD | ||
2691 | */ | ||
2692 | if (mmc_card_sdio(host->card) && | ||
2693 | (host->caps & MMC_CAP_POWER_OFF_CARD)) { | ||
2694 | pm_runtime_disable(&host->card->dev); | ||
2695 | pm_runtime_set_active(&host->card->dev); | ||
2696 | pm_runtime_enable(&host->card->dev); | ||
2697 | } | ||
2698 | } | ||
2699 | BUG_ON(!host->bus_ops->resume); | ||
2700 | err = host->bus_ops->resume(host); | ||
2701 | if (err) { | ||
2702 | pr_warning("%s: error %d during resume " | ||
2703 | "(card was removed?)\n", | ||
2704 | mmc_hostname(host), err); | ||
2705 | err = 0; | ||
2706 | } | ||
2707 | } | ||
2708 | host->pm_flags &= ~MMC_PM_KEEP_POWER; | ||
2709 | mmc_bus_put(host); | ||
2710 | |||
2711 | return err; | ||
2712 | } | 2635 | } |
2713 | EXPORT_SYMBOL(mmc_resume_host); | 2636 | EXPORT_SYMBOL(mmc_resume_host); |
2714 | 2637 | ||
@@ -2727,29 +2650,22 @@ int mmc_pm_notify(struct notifier_block *notify_block, | |||
2727 | switch (mode) { | 2650 | switch (mode) { |
2728 | case PM_HIBERNATION_PREPARE: | 2651 | case PM_HIBERNATION_PREPARE: |
2729 | case PM_SUSPEND_PREPARE: | 2652 | case PM_SUSPEND_PREPARE: |
2730 | if (host->card && mmc_card_mmc(host->card) && | ||
2731 | mmc_card_doing_bkops(host->card)) { | ||
2732 | err = mmc_stop_bkops(host->card); | ||
2733 | if (err) { | ||
2734 | pr_err("%s: didn't stop bkops\n", | ||
2735 | mmc_hostname(host)); | ||
2736 | return err; | ||
2737 | } | ||
2738 | mmc_card_clr_doing_bkops(host->card); | ||
2739 | } | ||
2740 | |||
2741 | spin_lock_irqsave(&host->lock, flags); | 2653 | spin_lock_irqsave(&host->lock, flags); |
2742 | host->rescan_disable = 1; | 2654 | host->rescan_disable = 1; |
2743 | spin_unlock_irqrestore(&host->lock, flags); | 2655 | spin_unlock_irqrestore(&host->lock, flags); |
2744 | cancel_delayed_work_sync(&host->detect); | 2656 | cancel_delayed_work_sync(&host->detect); |
2745 | 2657 | ||
2746 | if (!host->bus_ops || host->bus_ops->suspend) | 2658 | if (!host->bus_ops) |
2747 | break; | 2659 | break; |
2748 | 2660 | ||
2749 | /* Calling bus_ops->remove() with a claimed host can deadlock */ | 2661 | /* Validate prerequisites for suspend */ |
2750 | if (host->bus_ops->remove) | 2662 | if (host->bus_ops->pre_suspend) |
2751 | host->bus_ops->remove(host); | 2663 | err = host->bus_ops->pre_suspend(host); |
2664 | if (!err && host->bus_ops->suspend) | ||
2665 | break; | ||
2752 | 2666 | ||
2667 | /* Calling bus_ops->remove() with a claimed host can deadlock */ | ||
2668 | host->bus_ops->remove(host); | ||
2753 | mmc_claim_host(host); | 2669 | mmc_claim_host(host); |
2754 | mmc_detach_bus(host); | 2670 | mmc_detach_bus(host); |
2755 | mmc_power_off(host); | 2671 | mmc_power_off(host); |
diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h index b9f18a2a8874..5345d156493e 100644 --- a/drivers/mmc/core/core.h +++ b/drivers/mmc/core/core.h | |||
@@ -16,15 +16,17 @@ | |||
16 | #define MMC_CMD_RETRIES 3 | 16 | #define MMC_CMD_RETRIES 3 |
17 | 17 | ||
18 | struct mmc_bus_ops { | 18 | struct mmc_bus_ops { |
19 | int (*awake)(struct mmc_host *); | ||
20 | int (*sleep)(struct mmc_host *); | ||
21 | void (*remove)(struct mmc_host *); | 19 | void (*remove)(struct mmc_host *); |
22 | void (*detect)(struct mmc_host *); | 20 | void (*detect)(struct mmc_host *); |
21 | int (*pre_suspend)(struct mmc_host *); | ||
23 | int (*suspend)(struct mmc_host *); | 22 | int (*suspend)(struct mmc_host *); |
24 | int (*resume)(struct mmc_host *); | 23 | int (*resume)(struct mmc_host *); |
24 | int (*runtime_suspend)(struct mmc_host *); | ||
25 | int (*runtime_resume)(struct mmc_host *); | ||
25 | int (*power_save)(struct mmc_host *); | 26 | int (*power_save)(struct mmc_host *); |
26 | int (*power_restore)(struct mmc_host *); | 27 | int (*power_restore)(struct mmc_host *); |
27 | int (*alive)(struct mmc_host *); | 28 | int (*alive)(struct mmc_host *); |
29 | int (*shutdown)(struct mmc_host *); | ||
28 | }; | 30 | }; |
29 | 31 | ||
30 | void mmc_attach_bus(struct mmc_host *host, const struct mmc_bus_ops *ops); | 32 | void mmc_attach_bus(struct mmc_host *host, const struct mmc_bus_ops *ops); |
@@ -44,6 +46,7 @@ int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage); | |||
44 | int __mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage); | 46 | int __mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage); |
45 | void mmc_set_timing(struct mmc_host *host, unsigned int timing); | 47 | void mmc_set_timing(struct mmc_host *host, unsigned int timing); |
46 | void mmc_set_driver_type(struct mmc_host *host, unsigned int drv_type); | 48 | void mmc_set_driver_type(struct mmc_host *host, unsigned int drv_type); |
49 | void mmc_power_up(struct mmc_host *host); | ||
47 | void mmc_power_off(struct mmc_host *host); | 50 | void mmc_power_off(struct mmc_host *host); |
48 | void mmc_power_cycle(struct mmc_host *host); | 51 | void mmc_power_cycle(struct mmc_host *host); |
49 | 52 | ||
diff --git a/drivers/mmc/core/debugfs.c b/drivers/mmc/core/debugfs.c index 35c2f85b1956..54829c0ed000 100644 --- a/drivers/mmc/core/debugfs.c +++ b/drivers/mmc/core/debugfs.c | |||
@@ -258,13 +258,13 @@ static int mmc_dbg_card_status_get(void *data, u64 *val) | |||
258 | u32 status; | 258 | u32 status; |
259 | int ret; | 259 | int ret; |
260 | 260 | ||
261 | mmc_claim_host(card->host); | 261 | mmc_get_card(card); |
262 | 262 | ||
263 | ret = mmc_send_status(data, &status); | 263 | ret = mmc_send_status(data, &status); |
264 | if (!ret) | 264 | if (!ret) |
265 | *val = status; | 265 | *val = status; |
266 | 266 | ||
267 | mmc_release_host(card->host); | 267 | mmc_put_card(card); |
268 | 268 | ||
269 | return ret; | 269 | return ret; |
270 | } | 270 | } |
@@ -291,9 +291,9 @@ static int mmc_ext_csd_open(struct inode *inode, struct file *filp) | |||
291 | goto out_free; | 291 | goto out_free; |
292 | } | 292 | } |
293 | 293 | ||
294 | mmc_claim_host(card->host); | 294 | mmc_get_card(card); |
295 | err = mmc_send_ext_csd(card, ext_csd); | 295 | err = mmc_send_ext_csd(card, ext_csd); |
296 | mmc_release_host(card->host); | 296 | mmc_put_card(card); |
297 | if (err) | 297 | if (err) |
298 | goto out_free; | 298 | goto out_free; |
299 | 299 | ||
diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c index 2a3593d9f87d..6fb6f77450cb 100644 --- a/drivers/mmc/core/host.c +++ b/drivers/mmc/core/host.c | |||
@@ -306,7 +306,7 @@ static inline void mmc_host_clk_sysfs_init(struct mmc_host *host) | |||
306 | * parse the properties and set respective generic mmc-host flags and | 306 | * parse the properties and set respective generic mmc-host flags and |
307 | * parameters. | 307 | * parameters. |
308 | */ | 308 | */ |
309 | void mmc_of_parse(struct mmc_host *host) | 309 | int mmc_of_parse(struct mmc_host *host) |
310 | { | 310 | { |
311 | struct device_node *np; | 311 | struct device_node *np; |
312 | u32 bus_width; | 312 | u32 bus_width; |
@@ -315,7 +315,7 @@ void mmc_of_parse(struct mmc_host *host) | |||
315 | int len, ret, gpio; | 315 | int len, ret, gpio; |
316 | 316 | ||
317 | if (!host->parent || !host->parent->of_node) | 317 | if (!host->parent || !host->parent->of_node) |
318 | return; | 318 | return 0; |
319 | 319 | ||
320 | np = host->parent->of_node; | 320 | np = host->parent->of_node; |
321 | 321 | ||
@@ -338,6 +338,7 @@ void mmc_of_parse(struct mmc_host *host) | |||
338 | default: | 338 | default: |
339 | dev_err(host->parent, | 339 | dev_err(host->parent, |
340 | "Invalid \"bus-width\" value %ud!\n", bus_width); | 340 | "Invalid \"bus-width\" value %ud!\n", bus_width); |
341 | return -EINVAL; | ||
341 | } | 342 | } |
342 | 343 | ||
343 | /* f_max is obtained from the optional "max-frequency" property */ | 344 | /* f_max is obtained from the optional "max-frequency" property */ |
@@ -367,18 +368,22 @@ void mmc_of_parse(struct mmc_host *host) | |||
367 | host->caps |= MMC_CAP_NEEDS_POLL; | 368 | host->caps |= MMC_CAP_NEEDS_POLL; |
368 | 369 | ||
369 | gpio = of_get_named_gpio_flags(np, "cd-gpios", 0, &flags); | 370 | gpio = of_get_named_gpio_flags(np, "cd-gpios", 0, &flags); |
371 | if (gpio == -EPROBE_DEFER) | ||
372 | return gpio; | ||
370 | if (gpio_is_valid(gpio)) { | 373 | if (gpio_is_valid(gpio)) { |
371 | if (!(flags & OF_GPIO_ACTIVE_LOW)) | 374 | if (!(flags & OF_GPIO_ACTIVE_LOW)) |
372 | gpio_inv_cd = true; | 375 | gpio_inv_cd = true; |
373 | 376 | ||
374 | ret = mmc_gpio_request_cd(host, gpio); | 377 | ret = mmc_gpio_request_cd(host, gpio); |
375 | if (ret < 0) | 378 | if (ret < 0) { |
376 | dev_err(host->parent, | 379 | dev_err(host->parent, |
377 | "Failed to request CD GPIO #%d: %d!\n", | 380 | "Failed to request CD GPIO #%d: %d!\n", |
378 | gpio, ret); | 381 | gpio, ret); |
379 | else | 382 | return ret; |
383 | } else { | ||
380 | dev_info(host->parent, "Got CD GPIO #%d.\n", | 384 | dev_info(host->parent, "Got CD GPIO #%d.\n", |
381 | gpio); | 385 | gpio); |
386 | } | ||
382 | } | 387 | } |
383 | 388 | ||
384 | if (explicit_inv_cd ^ gpio_inv_cd) | 389 | if (explicit_inv_cd ^ gpio_inv_cd) |
@@ -389,14 +394,23 @@ void mmc_of_parse(struct mmc_host *host) | |||
389 | explicit_inv_wp = of_property_read_bool(np, "wp-inverted"); | 394 | explicit_inv_wp = of_property_read_bool(np, "wp-inverted"); |
390 | 395 | ||
391 | gpio = of_get_named_gpio_flags(np, "wp-gpios", 0, &flags); | 396 | gpio = of_get_named_gpio_flags(np, "wp-gpios", 0, &flags); |
397 | if (gpio == -EPROBE_DEFER) { | ||
398 | ret = -EPROBE_DEFER; | ||
399 | goto out; | ||
400 | } | ||
392 | if (gpio_is_valid(gpio)) { | 401 | if (gpio_is_valid(gpio)) { |
393 | if (!(flags & OF_GPIO_ACTIVE_LOW)) | 402 | if (!(flags & OF_GPIO_ACTIVE_LOW)) |
394 | gpio_inv_wp = true; | 403 | gpio_inv_wp = true; |
395 | 404 | ||
396 | ret = mmc_gpio_request_ro(host, gpio); | 405 | ret = mmc_gpio_request_ro(host, gpio); |
397 | if (ret < 0) | 406 | if (ret < 0) { |
398 | dev_err(host->parent, | 407 | dev_err(host->parent, |
399 | "Failed to request WP GPIO: %d!\n", ret); | 408 | "Failed to request WP GPIO: %d!\n", ret); |
409 | goto out; | ||
410 | } else { | ||
411 | dev_info(host->parent, "Got WP GPIO #%d.\n", | ||
412 | gpio); | ||
413 | } | ||
400 | } | 414 | } |
401 | if (explicit_inv_wp ^ gpio_inv_wp) | 415 | if (explicit_inv_wp ^ gpio_inv_wp) |
402 | host->caps2 |= MMC_CAP2_RO_ACTIVE_HIGH; | 416 | host->caps2 |= MMC_CAP2_RO_ACTIVE_HIGH; |
@@ -409,10 +423,18 @@ void mmc_of_parse(struct mmc_host *host) | |||
409 | host->caps |= MMC_CAP_POWER_OFF_CARD; | 423 | host->caps |= MMC_CAP_POWER_OFF_CARD; |
410 | if (of_find_property(np, "cap-sdio-irq", &len)) | 424 | if (of_find_property(np, "cap-sdio-irq", &len)) |
411 | host->caps |= MMC_CAP_SDIO_IRQ; | 425 | host->caps |= MMC_CAP_SDIO_IRQ; |
426 | if (of_find_property(np, "full-pwr-cycle", &len)) | ||
427 | host->caps2 |= MMC_CAP2_FULL_PWR_CYCLE; | ||
412 | if (of_find_property(np, "keep-power-in-suspend", &len)) | 428 | if (of_find_property(np, "keep-power-in-suspend", &len)) |
413 | host->pm_caps |= MMC_PM_KEEP_POWER; | 429 | host->pm_caps |= MMC_PM_KEEP_POWER; |
414 | if (of_find_property(np, "enable-sdio-wakeup", &len)) | 430 | if (of_find_property(np, "enable-sdio-wakeup", &len)) |
415 | host->pm_caps |= MMC_PM_WAKE_SDIO_IRQ; | 431 | host->pm_caps |= MMC_PM_WAKE_SDIO_IRQ; |
432 | |||
433 | return 0; | ||
434 | |||
435 | out: | ||
436 | mmc_gpio_free_cd(host); | ||
437 | return ret; | ||
416 | } | 438 | } |
417 | 439 | ||
418 | EXPORT_SYMBOL(mmc_of_parse); | 440 | EXPORT_SYMBOL(mmc_of_parse); |
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 0cbd1effe960..6d02012a1d0b 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c | |||
@@ -293,7 +293,7 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) | |||
293 | } | 293 | } |
294 | 294 | ||
295 | card->ext_csd.rev = ext_csd[EXT_CSD_REV]; | 295 | card->ext_csd.rev = ext_csd[EXT_CSD_REV]; |
296 | if (card->ext_csd.rev > 6) { | 296 | if (card->ext_csd.rev > 7) { |
297 | pr_err("%s: unrecognised EXT_CSD revision %d\n", | 297 | pr_err("%s: unrecognised EXT_CSD revision %d\n", |
298 | mmc_hostname(card->host), card->ext_csd.rev); | 298 | mmc_hostname(card->host), card->ext_csd.rev); |
299 | err = -EINVAL; | 299 | err = -EINVAL; |
@@ -461,9 +461,31 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) | |||
461 | */ | 461 | */ |
462 | card->ext_csd.boot_ro_lock = ext_csd[EXT_CSD_BOOT_WP]; | 462 | card->ext_csd.boot_ro_lock = ext_csd[EXT_CSD_BOOT_WP]; |
463 | card->ext_csd.boot_ro_lockable = true; | 463 | card->ext_csd.boot_ro_lockable = true; |
464 | |||
465 | /* Save power class values */ | ||
466 | card->ext_csd.raw_pwr_cl_52_195 = | ||
467 | ext_csd[EXT_CSD_PWR_CL_52_195]; | ||
468 | card->ext_csd.raw_pwr_cl_26_195 = | ||
469 | ext_csd[EXT_CSD_PWR_CL_26_195]; | ||
470 | card->ext_csd.raw_pwr_cl_52_360 = | ||
471 | ext_csd[EXT_CSD_PWR_CL_52_360]; | ||
472 | card->ext_csd.raw_pwr_cl_26_360 = | ||
473 | ext_csd[EXT_CSD_PWR_CL_26_360]; | ||
474 | card->ext_csd.raw_pwr_cl_200_195 = | ||
475 | ext_csd[EXT_CSD_PWR_CL_200_195]; | ||
476 | card->ext_csd.raw_pwr_cl_200_360 = | ||
477 | ext_csd[EXT_CSD_PWR_CL_200_360]; | ||
478 | card->ext_csd.raw_pwr_cl_ddr_52_195 = | ||
479 | ext_csd[EXT_CSD_PWR_CL_DDR_52_195]; | ||
480 | card->ext_csd.raw_pwr_cl_ddr_52_360 = | ||
481 | ext_csd[EXT_CSD_PWR_CL_DDR_52_360]; | ||
464 | } | 482 | } |
465 | 483 | ||
466 | if (card->ext_csd.rev >= 5) { | 484 | if (card->ext_csd.rev >= 5) { |
485 | /* Adjust production date as per JEDEC JESD84-B451 */ | ||
486 | if (card->cid.year < 2010) | ||
487 | card->cid.year += 16; | ||
488 | |||
467 | /* check whether the eMMC card supports BKOPS */ | 489 | /* check whether the eMMC card supports BKOPS */ |
468 | if (ext_csd[EXT_CSD_BKOPS_SUPPORT] & 0x1) { | 490 | if (ext_csd[EXT_CSD_BKOPS_SUPPORT] & 0x1) { |
469 | card->ext_csd.bkops = 1; | 491 | card->ext_csd.bkops = 1; |
@@ -607,7 +629,23 @@ static int mmc_compare_ext_csds(struct mmc_card *card, unsigned bus_width) | |||
607 | (card->ext_csd.raw_sectors[2] == | 629 | (card->ext_csd.raw_sectors[2] == |
608 | bw_ext_csd[EXT_CSD_SEC_CNT + 2]) && | 630 | bw_ext_csd[EXT_CSD_SEC_CNT + 2]) && |
609 | (card->ext_csd.raw_sectors[3] == | 631 | (card->ext_csd.raw_sectors[3] == |
610 | bw_ext_csd[EXT_CSD_SEC_CNT + 3])); | 632 | bw_ext_csd[EXT_CSD_SEC_CNT + 3]) && |
633 | (card->ext_csd.raw_pwr_cl_52_195 == | ||
634 | bw_ext_csd[EXT_CSD_PWR_CL_52_195]) && | ||
635 | (card->ext_csd.raw_pwr_cl_26_195 == | ||
636 | bw_ext_csd[EXT_CSD_PWR_CL_26_195]) && | ||
637 | (card->ext_csd.raw_pwr_cl_52_360 == | ||
638 | bw_ext_csd[EXT_CSD_PWR_CL_52_360]) && | ||
639 | (card->ext_csd.raw_pwr_cl_26_360 == | ||
640 | bw_ext_csd[EXT_CSD_PWR_CL_26_360]) && | ||
641 | (card->ext_csd.raw_pwr_cl_200_195 == | ||
642 | bw_ext_csd[EXT_CSD_PWR_CL_200_195]) && | ||
643 | (card->ext_csd.raw_pwr_cl_200_360 == | ||
644 | bw_ext_csd[EXT_CSD_PWR_CL_200_360]) && | ||
645 | (card->ext_csd.raw_pwr_cl_ddr_52_195 == | ||
646 | bw_ext_csd[EXT_CSD_PWR_CL_DDR_52_195]) && | ||
647 | (card->ext_csd.raw_pwr_cl_ddr_52_360 == | ||
648 | bw_ext_csd[EXT_CSD_PWR_CL_DDR_52_360])); | ||
611 | if (err) | 649 | if (err) |
612 | err = -EINVAL; | 650 | err = -EINVAL; |
613 | 651 | ||
@@ -676,11 +714,10 @@ static struct device_type mmc_type = { | |||
676 | * mmc_switch command. | 714 | * mmc_switch command. |
677 | */ | 715 | */ |
678 | static int mmc_select_powerclass(struct mmc_card *card, | 716 | static int mmc_select_powerclass(struct mmc_card *card, |
679 | unsigned int bus_width, u8 *ext_csd) | 717 | unsigned int bus_width) |
680 | { | 718 | { |
681 | int err = 0; | 719 | int err = 0; |
682 | unsigned int pwrclass_val; | 720 | unsigned int pwrclass_val = 0; |
683 | unsigned int index = 0; | ||
684 | struct mmc_host *host; | 721 | struct mmc_host *host; |
685 | 722 | ||
686 | BUG_ON(!card); | 723 | BUG_ON(!card); |
@@ -688,9 +725,6 @@ static int mmc_select_powerclass(struct mmc_card *card, | |||
688 | host = card->host; | 725 | host = card->host; |
689 | BUG_ON(!host); | 726 | BUG_ON(!host); |
690 | 727 | ||
691 | if (ext_csd == NULL) | ||
692 | return 0; | ||
693 | |||
694 | /* Power class selection is supported for versions >= 4.0 */ | 728 | /* Power class selection is supported for versions >= 4.0 */ |
695 | if (card->csd.mmca_vsn < CSD_SPEC_VER_4) | 729 | if (card->csd.mmca_vsn < CSD_SPEC_VER_4) |
696 | return 0; | 730 | return 0; |
@@ -702,13 +736,13 @@ static int mmc_select_powerclass(struct mmc_card *card, | |||
702 | switch (1 << host->ios.vdd) { | 736 | switch (1 << host->ios.vdd) { |
703 | case MMC_VDD_165_195: | 737 | case MMC_VDD_165_195: |
704 | if (host->ios.clock <= 26000000) | 738 | if (host->ios.clock <= 26000000) |
705 | index = EXT_CSD_PWR_CL_26_195; | 739 | pwrclass_val = card->ext_csd.raw_pwr_cl_26_195; |
706 | else if (host->ios.clock <= 52000000) | 740 | else if (host->ios.clock <= 52000000) |
707 | index = (bus_width <= EXT_CSD_BUS_WIDTH_8) ? | 741 | pwrclass_val = (bus_width <= EXT_CSD_BUS_WIDTH_8) ? |
708 | EXT_CSD_PWR_CL_52_195 : | 742 | card->ext_csd.raw_pwr_cl_52_195 : |
709 | EXT_CSD_PWR_CL_DDR_52_195; | 743 | card->ext_csd.raw_pwr_cl_ddr_52_195; |
710 | else if (host->ios.clock <= 200000000) | 744 | else if (host->ios.clock <= 200000000) |
711 | index = EXT_CSD_PWR_CL_200_195; | 745 | pwrclass_val = card->ext_csd.raw_pwr_cl_200_195; |
712 | break; | 746 | break; |
713 | case MMC_VDD_27_28: | 747 | case MMC_VDD_27_28: |
714 | case MMC_VDD_28_29: | 748 | case MMC_VDD_28_29: |
@@ -720,13 +754,13 @@ static int mmc_select_powerclass(struct mmc_card *card, | |||
720 | case MMC_VDD_34_35: | 754 | case MMC_VDD_34_35: |
721 | case MMC_VDD_35_36: | 755 | case MMC_VDD_35_36: |
722 | if (host->ios.clock <= 26000000) | 756 | if (host->ios.clock <= 26000000) |
723 | index = EXT_CSD_PWR_CL_26_360; | 757 | pwrclass_val = card->ext_csd.raw_pwr_cl_26_360; |
724 | else if (host->ios.clock <= 52000000) | 758 | else if (host->ios.clock <= 52000000) |
725 | index = (bus_width <= EXT_CSD_BUS_WIDTH_8) ? | 759 | pwrclass_val = (bus_width <= EXT_CSD_BUS_WIDTH_8) ? |
726 | EXT_CSD_PWR_CL_52_360 : | 760 | card->ext_csd.raw_pwr_cl_52_360 : |
727 | EXT_CSD_PWR_CL_DDR_52_360; | 761 | card->ext_csd.raw_pwr_cl_ddr_52_360; |
728 | else if (host->ios.clock <= 200000000) | 762 | else if (host->ios.clock <= 200000000) |
729 | index = EXT_CSD_PWR_CL_200_360; | 763 | pwrclass_val = card->ext_csd.raw_pwr_cl_200_360; |
730 | break; | 764 | break; |
731 | default: | 765 | default: |
732 | pr_warning("%s: Voltage range not supported " | 766 | pr_warning("%s: Voltage range not supported " |
@@ -734,8 +768,6 @@ static int mmc_select_powerclass(struct mmc_card *card, | |||
734 | return -EINVAL; | 768 | return -EINVAL; |
735 | } | 769 | } |
736 | 770 | ||
737 | pwrclass_val = ext_csd[index]; | ||
738 | |||
739 | if (bus_width & (EXT_CSD_BUS_WIDTH_8 | EXT_CSD_DDR_BUS_WIDTH_8)) | 771 | if (bus_width & (EXT_CSD_BUS_WIDTH_8 | EXT_CSD_DDR_BUS_WIDTH_8)) |
740 | pwrclass_val = (pwrclass_val & EXT_CSD_PWR_CL_8BIT_MASK) >> | 772 | pwrclass_val = (pwrclass_val & EXT_CSD_PWR_CL_8BIT_MASK) >> |
741 | EXT_CSD_PWR_CL_8BIT_SHIFT; | 773 | EXT_CSD_PWR_CL_8BIT_SHIFT; |
@@ -1013,11 +1045,9 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, | |||
1013 | } | 1045 | } |
1014 | 1046 | ||
1015 | /* | 1047 | /* |
1016 | * If the host supports the power_off_notify capability then | 1048 | * Enable power_off_notification byte in the ext_csd register |
1017 | * set the notification byte in the ext_csd register of device | ||
1018 | */ | 1049 | */ |
1019 | if ((host->caps2 & MMC_CAP2_POWEROFF_NOTIFY) && | 1050 | if (card->ext_csd.rev >= 6) { |
1020 | (card->ext_csd.rev >= 6)) { | ||
1021 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, | 1051 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, |
1022 | EXT_CSD_POWER_OFF_NOTIFICATION, | 1052 | EXT_CSD_POWER_OFF_NOTIFICATION, |
1023 | EXT_CSD_POWER_ON, | 1053 | EXT_CSD_POWER_ON, |
@@ -1131,7 +1161,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, | |||
1131 | 1161 | ||
1132 | ext_csd_bits = (bus_width == MMC_BUS_WIDTH_8) ? | 1162 | ext_csd_bits = (bus_width == MMC_BUS_WIDTH_8) ? |
1133 | EXT_CSD_BUS_WIDTH_8 : EXT_CSD_BUS_WIDTH_4; | 1163 | EXT_CSD_BUS_WIDTH_8 : EXT_CSD_BUS_WIDTH_4; |
1134 | err = mmc_select_powerclass(card, ext_csd_bits, ext_csd); | 1164 | err = mmc_select_powerclass(card, ext_csd_bits); |
1135 | if (err) | 1165 | if (err) |
1136 | pr_warning("%s: power class selection to bus width %d" | 1166 | pr_warning("%s: power class selection to bus width %d" |
1137 | " failed\n", mmc_hostname(card->host), | 1167 | " failed\n", mmc_hostname(card->host), |
@@ -1164,8 +1194,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, | |||
1164 | bus_width = bus_widths[idx]; | 1194 | bus_width = bus_widths[idx]; |
1165 | if (bus_width == MMC_BUS_WIDTH_1) | 1195 | if (bus_width == MMC_BUS_WIDTH_1) |
1166 | ddr = 0; /* no DDR for 1-bit width */ | 1196 | ddr = 0; /* no DDR for 1-bit width */ |
1167 | err = mmc_select_powerclass(card, ext_csd_bits[idx][0], | 1197 | err = mmc_select_powerclass(card, ext_csd_bits[idx][0]); |
1168 | ext_csd); | ||
1169 | if (err) | 1198 | if (err) |
1170 | pr_warning("%s: power class selection to " | 1199 | pr_warning("%s: power class selection to " |
1171 | "bus width %d failed\n", | 1200 | "bus width %d failed\n", |
@@ -1195,8 +1224,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, | |||
1195 | } | 1224 | } |
1196 | 1225 | ||
1197 | if (!err && ddr) { | 1226 | if (!err && ddr) { |
1198 | err = mmc_select_powerclass(card, ext_csd_bits[idx][1], | 1227 | err = mmc_select_powerclass(card, ext_csd_bits[idx][1]); |
1199 | ext_csd); | ||
1200 | if (err) | 1228 | if (err) |
1201 | pr_warning("%s: power class selection to " | 1229 | pr_warning("%s: power class selection to " |
1202 | "bus width %d ddr %d failed\n", | 1230 | "bus width %d ddr %d failed\n", |
@@ -1321,6 +1349,45 @@ err: | |||
1321 | return err; | 1349 | return err; |
1322 | } | 1350 | } |
1323 | 1351 | ||
1352 | static int mmc_can_sleep(struct mmc_card *card) | ||
1353 | { | ||
1354 | return (card && card->ext_csd.rev >= 3); | ||
1355 | } | ||
1356 | |||
1357 | static int mmc_sleep(struct mmc_host *host) | ||
1358 | { | ||
1359 | struct mmc_command cmd = {0}; | ||
1360 | struct mmc_card *card = host->card; | ||
1361 | int err; | ||
1362 | |||
1363 | if (host->caps2 & MMC_CAP2_NO_SLEEP_CMD) | ||
1364 | return 0; | ||
1365 | |||
1366 | err = mmc_deselect_cards(host); | ||
1367 | if (err) | ||
1368 | return err; | ||
1369 | |||
1370 | cmd.opcode = MMC_SLEEP_AWAKE; | ||
1371 | cmd.arg = card->rca << 16; | ||
1372 | cmd.arg |= 1 << 15; | ||
1373 | |||
1374 | cmd.flags = MMC_RSP_R1B | MMC_CMD_AC; | ||
1375 | err = mmc_wait_for_cmd(host, &cmd, 0); | ||
1376 | if (err) | ||
1377 | return err; | ||
1378 | |||
1379 | /* | ||
1380 | * If the host does not wait while the card signals busy, then we will | ||
1381 | * will have to wait the sleep/awake timeout. Note, we cannot use the | ||
1382 | * SEND_STATUS command to poll the status because that command (and most | ||
1383 | * others) is invalid while the card sleeps. | ||
1384 | */ | ||
1385 | if (!(host->caps & MMC_CAP_WAIT_WHILE_BUSY)) | ||
1386 | mmc_delay(DIV_ROUND_UP(card->ext_csd.sa_timeout, 10000)); | ||
1387 | |||
1388 | return err; | ||
1389 | } | ||
1390 | |||
1324 | static int mmc_can_poweroff_notify(const struct mmc_card *card) | 1391 | static int mmc_can_poweroff_notify(const struct mmc_card *card) |
1325 | { | 1392 | { |
1326 | return card && | 1393 | return card && |
@@ -1380,14 +1447,14 @@ static void mmc_detect(struct mmc_host *host) | |||
1380 | BUG_ON(!host); | 1447 | BUG_ON(!host); |
1381 | BUG_ON(!host->card); | 1448 | BUG_ON(!host->card); |
1382 | 1449 | ||
1383 | mmc_claim_host(host); | 1450 | mmc_get_card(host->card); |
1384 | 1451 | ||
1385 | /* | 1452 | /* |
1386 | * Just check if our card has been removed. | 1453 | * Just check if our card has been removed. |
1387 | */ | 1454 | */ |
1388 | err = _mmc_detect_card_removed(host); | 1455 | err = _mmc_detect_card_removed(host); |
1389 | 1456 | ||
1390 | mmc_release_host(host); | 1457 | mmc_put_card(host->card); |
1391 | 1458 | ||
1392 | if (err) { | 1459 | if (err) { |
1393 | mmc_remove(host); | 1460 | mmc_remove(host); |
@@ -1399,36 +1466,60 @@ static void mmc_detect(struct mmc_host *host) | |||
1399 | } | 1466 | } |
1400 | } | 1467 | } |
1401 | 1468 | ||
1402 | /* | 1469 | static int _mmc_suspend(struct mmc_host *host, bool is_suspend) |
1403 | * Suspend callback from host. | ||
1404 | */ | ||
1405 | static int mmc_suspend(struct mmc_host *host) | ||
1406 | { | 1470 | { |
1407 | int err = 0; | 1471 | int err = 0; |
1472 | unsigned int notify_type = is_suspend ? EXT_CSD_POWER_OFF_SHORT : | ||
1473 | EXT_CSD_POWER_OFF_LONG; | ||
1408 | 1474 | ||
1409 | BUG_ON(!host); | 1475 | BUG_ON(!host); |
1410 | BUG_ON(!host->card); | 1476 | BUG_ON(!host->card); |
1411 | 1477 | ||
1412 | mmc_claim_host(host); | 1478 | mmc_claim_host(host); |
1413 | 1479 | ||
1480 | if (mmc_card_doing_bkops(host->card)) { | ||
1481 | err = mmc_stop_bkops(host->card); | ||
1482 | if (err) | ||
1483 | goto out; | ||
1484 | } | ||
1485 | |||
1414 | err = mmc_cache_ctrl(host, 0); | 1486 | err = mmc_cache_ctrl(host, 0); |
1415 | if (err) | 1487 | if (err) |
1416 | goto out; | 1488 | goto out; |
1417 | 1489 | ||
1418 | if (mmc_can_poweroff_notify(host->card)) | 1490 | if (mmc_can_poweroff_notify(host->card) && |
1419 | err = mmc_poweroff_notify(host->card, EXT_CSD_POWER_OFF_SHORT); | 1491 | ((host->caps2 & MMC_CAP2_FULL_PWR_CYCLE) || !is_suspend)) |
1420 | else if (mmc_card_can_sleep(host)) | 1492 | err = mmc_poweroff_notify(host->card, notify_type); |
1421 | err = mmc_card_sleep(host); | 1493 | else if (mmc_can_sleep(host->card)) |
1494 | err = mmc_sleep(host); | ||
1422 | else if (!mmc_host_is_spi(host)) | 1495 | else if (!mmc_host_is_spi(host)) |
1423 | err = mmc_deselect_cards(host); | 1496 | err = mmc_deselect_cards(host); |
1424 | host->card->state &= ~(MMC_STATE_HIGHSPEED | MMC_STATE_HIGHSPEED_200); | 1497 | host->card->state &= ~(MMC_STATE_HIGHSPEED | MMC_STATE_HIGHSPEED_200); |
1425 | 1498 | ||
1499 | if (!err) | ||
1500 | mmc_power_off(host); | ||
1426 | out: | 1501 | out: |
1427 | mmc_release_host(host); | 1502 | mmc_release_host(host); |
1428 | return err; | 1503 | return err; |
1429 | } | 1504 | } |
1430 | 1505 | ||
1431 | /* | 1506 | /* |
1507 | * Suspend callback from host. | ||
1508 | */ | ||
1509 | static int mmc_suspend(struct mmc_host *host) | ||
1510 | { | ||
1511 | return _mmc_suspend(host, true); | ||
1512 | } | ||
1513 | |||
1514 | /* | ||
1515 | * Shutdown callback | ||
1516 | */ | ||
1517 | static int mmc_shutdown(struct mmc_host *host) | ||
1518 | { | ||
1519 | return _mmc_suspend(host, false); | ||
1520 | } | ||
1521 | |||
1522 | /* | ||
1432 | * Resume callback from host. | 1523 | * Resume callback from host. |
1433 | * | 1524 | * |
1434 | * This function tries to determine if the same card is still present | 1525 | * This function tries to determine if the same card is still present |
@@ -1442,74 +1533,94 @@ static int mmc_resume(struct mmc_host *host) | |||
1442 | BUG_ON(!host->card); | 1533 | BUG_ON(!host->card); |
1443 | 1534 | ||
1444 | mmc_claim_host(host); | 1535 | mmc_claim_host(host); |
1536 | mmc_power_up(host); | ||
1537 | mmc_select_voltage(host, host->ocr); | ||
1445 | err = mmc_init_card(host, host->ocr, host->card); | 1538 | err = mmc_init_card(host, host->ocr, host->card); |
1446 | mmc_release_host(host); | 1539 | mmc_release_host(host); |
1447 | 1540 | ||
1448 | return err; | 1541 | return err; |
1449 | } | 1542 | } |
1450 | 1543 | ||
1451 | static int mmc_power_restore(struct mmc_host *host) | 1544 | |
1545 | /* | ||
1546 | * Callback for runtime_suspend. | ||
1547 | */ | ||
1548 | static int mmc_runtime_suspend(struct mmc_host *host) | ||
1452 | { | 1549 | { |
1453 | int ret; | 1550 | int err; |
1551 | |||
1552 | if (!(host->caps & MMC_CAP_AGGRESSIVE_PM)) | ||
1553 | return 0; | ||
1454 | 1554 | ||
1455 | host->card->state &= ~(MMC_STATE_HIGHSPEED | MMC_STATE_HIGHSPEED_200); | ||
1456 | mmc_claim_host(host); | 1555 | mmc_claim_host(host); |
1457 | ret = mmc_init_card(host, host->ocr, host->card); | ||
1458 | mmc_release_host(host); | ||
1459 | 1556 | ||
1460 | return ret; | 1557 | err = mmc_suspend(host); |
1558 | if (err) { | ||
1559 | pr_err("%s: error %d doing aggessive suspend\n", | ||
1560 | mmc_hostname(host), err); | ||
1561 | goto out; | ||
1562 | } | ||
1563 | mmc_power_off(host); | ||
1564 | |||
1565 | out: | ||
1566 | mmc_release_host(host); | ||
1567 | return err; | ||
1461 | } | 1568 | } |
1462 | 1569 | ||
1463 | static int mmc_sleep(struct mmc_host *host) | 1570 | /* |
1571 | * Callback for runtime_resume. | ||
1572 | */ | ||
1573 | static int mmc_runtime_resume(struct mmc_host *host) | ||
1464 | { | 1574 | { |
1465 | struct mmc_card *card = host->card; | 1575 | int err; |
1466 | int err = -ENOSYS; | ||
1467 | 1576 | ||
1468 | if (card && card->ext_csd.rev >= 3) { | 1577 | if (!(host->caps & MMC_CAP_AGGRESSIVE_PM)) |
1469 | err = mmc_card_sleepawake(host, 1); | 1578 | return 0; |
1470 | if (err < 0) | ||
1471 | pr_debug("%s: Error %d while putting card into sleep", | ||
1472 | mmc_hostname(host), err); | ||
1473 | } | ||
1474 | 1579 | ||
1475 | return err; | 1580 | mmc_claim_host(host); |
1581 | |||
1582 | mmc_power_up(host); | ||
1583 | err = mmc_resume(host); | ||
1584 | if (err) | ||
1585 | pr_err("%s: error %d doing aggessive resume\n", | ||
1586 | mmc_hostname(host), err); | ||
1587 | |||
1588 | mmc_release_host(host); | ||
1589 | return 0; | ||
1476 | } | 1590 | } |
1477 | 1591 | ||
1478 | static int mmc_awake(struct mmc_host *host) | 1592 | static int mmc_power_restore(struct mmc_host *host) |
1479 | { | 1593 | { |
1480 | struct mmc_card *card = host->card; | 1594 | int ret; |
1481 | int err = -ENOSYS; | ||
1482 | 1595 | ||
1483 | if (card && card->ext_csd.rev >= 3) { | 1596 | host->card->state &= ~(MMC_STATE_HIGHSPEED | MMC_STATE_HIGHSPEED_200); |
1484 | err = mmc_card_sleepawake(host, 0); | 1597 | mmc_claim_host(host); |
1485 | if (err < 0) | 1598 | ret = mmc_init_card(host, host->ocr, host->card); |
1486 | pr_debug("%s: Error %d while awaking sleeping card", | 1599 | mmc_release_host(host); |
1487 | mmc_hostname(host), err); | ||
1488 | } | ||
1489 | 1600 | ||
1490 | return err; | 1601 | return ret; |
1491 | } | 1602 | } |
1492 | 1603 | ||
1493 | static const struct mmc_bus_ops mmc_ops = { | 1604 | static const struct mmc_bus_ops mmc_ops = { |
1494 | .awake = mmc_awake, | ||
1495 | .sleep = mmc_sleep, | ||
1496 | .remove = mmc_remove, | 1605 | .remove = mmc_remove, |
1497 | .detect = mmc_detect, | 1606 | .detect = mmc_detect, |
1498 | .suspend = NULL, | 1607 | .suspend = NULL, |
1499 | .resume = NULL, | 1608 | .resume = NULL, |
1500 | .power_restore = mmc_power_restore, | 1609 | .power_restore = mmc_power_restore, |
1501 | .alive = mmc_alive, | 1610 | .alive = mmc_alive, |
1611 | .shutdown = mmc_shutdown, | ||
1502 | }; | 1612 | }; |
1503 | 1613 | ||
1504 | static const struct mmc_bus_ops mmc_ops_unsafe = { | 1614 | static const struct mmc_bus_ops mmc_ops_unsafe = { |
1505 | .awake = mmc_awake, | ||
1506 | .sleep = mmc_sleep, | ||
1507 | .remove = mmc_remove, | 1615 | .remove = mmc_remove, |
1508 | .detect = mmc_detect, | 1616 | .detect = mmc_detect, |
1509 | .suspend = mmc_suspend, | 1617 | .suspend = mmc_suspend, |
1510 | .resume = mmc_resume, | 1618 | .resume = mmc_resume, |
1619 | .runtime_suspend = mmc_runtime_suspend, | ||
1620 | .runtime_resume = mmc_runtime_resume, | ||
1511 | .power_restore = mmc_power_restore, | 1621 | .power_restore = mmc_power_restore, |
1512 | .alive = mmc_alive, | 1622 | .alive = mmc_alive, |
1623 | .shutdown = mmc_shutdown, | ||
1513 | }; | 1624 | }; |
1514 | 1625 | ||
1515 | static void mmc_attach_bus_ops(struct mmc_host *host) | 1626 | static void mmc_attach_bus_ops(struct mmc_host *host) |
diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c index 49f04bc9d0eb..837fc7386e23 100644 --- a/drivers/mmc/core/mmc_ops.c +++ b/drivers/mmc/core/mmc_ops.c | |||
@@ -59,40 +59,6 @@ int mmc_deselect_cards(struct mmc_host *host) | |||
59 | return _mmc_select_card(host, NULL); | 59 | return _mmc_select_card(host, NULL); |
60 | } | 60 | } |
61 | 61 | ||
62 | int mmc_card_sleepawake(struct mmc_host *host, int sleep) | ||
63 | { | ||
64 | struct mmc_command cmd = {0}; | ||
65 | struct mmc_card *card = host->card; | ||
66 | int err; | ||
67 | |||
68 | if (sleep) | ||
69 | mmc_deselect_cards(host); | ||
70 | |||
71 | cmd.opcode = MMC_SLEEP_AWAKE; | ||
72 | cmd.arg = card->rca << 16; | ||
73 | if (sleep) | ||
74 | cmd.arg |= 1 << 15; | ||
75 | |||
76 | cmd.flags = MMC_RSP_R1B | MMC_CMD_AC; | ||
77 | err = mmc_wait_for_cmd(host, &cmd, 0); | ||
78 | if (err) | ||
79 | return err; | ||
80 | |||
81 | /* | ||
82 | * If the host does not wait while the card signals busy, then we will | ||
83 | * will have to wait the sleep/awake timeout. Note, we cannot use the | ||
84 | * SEND_STATUS command to poll the status because that command (and most | ||
85 | * others) is invalid while the card sleeps. | ||
86 | */ | ||
87 | if (!(host->caps & MMC_CAP_WAIT_WHILE_BUSY)) | ||
88 | mmc_delay(DIV_ROUND_UP(card->ext_csd.sa_timeout, 10000)); | ||
89 | |||
90 | if (!sleep) | ||
91 | err = mmc_select_card(card); | ||
92 | |||
93 | return err; | ||
94 | } | ||
95 | |||
96 | int mmc_go_idle(struct mmc_host *host) | 62 | int mmc_go_idle(struct mmc_host *host) |
97 | { | 63 | { |
98 | int err; | 64 | int err; |
@@ -431,6 +397,8 @@ int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value, | |||
431 | 397 | ||
432 | 398 | ||
433 | cmd.cmd_timeout_ms = timeout_ms; | 399 | cmd.cmd_timeout_ms = timeout_ms; |
400 | if (index == EXT_CSD_SANITIZE_START) | ||
401 | cmd.sanitize_busy = true; | ||
434 | 402 | ||
435 | err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES); | 403 | err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES); |
436 | if (err) | 404 | if (err) |
diff --git a/drivers/mmc/core/mmc_ops.h b/drivers/mmc/core/mmc_ops.h index 3dd8941c2980..80ae9f4e0293 100644 --- a/drivers/mmc/core/mmc_ops.h +++ b/drivers/mmc/core/mmc_ops.h | |||
@@ -24,7 +24,6 @@ int mmc_send_status(struct mmc_card *card, u32 *status); | |||
24 | int mmc_send_cid(struct mmc_host *host, u32 *cid); | 24 | int mmc_send_cid(struct mmc_host *host, u32 *cid); |
25 | int mmc_spi_read_ocr(struct mmc_host *host, int highcap, u32 *ocrp); | 25 | int mmc_spi_read_ocr(struct mmc_host *host, int highcap, u32 *ocrp); |
26 | int mmc_spi_set_crc(struct mmc_host *host, int use_crc); | 26 | int mmc_spi_set_crc(struct mmc_host *host, int use_crc); |
27 | int mmc_card_sleepawake(struct mmc_host *host, int sleep); | ||
28 | int mmc_bus_test(struct mmc_card *card, u8 bus_width); | 27 | int mmc_bus_test(struct mmc_card *card, u8 bus_width); |
29 | int mmc_send_hpi_cmd(struct mmc_card *card, u32 *status); | 28 | int mmc_send_hpi_cmd(struct mmc_card *card, u32 *status); |
30 | 29 | ||
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index 9e645e19cec6..176d125f5b57 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c | |||
@@ -646,8 +646,13 @@ static int mmc_sd_init_uhs_card(struct mmc_card *card) | |||
646 | if (err) | 646 | if (err) |
647 | goto out; | 647 | goto out; |
648 | 648 | ||
649 | /* SPI mode doesn't define CMD19 */ | 649 | /* |
650 | if (!mmc_host_is_spi(card->host) && card->host->ops->execute_tuning) { | 650 | * SPI mode doesn't define CMD19 and tuning is only valid for SDR50 and |
651 | * SDR104 mode SD-cards. Note that tuning is mandatory for SDR104. | ||
652 | */ | ||
653 | if (!mmc_host_is_spi(card->host) && card->host->ops->execute_tuning && | ||
654 | (card->sd_bus_speed == UHS_SDR50_BUS_SPEED || | ||
655 | card->sd_bus_speed == UHS_SDR104_BUS_SPEED)) { | ||
651 | mmc_host_clk_hold(card->host); | 656 | mmc_host_clk_hold(card->host); |
652 | err = card->host->ops->execute_tuning(card->host, | 657 | err = card->host->ops->execute_tuning(card->host, |
653 | MMC_SEND_TUNING_BLOCK); | 658 | MMC_SEND_TUNING_BLOCK); |
@@ -1037,14 +1042,14 @@ static void mmc_sd_detect(struct mmc_host *host) | |||
1037 | BUG_ON(!host); | 1042 | BUG_ON(!host); |
1038 | BUG_ON(!host->card); | 1043 | BUG_ON(!host->card); |
1039 | 1044 | ||
1040 | mmc_claim_host(host); | 1045 | mmc_get_card(host->card); |
1041 | 1046 | ||
1042 | /* | 1047 | /* |
1043 | * Just check if our card has been removed. | 1048 | * Just check if our card has been removed. |
1044 | */ | 1049 | */ |
1045 | err = _mmc_detect_card_removed(host); | 1050 | err = _mmc_detect_card_removed(host); |
1046 | 1051 | ||
1047 | mmc_release_host(host); | 1052 | mmc_put_card(host->card); |
1048 | 1053 | ||
1049 | if (err) { | 1054 | if (err) { |
1050 | mmc_sd_remove(host); | 1055 | mmc_sd_remove(host); |
@@ -1070,6 +1075,8 @@ static int mmc_sd_suspend(struct mmc_host *host) | |||
1070 | if (!mmc_host_is_spi(host)) | 1075 | if (!mmc_host_is_spi(host)) |
1071 | err = mmc_deselect_cards(host); | 1076 | err = mmc_deselect_cards(host); |
1072 | host->card->state &= ~MMC_STATE_HIGHSPEED; | 1077 | host->card->state &= ~MMC_STATE_HIGHSPEED; |
1078 | if (!err) | ||
1079 | mmc_power_off(host); | ||
1073 | mmc_release_host(host); | 1080 | mmc_release_host(host); |
1074 | 1081 | ||
1075 | return err; | 1082 | return err; |
@@ -1089,12 +1096,61 @@ static int mmc_sd_resume(struct mmc_host *host) | |||
1089 | BUG_ON(!host->card); | 1096 | BUG_ON(!host->card); |
1090 | 1097 | ||
1091 | mmc_claim_host(host); | 1098 | mmc_claim_host(host); |
1099 | mmc_power_up(host); | ||
1100 | mmc_select_voltage(host, host->ocr); | ||
1092 | err = mmc_sd_init_card(host, host->ocr, host->card); | 1101 | err = mmc_sd_init_card(host, host->ocr, host->card); |
1093 | mmc_release_host(host); | 1102 | mmc_release_host(host); |
1094 | 1103 | ||
1095 | return err; | 1104 | return err; |
1096 | } | 1105 | } |
1097 | 1106 | ||
1107 | /* | ||
1108 | * Callback for runtime_suspend. | ||
1109 | */ | ||
1110 | static int mmc_sd_runtime_suspend(struct mmc_host *host) | ||
1111 | { | ||
1112 | int err; | ||
1113 | |||
1114 | if (!(host->caps & MMC_CAP_AGGRESSIVE_PM)) | ||
1115 | return 0; | ||
1116 | |||
1117 | mmc_claim_host(host); | ||
1118 | |||
1119 | err = mmc_sd_suspend(host); | ||
1120 | if (err) { | ||
1121 | pr_err("%s: error %d doing aggessive suspend\n", | ||
1122 | mmc_hostname(host), err); | ||
1123 | goto out; | ||
1124 | } | ||
1125 | mmc_power_off(host); | ||
1126 | |||
1127 | out: | ||
1128 | mmc_release_host(host); | ||
1129 | return err; | ||
1130 | } | ||
1131 | |||
1132 | /* | ||
1133 | * Callback for runtime_resume. | ||
1134 | */ | ||
1135 | static int mmc_sd_runtime_resume(struct mmc_host *host) | ||
1136 | { | ||
1137 | int err; | ||
1138 | |||
1139 | if (!(host->caps & MMC_CAP_AGGRESSIVE_PM)) | ||
1140 | return 0; | ||
1141 | |||
1142 | mmc_claim_host(host); | ||
1143 | |||
1144 | mmc_power_up(host); | ||
1145 | err = mmc_sd_resume(host); | ||
1146 | if (err) | ||
1147 | pr_err("%s: error %d doing aggessive resume\n", | ||
1148 | mmc_hostname(host), err); | ||
1149 | |||
1150 | mmc_release_host(host); | ||
1151 | return 0; | ||
1152 | } | ||
1153 | |||
1098 | static int mmc_sd_power_restore(struct mmc_host *host) | 1154 | static int mmc_sd_power_restore(struct mmc_host *host) |
1099 | { | 1155 | { |
1100 | int ret; | 1156 | int ret; |
@@ -1114,15 +1170,19 @@ static const struct mmc_bus_ops mmc_sd_ops = { | |||
1114 | .resume = NULL, | 1170 | .resume = NULL, |
1115 | .power_restore = mmc_sd_power_restore, | 1171 | .power_restore = mmc_sd_power_restore, |
1116 | .alive = mmc_sd_alive, | 1172 | .alive = mmc_sd_alive, |
1173 | .shutdown = mmc_sd_suspend, | ||
1117 | }; | 1174 | }; |
1118 | 1175 | ||
1119 | static const struct mmc_bus_ops mmc_sd_ops_unsafe = { | 1176 | static const struct mmc_bus_ops mmc_sd_ops_unsafe = { |
1120 | .remove = mmc_sd_remove, | 1177 | .remove = mmc_sd_remove, |
1121 | .detect = mmc_sd_detect, | 1178 | .detect = mmc_sd_detect, |
1179 | .runtime_suspend = mmc_sd_runtime_suspend, | ||
1180 | .runtime_resume = mmc_sd_runtime_resume, | ||
1122 | .suspend = mmc_sd_suspend, | 1181 | .suspend = mmc_sd_suspend, |
1123 | .resume = mmc_sd_resume, | 1182 | .resume = mmc_sd_resume, |
1124 | .power_restore = mmc_sd_power_restore, | 1183 | .power_restore = mmc_sd_power_restore, |
1125 | .alive = mmc_sd_alive, | 1184 | .alive = mmc_sd_alive, |
1185 | .shutdown = mmc_sd_suspend, | ||
1126 | }; | 1186 | }; |
1127 | 1187 | ||
1128 | static void mmc_sd_attach_bus_ops(struct mmc_host *host) | 1188 | static void mmc_sd_attach_bus_ops(struct mmc_host *host) |
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index 6889a821c1da..80d89cff7306 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c | |||
@@ -563,10 +563,18 @@ static int mmc_sdio_init_uhs_card(struct mmc_card *card) | |||
563 | if (err) | 563 | if (err) |
564 | goto out; | 564 | goto out; |
565 | 565 | ||
566 | /* Initialize and start re-tuning timer */ | 566 | /* |
567 | if (!mmc_host_is_spi(card->host) && card->host->ops->execute_tuning) | 567 | * SPI mode doesn't define CMD19 and tuning is only valid for SDR50 and |
568 | * SDR104 mode SD-cards. Note that tuning is mandatory for SDR104. | ||
569 | */ | ||
570 | if (!mmc_host_is_spi(card->host) && card->host->ops->execute_tuning && | ||
571 | ((card->sw_caps.sd3_bus_mode & SD_MODE_UHS_SDR50) || | ||
572 | (card->sw_caps.sd3_bus_mode & SD_MODE_UHS_SDR104))) { | ||
573 | mmc_host_clk_hold(card->host); | ||
568 | err = card->host->ops->execute_tuning(card->host, | 574 | err = card->host->ops->execute_tuning(card->host, |
569 | MMC_SEND_TUNING_BLOCK); | 575 | MMC_SEND_TUNING_BLOCK); |
576 | mmc_host_clk_release(card->host); | ||
577 | } | ||
570 | 578 | ||
571 | out: | 579 | out: |
572 | 580 | ||
@@ -902,11 +910,11 @@ out: | |||
902 | } | 910 | } |
903 | 911 | ||
904 | /* | 912 | /* |
905 | * SDIO suspend. We need to suspend all functions separately. | 913 | * SDIO pre_suspend. We need to suspend all functions separately. |
906 | * Therefore all registered functions must have drivers with suspend | 914 | * Therefore all registered functions must have drivers with suspend |
907 | * and resume methods. Failing that we simply remove the whole card. | 915 | * and resume methods. Failing that we simply remove the whole card. |
908 | */ | 916 | */ |
909 | static int mmc_sdio_suspend(struct mmc_host *host) | 917 | static int mmc_sdio_pre_suspend(struct mmc_host *host) |
910 | { | 918 | { |
911 | int i, err = 0; | 919 | int i, err = 0; |
912 | 920 | ||
@@ -917,8 +925,26 @@ static int mmc_sdio_suspend(struct mmc_host *host) | |||
917 | if (!pmops || !pmops->suspend || !pmops->resume) { | 925 | if (!pmops || !pmops->suspend || !pmops->resume) { |
918 | /* force removal of entire card in that case */ | 926 | /* force removal of entire card in that case */ |
919 | err = -ENOSYS; | 927 | err = -ENOSYS; |
920 | } else | 928 | break; |
921 | err = pmops->suspend(&func->dev); | 929 | } |
930 | } | ||
931 | } | ||
932 | |||
933 | return err; | ||
934 | } | ||
935 | |||
936 | /* | ||
937 | * SDIO suspend. Suspend all functions separately. | ||
938 | */ | ||
939 | static int mmc_sdio_suspend(struct mmc_host *host) | ||
940 | { | ||
941 | int i, err = 0; | ||
942 | |||
943 | for (i = 0; i < host->card->sdio_funcs; i++) { | ||
944 | struct sdio_func *func = host->card->sdio_func[i]; | ||
945 | if (func && sdio_func_present(func) && func->dev.driver) { | ||
946 | const struct dev_pm_ops *pmops = func->dev.driver->pm; | ||
947 | err = pmops->suspend(&func->dev); | ||
922 | if (err) | 948 | if (err) |
923 | break; | 949 | break; |
924 | } | 950 | } |
@@ -937,6 +963,9 @@ static int mmc_sdio_suspend(struct mmc_host *host) | |||
937 | mmc_release_host(host); | 963 | mmc_release_host(host); |
938 | } | 964 | } |
939 | 965 | ||
966 | if (!err && !mmc_card_keep_power(host)) | ||
967 | mmc_power_off(host); | ||
968 | |||
940 | return err; | 969 | return err; |
941 | } | 970 | } |
942 | 971 | ||
@@ -950,6 +979,23 @@ static int mmc_sdio_resume(struct mmc_host *host) | |||
950 | /* Basic card reinitialization. */ | 979 | /* Basic card reinitialization. */ |
951 | mmc_claim_host(host); | 980 | mmc_claim_host(host); |
952 | 981 | ||
982 | /* Restore power if needed */ | ||
983 | if (!mmc_card_keep_power(host)) { | ||
984 | mmc_power_up(host); | ||
985 | mmc_select_voltage(host, host->ocr); | ||
986 | /* | ||
987 | * Tell runtime PM core we just powered up the card, | ||
988 | * since it still believes the card is powered off. | ||
989 | * Note that currently runtime PM is only enabled | ||
990 | * for SDIO cards that are MMC_CAP_POWER_OFF_CARD | ||
991 | */ | ||
992 | if (host->caps & MMC_CAP_POWER_OFF_CARD) { | ||
993 | pm_runtime_disable(&host->card->dev); | ||
994 | pm_runtime_set_active(&host->card->dev); | ||
995 | pm_runtime_enable(&host->card->dev); | ||
996 | } | ||
997 | } | ||
998 | |||
953 | /* No need to reinitialize powered-resumed nonremovable cards */ | 999 | /* No need to reinitialize powered-resumed nonremovable cards */ |
954 | if (mmc_card_is_removable(host) || !mmc_card_keep_power(host)) { | 1000 | if (mmc_card_is_removable(host) || !mmc_card_keep_power(host)) { |
955 | sdio_reset(host); | 1001 | sdio_reset(host); |
@@ -987,6 +1033,7 @@ static int mmc_sdio_resume(struct mmc_host *host) | |||
987 | } | 1033 | } |
988 | } | 1034 | } |
989 | 1035 | ||
1036 | host->pm_flags &= ~MMC_PM_KEEP_POWER; | ||
990 | return err; | 1037 | return err; |
991 | } | 1038 | } |
992 | 1039 | ||
@@ -1051,11 +1098,28 @@ out: | |||
1051 | return ret; | 1098 | return ret; |
1052 | } | 1099 | } |
1053 | 1100 | ||
1101 | static int mmc_sdio_runtime_suspend(struct mmc_host *host) | ||
1102 | { | ||
1103 | /* No references to the card, cut the power to it. */ | ||
1104 | mmc_power_off(host); | ||
1105 | return 0; | ||
1106 | } | ||
1107 | |||
1108 | static int mmc_sdio_runtime_resume(struct mmc_host *host) | ||
1109 | { | ||
1110 | /* Restore power and re-initialize. */ | ||
1111 | mmc_power_up(host); | ||
1112 | return mmc_sdio_power_restore(host); | ||
1113 | } | ||
1114 | |||
1054 | static const struct mmc_bus_ops mmc_sdio_ops = { | 1115 | static const struct mmc_bus_ops mmc_sdio_ops = { |
1055 | .remove = mmc_sdio_remove, | 1116 | .remove = mmc_sdio_remove, |
1056 | .detect = mmc_sdio_detect, | 1117 | .detect = mmc_sdio_detect, |
1118 | .pre_suspend = mmc_sdio_pre_suspend, | ||
1057 | .suspend = mmc_sdio_suspend, | 1119 | .suspend = mmc_sdio_suspend, |
1058 | .resume = mmc_sdio_resume, | 1120 | .resume = mmc_sdio_resume, |
1121 | .runtime_suspend = mmc_sdio_runtime_suspend, | ||
1122 | .runtime_resume = mmc_sdio_runtime_resume, | ||
1059 | .power_restore = mmc_sdio_power_restore, | 1123 | .power_restore = mmc_sdio_power_restore, |
1060 | .alive = mmc_sdio_alive, | 1124 | .alive = mmc_sdio_alive, |
1061 | }; | 1125 | }; |