aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/power/runtime_pm.txt10
-rw-r--r--drivers/base/power/runtime.c18
2 files changed, 26 insertions, 2 deletions
diff --git a/Documentation/power/runtime_pm.txt b/Documentation/power/runtime_pm.txt
index 0e856088db7c..5336149f831b 100644
--- a/Documentation/power/runtime_pm.txt
+++ b/Documentation/power/runtime_pm.txt
@@ -789,6 +789,16 @@ will behave normally, not taking the autosuspend delay into account.
789Similarly, if the power.use_autosuspend field isn't set then the autosuspend 789Similarly, if the power.use_autosuspend field isn't set then the autosuspend
790helper functions will behave just like the non-autosuspend counterparts. 790helper functions will behave just like the non-autosuspend counterparts.
791 791
792Under some circumstances a driver or subsystem may want to prevent a device
793from autosuspending immediately, even though the usage counter is zero and the
794autosuspend delay time has expired. If the ->runtime_suspend() callback
795returns -EAGAIN or -EBUSY, and if the next autosuspend delay expiration time is
796in the future (as it normally would be if the callback invoked
797pm_runtime_mark_last_busy()), the PM core will automatically reschedule the
798autosuspend. The ->runtime_suspend() callback can't do this rescheduling
799itself because no suspend requests of any kind are accepted while the device is
800suspending (i.e., while the callback is running).
801
792The implementation is well suited for asynchronous use in interrupt contexts. 802The implementation is well suited for asynchronous use in interrupt contexts.
793However such use inevitably involves races, because the PM core can't 803However such use inevitably involves races, because the PM core can't
794synchronize ->runtime_suspend() callbacks with the arrival of I/O requests. 804synchronize ->runtime_suspend() callbacks with the arrival of I/O requests.
diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
index 18ef87e525fa..124dbf60c9bf 100644
--- a/drivers/base/power/runtime.c
+++ b/drivers/base/power/runtime.c
@@ -293,6 +293,9 @@ static int rpm_callback(int (*cb)(struct device *), struct device *dev)
293 * the callback was running then carry it out, otherwise send an idle 293 * the callback was running then carry it out, otherwise send an idle
294 * notification for its parent (if the suspend succeeded and both 294 * notification for its parent (if the suspend succeeded and both
295 * ignore_children of parent->power and irq_safe of dev->power are not set). 295 * ignore_children of parent->power and irq_safe of dev->power are not set).
296 * If ->runtime_suspend failed with -EAGAIN or -EBUSY, and if the RPM_AUTO
297 * flag is set and the next autosuspend-delay expiration time is in the
298 * future, schedule another autosuspend attempt.
296 * 299 *
297 * This function must be called under dev->power.lock with interrupts disabled. 300 * This function must be called under dev->power.lock with interrupts disabled.
298 */ 301 */
@@ -413,10 +416,21 @@ static int rpm_suspend(struct device *dev, int rpmflags)
413 if (retval) { 416 if (retval) {
414 __update_runtime_status(dev, RPM_ACTIVE); 417 __update_runtime_status(dev, RPM_ACTIVE);
415 dev->power.deferred_resume = false; 418 dev->power.deferred_resume = false;
416 if (retval == -EAGAIN || retval == -EBUSY) 419 if (retval == -EAGAIN || retval == -EBUSY) {
417 dev->power.runtime_error = 0; 420 dev->power.runtime_error = 0;
418 else 421
422 /*
423 * If the callback routine failed an autosuspend, and
424 * if the last_busy time has been updated so that there
425 * is a new autosuspend expiration time, automatically
426 * reschedule another autosuspend.
427 */
428 if ((rpmflags & RPM_AUTO) &&
429 pm_runtime_autosuspend_expiration(dev) != 0)
430 goto repeat;
431 } else {
419 pm_runtime_cancel_pending(dev); 432 pm_runtime_cancel_pending(dev);
433 }
420 wake_up_all(&dev->power.wait_queue); 434 wake_up_all(&dev->power.wait_queue);
421 goto out; 435 goto out;
422 } 436 }