summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPraveen Talari <praveen.talari@oss.qualcomm.com>2026-07-06 14:23:09 +0530
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2026-07-09 16:50:18 +0200
commiteef1d74bf88f120f4f63a83a5201fcda67bf3b52 (patch)
tree04f1877cc828da29a39e81f5587e590f892c2158
parent8cdeaa50eae8dad34885515f62559ee83e7e8dda (diff)
PM: runtime: Only set runtime_error on suspend callback failures
When a runtime resume callback returns an error, rpm_callback() sets power.runtime_error on the device. This causes all subsequent calls to rpm_resume() to return -EINVAL immediately at the top of the function without invoking the callback again, making the failure permanent until runtime PM is explicitly re-initialized. Unlike suspend failures, resume failures should be retryable. If a device's resume callback fails, there is no reason to permanently block future resume attempts on that device and all of its consumers. Fix this by moving the power.runtime_error assignment out of the generic rpm_callback() and into rpm_suspend() at its fail label, where suspend callback failures are handled. Resume callback failures now return the error to the caller but leave power.runtime_error clear, allowing the next resume attempt to invoke the callback normally. Signed-off-by: Praveen Talari <praveen.talari@oss.qualcomm.com> Link: https://patch.msgid.link/20260706-fix_sticky_-einval_after_pm_runtime_api_failure-v3-1-92feb5a7b926@oss.qualcomm.com Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r--drivers/base/power/runtime.c6
1 files changed, 3 insertions, 3 deletions
diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
index 335288e8b5b3..fab38bc98113 100644
--- a/drivers/base/power/runtime.c
+++ b/drivers/base/power/runtime.c
@@ -469,9 +469,6 @@ static int rpm_callback(int (*cb)(struct device *), struct device *dev)
if (retval == -EACCES)
retval = -EAGAIN;
- if (retval != -EAGAIN && retval != -EBUSY)
- dev->power.runtime_error = retval;
-
return retval;
}
@@ -751,6 +748,9 @@ static int rpm_suspend(struct device *dev, int rpmflags)
dev->power.deferred_resume = false;
wake_up_all(&dev->power.wait_queue);
+ if (retval != -EAGAIN && retval != -EBUSY)
+ dev->power.runtime_error = retval;
+
/*
* On transient errors, if the callback routine failed an autosuspend,
* and if the last_busy time has been updated so that there is a new