summaryrefslogtreecommitdiffstats
path: root/drivers/mmc
diff options
context:
space:
mode:
authorOhad Ben-Cohen <ohad@wizery.com>2010-10-02 13:54:13 +0200
committerChris Ball <cjb@laptop.org>2010-10-23 21:11:19 +0800
commited2a9785942b0986ac858f3f48d7fc5f7c7183de (patch)
tree31853b8ba7ab7ee06fbd5bbf08c9e94fca091631 /drivers/mmc
parent87973ba27b751353e2915cb3aa5c0e0dc6a79a4f (diff)
mmc: sdio: support suspend/resume while runtime suspended
Bring SDIO devices back to full power before their suspend handler is invoked. Doing so ensures that SDIO suspend/resume semantics are maintained (drivers still get to decide whether their card should be removed or kept during system suspend, and at what power state), and that SDIO suspend/resume execution paths are unchanged. This is achieved by resuming a runtime-suspended SDIO device in its ->prepare() PM callback (similary to the PCI subsystem). Since the PM core always increments the run-time usage counter before calling the ->prepare() callback and decrements it after calling the ->complete() callback, it is guaranteed that when the system will come out of suspend, our device's power state will reflect its runtime PM usage counter. Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com> Tested-by: Luciano Coelho <luciano.coelho@nokia.com> Signed-off-by: Chris Ball <cjb@laptop.org>
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/core/sdio_bus.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/drivers/mmc/core/sdio_bus.c b/drivers/mmc/core/sdio_bus.c
index 36374834fcf..2716c7ab6bb 100644
--- a/drivers/mmc/core/sdio_bus.c
+++ b/drivers/mmc/core/sdio_bus.c
@@ -189,12 +189,41 @@ out:
#ifdef CONFIG_PM_RUNTIME
+static int sdio_bus_pm_prepare(struct device *dev)
+{
+ /*
+ * Resume an SDIO device which was suspended at run time at this
+ * point, in order to allow standard SDIO suspend/resume paths
+ * to keep working as usual.
+ *
+ * Ultimately, the SDIO driver itself will decide (in its
+ * suspend handler, or lack thereof) whether the card should be
+ * removed or kept, and if kept, at what power state.
+ *
+ * At this point, PM core have increased our use count, so it's
+ * safe to directly resume the device. After system is resumed
+ * again, PM core will drop back its runtime PM use count, and if
+ * needed device will be suspended again.
+ *
+ * The end result is guaranteed to be a power state that is
+ * coherent with the device's runtime PM use count.
+ *
+ * The return value of pm_runtime_resume is deliberately unchecked
+ * since there is little point in failing system suspend if a
+ * device can't be resumed.
+ */
+ pm_runtime_resume(dev);
+
+ return 0;
+}
+
static const struct dev_pm_ops sdio_bus_pm_ops = {
SET_RUNTIME_PM_OPS(
pm_generic_runtime_suspend,
pm_generic_runtime_resume,
pm_generic_runtime_idle
)
+ .prepare = sdio_bus_pm_prepare,
};
#define SDIO_PM_OPS_PTR (&sdio_bus_pm_ops)