diff options
author | Alan Stern <stern@rowland.harvard.edu> | 2010-03-22 19:50:07 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rjw@sisk.pl> | 2010-05-10 17:08:16 -0400 |
commit | 240c7337a4cd3d91b196c5ef97ad461b3a22fa09 (patch) | |
tree | 252a5938fa8c9f75925653876c32bef1a2ed899b /drivers | |
parent | 228c54ef7a028d5a4b6606eb0c8035874d9b6788 (diff) |
PM: Allow runtime_suspend methods to call pm_schedule_suspend()
This patch (as1361) changes the runtime PM interface slightly; it
allows suspend requests to be scheduled while the runtime_suspend
method is running. If the method succeeds then the scheduled request
is cancelled, whereas if the method fails then an idle notification is
sent only if no request was scheduled.
Being able to schedule suspend requests from within a runtime_suspend
method is useful for drivers that need to test for idleness and
suspend the device all while holding a single spinlock, or for drivers
that want to check for idleness by polling.
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/base/power/runtime.c | 10 |
1 files changed, 5 insertions, 5 deletions
diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c index 626dd147b75f..b0ec0e9f27e9 100644 --- a/drivers/base/power/runtime.c +++ b/drivers/base/power/runtime.c | |||
@@ -229,14 +229,16 @@ int __pm_runtime_suspend(struct device *dev, bool from_wq) | |||
229 | 229 | ||
230 | if (retval) { | 230 | if (retval) { |
231 | dev->power.runtime_status = RPM_ACTIVE; | 231 | dev->power.runtime_status = RPM_ACTIVE; |
232 | pm_runtime_cancel_pending(dev); | ||
233 | |||
234 | if (retval == -EAGAIN || retval == -EBUSY) { | 232 | if (retval == -EAGAIN || retval == -EBUSY) { |
235 | notify = true; | 233 | if (dev->power.timer_expires == 0) |
234 | notify = true; | ||
236 | dev->power.runtime_error = 0; | 235 | dev->power.runtime_error = 0; |
236 | } else { | ||
237 | pm_runtime_cancel_pending(dev); | ||
237 | } | 238 | } |
238 | } else { | 239 | } else { |
239 | dev->power.runtime_status = RPM_SUSPENDED; | 240 | dev->power.runtime_status = RPM_SUSPENDED; |
241 | pm_runtime_deactivate_timer(dev); | ||
240 | 242 | ||
241 | if (dev->parent) { | 243 | if (dev->parent) { |
242 | parent = dev->parent; | 244 | parent = dev->parent; |
@@ -659,8 +661,6 @@ int pm_schedule_suspend(struct device *dev, unsigned int delay) | |||
659 | 661 | ||
660 | if (dev->power.runtime_status == RPM_SUSPENDED) | 662 | if (dev->power.runtime_status == RPM_SUSPENDED) |
661 | retval = 1; | 663 | retval = 1; |
662 | else if (dev->power.runtime_status == RPM_SUSPENDING) | ||
663 | retval = -EINPROGRESS; | ||
664 | else if (atomic_read(&dev->power.usage_count) > 0 | 664 | else if (atomic_read(&dev->power.usage_count) > 0 |
665 | || dev->power.disable_depth > 0) | 665 | || dev->power.disable_depth > 0) |
666 | retval = -EAGAIN; | 666 | retval = -EAGAIN; |