aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/core/core.c
diff options
context:
space:
mode:
authorUlf Hansson <ulf.hansson@linaro.org>2013-06-10 11:03:37 -0400
committerChris Ball <cjb@laptop.org>2013-06-27 12:39:15 -0400
commit810caddba42a54fe5db4e2664757a9a334ba359c (patch)
tree12bd0ddf6a95e42bbc5f0438337b5492710760d6 /drivers/mmc/core/core.c
parent58a8a4a1a5da4694a3a069de5e0a8c15995e7b5f (diff)
mmc: core: Validate suspend prerequisites for SDIO at SUSPEND_PREPARE
This patch moves the validation for all the suspend prerequisites to be done at SUSPEND_PREPARE notification. Previously in the SDIO case parts of the validation was done from mmc_suspend_host. This patch invents a new pre_suspend bus_ops callback and implements it for SDIO. Returning an error code from it, will mean at SUSPEND_PREPARE notification, the card will be removed before proceeding with the suspend sequence. Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> Tested-by: Jaehoon Chung <jh80.chung@samsung.com> Signed-off-by: Chris Ball <cjb@laptop.org>
Diffstat (limited to 'drivers/mmc/core/core.c')
-rw-r--r--drivers/mmc/core/core.c25
1 files changed, 8 insertions, 17 deletions
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index d2ee2829b313..7a8a42d3a039 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -2628,22 +2628,6 @@ int mmc_suspend_host(struct mmc_host *host)
2628 if (host->bus_ops && !host->bus_dead) { 2628 if (host->bus_ops && !host->bus_dead) {
2629 if (host->bus_ops->suspend) 2629 if (host->bus_ops->suspend)
2630 err = host->bus_ops->suspend(host); 2630 err = host->bus_ops->suspend(host);
2631
2632 if (err == -ENOSYS || !host->bus_ops->resume) {
2633 /*
2634 * We simply "remove" the card in this case.
2635 * It will be redetected on resume. (Calling
2636 * bus_ops->remove() with a claimed host can
2637 * deadlock.)
2638 */
2639 host->bus_ops->remove(host);
2640 mmc_claim_host(host);
2641 mmc_detach_bus(host);
2642 mmc_power_off(host);
2643 mmc_release_host(host);
2644 host->pm_flags = 0;
2645 err = 0;
2646 }
2647 } 2631 }
2648 mmc_bus_put(host); 2632 mmc_bus_put(host);
2649 2633
@@ -2706,6 +2690,7 @@ int mmc_pm_notify(struct notifier_block *notify_block,
2706 struct mmc_host *host = container_of( 2690 struct mmc_host *host = container_of(
2707 notify_block, struct mmc_host, pm_notify); 2691 notify_block, struct mmc_host, pm_notify);
2708 unsigned long flags; 2692 unsigned long flags;
2693 int err = 0;
2709 2694
2710 switch (mode) { 2695 switch (mode) {
2711 case PM_HIBERNATION_PREPARE: 2696 case PM_HIBERNATION_PREPARE:
@@ -2715,7 +2700,13 @@ int mmc_pm_notify(struct notifier_block *notify_block,
2715 spin_unlock_irqrestore(&host->lock, flags); 2700 spin_unlock_irqrestore(&host->lock, flags);
2716 cancel_delayed_work_sync(&host->detect); 2701 cancel_delayed_work_sync(&host->detect);
2717 2702
2718 if (!host->bus_ops || host->bus_ops->suspend) 2703 if (!host->bus_ops)
2704 break;
2705
2706 /* Validate prerequisites for suspend */
2707 if (host->bus_ops->pre_suspend)
2708 err = host->bus_ops->pre_suspend(host);
2709 if (!err && host->bus_ops->suspend)
2719 break; 2710 break;
2720 2711
2721 /* Calling bus_ops->remove() with a claimed host can deadlock */ 2712 /* Calling bus_ops->remove() with a claimed host can deadlock */