diff options
author | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2013-06-03 15:49:52 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2013-06-03 15:49:52 -0400 |
commit | 45f0a85c8258741d11bda25c0a5669c06267204a (patch) | |
tree | a618cce0583426a5c7f53f56cf19139a6f9733ce /drivers/base/power | |
parent | cd38ca854de15b26eb91009137cbe157d8a8e773 (diff) |
PM / Runtime: Rework the "runtime idle" helper routine
The "runtime idle" helper routine, rpm_idle(), currently ignores
return values from .runtime_idle() callbacks executed by it.
However, it turns out that many subsystems use
pm_generic_runtime_idle() which checks the return value of the
driver's callback and executes pm_runtime_suspend() for the device
unless that value is not 0. If that logic is moved to rpm_idle()
instead, pm_generic_runtime_idle() can be dropped and its users
will not need any .runtime_idle() callbacks any more.
Moreover, the PCI, SCSI, and SATA subsystems' .runtime_idle()
routines, pci_pm_runtime_idle(), scsi_runtime_idle(), and
ata_port_runtime_idle(), respectively, as well as a few drivers'
ones may be simplified if rpm_idle() calls rpm_suspend() after 0 has
been returned by the .runtime_idle() callback executed by it.
To reduce overall code bloat, make the changes described above.
Tested-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Tested-by: Kevin Hilman <khilman@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Kevin Hilman <khilman@linaro.org>
Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Diffstat (limited to 'drivers/base/power')
-rw-r--r-- | drivers/base/power/domain.c | 1 | ||||
-rw-r--r-- | drivers/base/power/generic_ops.c | 23 | ||||
-rw-r--r-- | drivers/base/power/runtime.c | 12 |
3 files changed, 5 insertions, 31 deletions
diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index 7072404c8b6d..bfb8955c406c 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c | |||
@@ -2143,7 +2143,6 @@ void pm_genpd_init(struct generic_pm_domain *genpd, | |||
2143 | genpd->max_off_time_changed = true; | 2143 | genpd->max_off_time_changed = true; |
2144 | genpd->domain.ops.runtime_suspend = pm_genpd_runtime_suspend; | 2144 | genpd->domain.ops.runtime_suspend = pm_genpd_runtime_suspend; |
2145 | genpd->domain.ops.runtime_resume = pm_genpd_runtime_resume; | 2145 | genpd->domain.ops.runtime_resume = pm_genpd_runtime_resume; |
2146 | genpd->domain.ops.runtime_idle = pm_generic_runtime_idle; | ||
2147 | genpd->domain.ops.prepare = pm_genpd_prepare; | 2146 | genpd->domain.ops.prepare = pm_genpd_prepare; |
2148 | genpd->domain.ops.suspend = pm_genpd_suspend; | 2147 | genpd->domain.ops.suspend = pm_genpd_suspend; |
2149 | genpd->domain.ops.suspend_late = pm_genpd_suspend_late; | 2148 | genpd->domain.ops.suspend_late = pm_genpd_suspend_late; |
diff --git a/drivers/base/power/generic_ops.c b/drivers/base/power/generic_ops.c index bfd898b8988e..5ee030a864f9 100644 --- a/drivers/base/power/generic_ops.c +++ b/drivers/base/power/generic_ops.c | |||
@@ -12,29 +12,6 @@ | |||
12 | 12 | ||
13 | #ifdef CONFIG_PM_RUNTIME | 13 | #ifdef CONFIG_PM_RUNTIME |
14 | /** | 14 | /** |
15 | * pm_generic_runtime_idle - Generic runtime idle callback for subsystems. | ||
16 | * @dev: Device to handle. | ||
17 | * | ||
18 | * If PM operations are defined for the @dev's driver and they include | ||
19 | * ->runtime_idle(), execute it and return its error code, if nonzero. | ||
20 | * Otherwise, execute pm_runtime_suspend() for the device and return 0. | ||
21 | */ | ||
22 | int pm_generic_runtime_idle(struct device *dev) | ||
23 | { | ||
24 | const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; | ||
25 | |||
26 | if (pm && pm->runtime_idle) { | ||
27 | int ret = pm->runtime_idle(dev); | ||
28 | if (ret) | ||
29 | return ret; | ||
30 | } | ||
31 | |||
32 | pm_runtime_suspend(dev); | ||
33 | return 0; | ||
34 | } | ||
35 | EXPORT_SYMBOL_GPL(pm_generic_runtime_idle); | ||
36 | |||
37 | /** | ||
38 | * pm_generic_runtime_suspend - Generic runtime suspend callback for subsystems. | 15 | * pm_generic_runtime_suspend - Generic runtime suspend callback for subsystems. |
39 | * @dev: Device to suspend. | 16 | * @dev: Device to suspend. |
40 | * | 17 | * |
diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c index ef13ad08afb2..268a35097578 100644 --- a/drivers/base/power/runtime.c +++ b/drivers/base/power/runtime.c | |||
@@ -293,11 +293,8 @@ static int rpm_idle(struct device *dev, int rpmflags) | |||
293 | /* Pending requests need to be canceled. */ | 293 | /* Pending requests need to be canceled. */ |
294 | dev->power.request = RPM_REQ_NONE; | 294 | dev->power.request = RPM_REQ_NONE; |
295 | 295 | ||
296 | if (dev->power.no_callbacks) { | 296 | if (dev->power.no_callbacks) |
297 | /* Assume ->runtime_idle() callback would have suspended. */ | ||
298 | retval = rpm_suspend(dev, rpmflags); | ||
299 | goto out; | 297 | goto out; |
300 | } | ||
301 | 298 | ||
302 | /* Carry out an asynchronous or a synchronous idle notification. */ | 299 | /* Carry out an asynchronous or a synchronous idle notification. */ |
303 | if (rpmflags & RPM_ASYNC) { | 300 | if (rpmflags & RPM_ASYNC) { |
@@ -306,7 +303,8 @@ static int rpm_idle(struct device *dev, int rpmflags) | |||
306 | dev->power.request_pending = true; | 303 | dev->power.request_pending = true; |
307 | queue_work(pm_wq, &dev->power.work); | 304 | queue_work(pm_wq, &dev->power.work); |
308 | } | 305 | } |
309 | goto out; | 306 | trace_rpm_return_int(dev, _THIS_IP_, 0); |
307 | return 0; | ||
310 | } | 308 | } |
311 | 309 | ||
312 | dev->power.idle_notification = true; | 310 | dev->power.idle_notification = true; |
@@ -326,14 +324,14 @@ static int rpm_idle(struct device *dev, int rpmflags) | |||
326 | callback = dev->driver->pm->runtime_idle; | 324 | callback = dev->driver->pm->runtime_idle; |
327 | 325 | ||
328 | if (callback) | 326 | if (callback) |
329 | __rpm_callback(callback, dev); | 327 | retval = __rpm_callback(callback, dev); |
330 | 328 | ||
331 | dev->power.idle_notification = false; | 329 | dev->power.idle_notification = false; |
332 | wake_up_all(&dev->power.wait_queue); | 330 | wake_up_all(&dev->power.wait_queue); |
333 | 331 | ||
334 | out: | 332 | out: |
335 | trace_rpm_return_int(dev, _THIS_IP_, retval); | 333 | trace_rpm_return_int(dev, _THIS_IP_, retval); |
336 | return retval; | 334 | return retval ? retval : rpm_suspend(dev, rpmflags); |
337 | } | 335 | } |
338 | 336 | ||
339 | /** | 337 | /** |