diff options
author | Ulf Hansson <ulf.hansson@linaro.org> | 2013-10-15 16:25:08 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2013-10-15 20:06:57 -0400 |
commit | d66e6db28df330c0e5b61f9863754fc2fd37f8ca (patch) | |
tree | 7e7a9a8ed73b80c083019acd337956b3c537ff5f | |
parent | 61e6cfa80de5760bbe406f4e815b7739205754d2 (diff) |
PM / Runtime: Respect autosuspend when idle triggers suspend
For devices which don't have a .runtime_idle() callback or if it
returns 0, rpm_idle() will end up in triggering a call to
rpm_suspend(), thus trying to carry out a runtime suspend directly
from runtime_idle().
In the above situation we want to respect devices which has enabled
autosuspend, we therfore append the flag sent to rpm_suspend with
RPM_AUTO.
Do note that drivers still needs to update the device last busy mark,
to control the delay for this circumstance.
Updated runtime PM documentation accordingly.
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Acked-by: Kevin Hilman <khilman@linaro.org>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r-- | Documentation/power/runtime_pm.txt | 14 | ||||
-rw-r--r-- | drivers/base/power/runtime.c | 5 |
2 files changed, 11 insertions, 8 deletions
diff --git a/Documentation/power/runtime_pm.txt b/Documentation/power/runtime_pm.txt index 71d8fe4e75d3..0f54333b0ff2 100644 --- a/Documentation/power/runtime_pm.txt +++ b/Documentation/power/runtime_pm.txt | |||
@@ -145,11 +145,13 @@ The action performed by the idle callback is totally dependent on the subsystem | |||
145 | if the device can be suspended (i.e. if all of the conditions necessary for | 145 | if the device can be suspended (i.e. if all of the conditions necessary for |
146 | suspending the device are satisfied) and to queue up a suspend request for the | 146 | suspending the device are satisfied) and to queue up a suspend request for the |
147 | device in that case. If there is no idle callback, or if the callback returns | 147 | device in that case. If there is no idle callback, or if the callback returns |
148 | 0, then the PM core will attempt to carry out a runtime suspend of the device; | 148 | 0, then the PM core will attempt to carry out a runtime suspend of the device, |
149 | in essence, it will call pm_runtime_suspend() directly. To prevent this (for | 149 | also respecting devices configured for autosuspend. In essence this means a |
150 | example, if the callback routine has started a delayed suspend), the routine | 150 | call to pm_runtime_autosuspend() (do note that drivers needs to update the |
151 | should return a non-zero value. Negative error return codes are ignored by the | 151 | device last busy mark, pm_runtime_mark_last_busy(), to control the delay under |
152 | PM core. | 152 | this circumstance). To prevent this (for example, if the callback routine has |
153 | started a delayed suspend), the routine must return a non-zero value. Negative | ||
154 | error return codes are ignored by the PM core. | ||
153 | 155 | ||
154 | The helper functions provided by the PM core, described in Section 4, guarantee | 156 | The helper functions provided by the PM core, described in Section 4, guarantee |
155 | that the following constraints are met with respect to runtime PM callbacks for | 157 | that the following constraints are met with respect to runtime PM callbacks for |
@@ -308,7 +310,7 @@ drivers/base/power/runtime.c and include/linux/pm_runtime.h: | |||
308 | - execute the subsystem-level idle callback for the device; returns an | 310 | - execute the subsystem-level idle callback for the device; returns an |
309 | error code on failure, where -EINPROGRESS means that ->runtime_idle() is | 311 | error code on failure, where -EINPROGRESS means that ->runtime_idle() is |
310 | already being executed; if there is no callback or the callback returns 0 | 312 | already being executed; if there is no callback or the callback returns 0 |
311 | then run pm_runtime_suspend(dev) and return its result | 313 | then run pm_runtime_autosuspend(dev) and return its result |
312 | 314 | ||
313 | int pm_runtime_suspend(struct device *dev); | 315 | int pm_runtime_suspend(struct device *dev); |
314 | - execute the subsystem-level suspend callback for the device; returns 0 on | 316 | - execute the subsystem-level suspend callback for the device; returns 0 on |
diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c index 268a35097578..72e00e66ecc5 100644 --- a/drivers/base/power/runtime.c +++ b/drivers/base/power/runtime.c | |||
@@ -258,7 +258,8 @@ static int __rpm_callback(int (*cb)(struct device *), struct device *dev) | |||
258 | * Check if the device's runtime PM status allows it to be suspended. If | 258 | * Check if the device's runtime PM status allows it to be suspended. If |
259 | * another idle notification has been started earlier, return immediately. If | 259 | * another idle notification has been started earlier, return immediately. If |
260 | * the RPM_ASYNC flag is set then queue an idle-notification request; otherwise | 260 | * the RPM_ASYNC flag is set then queue an idle-notification request; otherwise |
261 | * run the ->runtime_idle() callback directly. | 261 | * run the ->runtime_idle() callback directly. If the ->runtime_idle callback |
262 | * doesn't exist or if it returns 0, call rpm_suspend with the RPM_AUTO flag. | ||
262 | * | 263 | * |
263 | * This function must be called under dev->power.lock with interrupts disabled. | 264 | * This function must be called under dev->power.lock with interrupts disabled. |
264 | */ | 265 | */ |
@@ -331,7 +332,7 @@ static int rpm_idle(struct device *dev, int rpmflags) | |||
331 | 332 | ||
332 | out: | 333 | out: |
333 | trace_rpm_return_int(dev, _THIS_IP_, retval); | 334 | trace_rpm_return_int(dev, _THIS_IP_, retval); |
334 | return retval ? retval : rpm_suspend(dev, rpmflags); | 335 | return retval ? retval : rpm_suspend(dev, rpmflags | RPM_AUTO); |
335 | } | 336 | } |
336 | 337 | ||
337 | /** | 338 | /** |