runtime_idle() callback implementations have to return a non-zero value if they don't intend to suspend now. Several drivers use an errno like -EBUSY for this purpose. This can be problematic because the return value is propagated up the call chain, from rpm_idle() to __pm_runtime_idle(), and from there to callers like pm_runtime_put_sync(). A driver author checking the return value of e.g. pm_runtime_put_sync() may as usual check for retval < 0 and bail out. Therefore a positive value should be returned. To facilitate this add constants RPM_IDLE_SUSPEND and RPM_IDLE_NO_SUSPEND.
Signed-off-by: Heiner Kallweit <hkallwe...@gmail.com> --- drivers/base/power/runtime.c | 6 +++++- include/linux/pm.h | 10 ++++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c index 9f62790f6..4f529075e 100644 --- a/drivers/base/power/runtime.c +++ b/drivers/base/power/runtime.c @@ -453,7 +453,11 @@ static int rpm_idle(struct device *dev, int rpmflags) out: trace_rpm_return_int_rcuidle(dev, _THIS_IP_, retval); - return retval ? retval : rpm_suspend(dev, rpmflags | RPM_AUTO); + + if (retval == RPM_IDLE_SUSPEND) + return rpm_suspend(dev, rpmflags | RPM_AUTO); + + return retval; } /** diff --git a/include/linux/pm.h b/include/linux/pm.h index 121c104a4..971ed3d77 100644 --- a/include/linux/pm.h +++ b/include/linux/pm.h @@ -227,8 +227,9 @@ typedef struct pm_message { * * @runtime_idle: Device appears to be inactive and it might be put into a * low-power state if all of the necessary conditions are satisfied. - * Check these conditions, and return 0 if it's appropriate to let the PM - * core queue a suspend request for the device. + * Check these conditions, and return RPM_IDLE_SUSPEND if it's + * appropriate to let the PM core queue a suspend request for the device. + * Return RPM_IDLE_NO_SUSPEND if you don't want to suspend now. * * Several device power state transitions are externally visible, affecting * the state of pending I/O queues and (for drivers that touch hardware) @@ -523,6 +524,11 @@ enum rpm_request { RPM_REQ_RESUME, }; +enum rpm_idle { + RPM_IDLE_SUSPEND = 0, + RPM_IDLE_NO_SUSPEND, +}; + struct wakeup_source; struct wake_irq; struct pm_domain_data; -- 2.26.2