summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Norris <briannorris@chromium.org>2025-09-25 12:42:15 -0700
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2025-09-27 13:41:47 +0200
commitd0b8651a026125d58b50b464aeb78f2c5956179f (patch)
tree844204cb57c0d563d7371534727d59ee31c1d19d
parent7f7acd193ba8aaa8ed07cfadc335bb17a991fd42 (diff)
PM: runtime: Make put{,_sync}() return 1 when already suspended
The pm_runtime.h docs say pm_runtime_put() and pm_runtime_put_sync() return 1 when already suspended, but this is not true -- they return -EAGAIN. On the other hand, pm_runtime_put_sync_suspend() and pm_runtime_put_sync_autosuspend() *do* return 1. This is an artifact of the fact that the former are built on rpm_idle(), whereas the latter are built on rpm_suspend(). There are precious few pm_runtime_put()/pm_runtime_put_sync() callers that check the return code at all, but most of them only log errors, and usually only for negative error codes. None of them should be treating this as an error, so: * at best, this may fix some case where a driver treats this condition as an error, when it shouldn't; * at worst, this should make no effect; and * somewhere in between, we could potentially clear up non-fatal log messages. Fix the pm_runtime_already_suspended_test() while tweaking the behavior. The test makes a lot more sense when these all return 1 when the device is already suspended: pm_runtime_put_sync(dev); pm_runtime_suspend(dev); pm_runtime_autosuspend(dev); pm_request_autosuspend(dev); pm_runtime_put_sync_autosuspend(dev); Notably, I've avoided testing the return codes for these, since they really should be ignored by callers, and we may make them 'void' altogether: pm_runtime_put(dev); pm_runtime_put_autosuspend(dev); Signed-off-by: Brian Norris <briannorris@chromium.org> Reviewed-by: Dhruva Gole <d-gole@ti.com> Reviewed-by: Sakari Ailus <sakari.ailus@linux.intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r--drivers/base/power/runtime-test.c2
-rw-r--r--drivers/base/power/runtime.c3
2 files changed, 4 insertions, 1 deletions
diff --git a/drivers/base/power/runtime-test.c b/drivers/base/power/runtime-test.c
index 2e966fd96664..eca9885e807d 100644
--- a/drivers/base/power/runtime-test.c
+++ b/drivers/base/power/runtime-test.c
@@ -42,7 +42,7 @@ static void pm_runtime_already_suspended_test(struct kunit *test)
pm_runtime_put(dev);
pm_runtime_get_noresume(dev);
- KUNIT_EXPECT_EQ(test, -EAGAIN, pm_runtime_put_sync(dev));
+ KUNIT_EXPECT_EQ(test, 1, pm_runtime_put_sync(dev));
KUNIT_EXPECT_EQ(test, 1, pm_runtime_suspend(dev));
KUNIT_EXPECT_EQ(test, 1, pm_runtime_autosuspend(dev));
diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
index 3e84dc4122de..faa68bf9ef3d 100644
--- a/drivers/base/power/runtime.c
+++ b/drivers/base/power/runtime.c
@@ -498,6 +498,9 @@ static int rpm_idle(struct device *dev, int rpmflags)
if (retval < 0)
; /* Conditions are wrong. */
+ else if ((rpmflags & RPM_GET_PUT) && retval == 1)
+ ; /* put() is allowed in RPM_SUSPENDED */
+
/* Idle notifications are allowed only in the RPM_ACTIVE state. */
else if (dev->power.runtime_status != RPM_ACTIVE)
retval = -EAGAIN;