diff options
author | Rafael J. Wysocki <rjw@sisk.pl> | 2011-10-16 23:26:49 +0200 |
---|---|---|
committer | Rafael J. Wysocki <rjw@sisk.pl> | 2011-10-16 23:26:49 +0200 |
commit | 9bd717c0dc8224cadfd66df7eeff98c987711d98 (patch) | |
tree | bca8a9232d457d984d87da53b5ffadcb7dcd46be /drivers/base | |
parent | 7811ac276bb9f77aa6475110ef340c1bc3090def (diff) | |
parent | 857b36c7b038ac56a882ee914df93e5985443074 (diff) |
Merge branch 'pm-runtime' into pm-for-linus
* pm-runtime:
PM / Runtime: Handle .runtime_suspend() failure correctly
PM / Runtime: Fix kerneldoc comment for rpm_suspend()
PM / Runtime: Update document about callbacks
Diffstat (limited to 'drivers/base')
-rw-r--r-- | drivers/base/power/runtime.c | 33 |
1 files changed, 18 insertions, 15 deletions
diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c index 7a6fb5e34a0e..6bb3aafa85ed 100644 --- a/drivers/base/power/runtime.c +++ b/drivers/base/power/runtime.c @@ -286,14 +286,16 @@ static int rpm_callback(int (*cb)(struct device *), struct device *dev) * @dev: Device to suspend. * @rpmflags: Flag bits. * - * Check if the device's runtime PM status allows it to be suspended. If - * another suspend has been started earlier, either return immediately or wait - * for it to finish, depending on the RPM_NOWAIT and RPM_ASYNC flags. Cancel a - * pending idle notification. If the RPM_ASYNC flag is set then queue a - * suspend request; otherwise run the ->runtime_suspend() callback directly. - * If a deferred resume was requested while the callback was running then carry - * it out; otherwise send an idle notification for the device (if the suspend - * failed) or for its parent (if the suspend succeeded). + * Check if the device's runtime PM status allows it to be suspended. + * Cancel a pending idle notification, autosuspend or suspend. If + * another suspend has been started earlier, either return immediately + * or wait for it to finish, depending on the RPM_NOWAIT and RPM_ASYNC + * flags. If the RPM_ASYNC flag is set then queue a suspend request; + * otherwise run the ->runtime_suspend() callback directly. When + * ->runtime_suspend succeeded, if a deferred resume was requested while + * the callback was running then carry it out, otherwise send an idle + * notification for its parent (if the suspend succeeded and both + * ignore_children of parent->power and irq_safe of dev->power are not set). * * This function must be called under dev->power.lock with interrupts disabled. */ @@ -418,15 +420,16 @@ static int rpm_suspend(struct device *dev, int rpmflags) dev->power.runtime_error = 0; else pm_runtime_cancel_pending(dev); - } else { + wake_up_all(&dev->power.wait_queue); + goto out; + } no_callback: - __update_runtime_status(dev, RPM_SUSPENDED); - pm_runtime_deactivate_timer(dev); + __update_runtime_status(dev, RPM_SUSPENDED); + pm_runtime_deactivate_timer(dev); - if (dev->parent) { - parent = dev->parent; - atomic_add_unless(&parent->power.child_count, -1, 0); - } + if (dev->parent) { + parent = dev->parent; + atomic_add_unless(&parent->power.child_count, -1, 0); } wake_up_all(&dev->power.wait_queue); |