PM: Allow runtime_suspend methods to call pm_schedule_suspend()
authorAlan Stern <stern@rowland.harvard.edu>
Mon, 22 Mar 2010 23:50:07 +0000 (00:50 +0100)
committerRafael J. Wysocki <rjw@sisk.pl>
Mon, 10 May 2010 21:08:16 +0000 (23:08 +0200)
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>
drivers/base/power/runtime.c

index 626dd147b75ffce582944d303430197213d61fcf..b0ec0e9f27e9c7d66bb0a088f5bf6329ee35df60 100644 (file)
@@ -229,14 +229,16 @@ int __pm_runtime_suspend(struct device *dev, bool from_wq)
 
        if (retval) {
                dev->power.runtime_status = RPM_ACTIVE;
-               pm_runtime_cancel_pending(dev);
-
                if (retval == -EAGAIN || retval == -EBUSY) {
-                       notify = true;
+                       if (dev->power.timer_expires == 0)
+                               notify = true;
                        dev->power.runtime_error = 0;
+               } else {
+                       pm_runtime_cancel_pending(dev);
                }
        } else {
                dev->power.runtime_status = RPM_SUSPENDED;
+               pm_runtime_deactivate_timer(dev);
 
                if (dev->parent) {
                        parent = dev->parent;
@@ -659,8 +661,6 @@ int pm_schedule_suspend(struct device *dev, unsigned int delay)
 
        if (dev->power.runtime_status == RPM_SUSPENDED)
                retval = 1;
-       else if (dev->power.runtime_status == RPM_SUSPENDING)
-               retval = -EINPROGRESS;
        else if (atomic_read(&dev->power.usage_count) > 0
            || dev->power.disable_depth > 0)
                retval = -EAGAIN;