diff options
author | Ohad Ben-Cohen <ohad@wizery.com> | 2010-10-02 07:54:13 -0400 |
---|---|---|
committer | Chris Ball <cjb@laptop.org> | 2010-10-23 09:11:19 -0400 |
commit | ed2a9785942b0986ac858f3f48d7fc5f7c7183de (patch) | |
tree | 31853b8ba7ab7ee06fbd5bbf08c9e94fca091631 /drivers/mmc/core | |
parent | 87973ba27b751353e2915cb3aa5c0e0dc6a79a4f (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/core')
-rw-r--r-- | drivers/mmc/core/sdio_bus.c | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/drivers/mmc/core/sdio_bus.c b/drivers/mmc/core/sdio_bus.c index 36374834fcff..2716c7ab6bbf 100644 --- a/drivers/mmc/core/sdio_bus.c +++ b/drivers/mmc/core/sdio_bus.c | |||
@@ -189,12 +189,41 @@ out: | |||
189 | 189 | ||
190 | #ifdef CONFIG_PM_RUNTIME | 190 | #ifdef CONFIG_PM_RUNTIME |
191 | 191 | ||
192 | static int sdio_bus_pm_prepare(struct device *dev) | ||
193 | { | ||
194 | /* | ||
195 | * Resume an SDIO device which was suspended at run time at this | ||
196 | * point, in order to allow standard SDIO suspend/resume paths | ||
197 | * to keep working as usual. | ||
198 | * | ||
199 | * Ultimately, the SDIO driver itself will decide (in its | ||
200 | * suspend handler, or lack thereof) whether the card should be | ||
201 | * removed or kept, and if kept, at what power state. | ||
202 | * | ||
203 | * At this point, PM core have increased our use count, so it's | ||
204 | * safe to directly resume the device. After system is resumed | ||
205 | * again, PM core will drop back its runtime PM use count, and if | ||
206 | * needed device will be suspended again. | ||
207 | * | ||
208 | * The end result is guaranteed to be a power state that is | ||
209 | * coherent with the device's runtime PM use count. | ||
210 | * | ||
211 | * The return value of pm_runtime_resume is deliberately unchecked | ||
212 | * since there is little point in failing system suspend if a | ||
213 | * device can't be resumed. | ||
214 | */ | ||
215 | pm_runtime_resume(dev); | ||
216 | |||
217 | return 0; | ||
218 | } | ||
219 | |||
192 | static const struct dev_pm_ops sdio_bus_pm_ops = { | 220 | static const struct dev_pm_ops sdio_bus_pm_ops = { |
193 | SET_RUNTIME_PM_OPS( | 221 | SET_RUNTIME_PM_OPS( |
194 | pm_generic_runtime_suspend, | 222 | pm_generic_runtime_suspend, |
195 | pm_generic_runtime_resume, | 223 | pm_generic_runtime_resume, |
196 | pm_generic_runtime_idle | 224 | pm_generic_runtime_idle |
197 | ) | 225 | ) |
226 | .prepare = sdio_bus_pm_prepare, | ||
198 | }; | 227 | }; |
199 | 228 | ||
200 | #define SDIO_PM_OPS_PTR (&sdio_bus_pm_ops) | 229 | #define SDIO_PM_OPS_PTR (&sdio_bus_pm_ops) |