diff options
author | Ulf Hansson <ulf.hansson@linaro.org> | 2014-03-01 05:56:04 -0500 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2014-03-01 18:18:15 -0500 |
commit | 5f59df79837bb809f3945613aba5519cd9755a53 (patch) | |
tree | 3ad0bfc09e8898b1f1f22c252ba8ef6bdda623b7 /drivers/base/power | |
parent | cfbf8d4857c26a8a307fb7cd258074c9dcd8c691 (diff) |
PM / runtime: Fetch runtime PM callbacks using a macro
While fetching the proper runtime PM callback, we walk the hierarchy of
device's power domains, subsystems and drivers.
This is common for rpm_suspend(), rpm_idle() and rpm_resume(). Let's
clean up the code by using a macro that handles this.
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/base/power')
-rw-r--r-- | drivers/base/power/runtime.c | 78 |
1 files changed, 39 insertions, 39 deletions
diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c index 72e00e66ecc5..ac495b1357fa 100644 --- a/drivers/base/power/runtime.c +++ b/drivers/base/power/runtime.c | |||
@@ -13,6 +13,42 @@ | |||
13 | #include <trace/events/rpm.h> | 13 | #include <trace/events/rpm.h> |
14 | #include "power.h" | 14 | #include "power.h" |
15 | 15 | ||
16 | #define RPM_GET_CALLBACK(dev, cb) \ | ||
17 | ({ \ | ||
18 | int (*__rpm_cb)(struct device *__d); \ | ||
19 | \ | ||
20 | if (dev->pm_domain) \ | ||
21 | __rpm_cb = dev->pm_domain->ops.cb; \ | ||
22 | else if (dev->type && dev->type->pm) \ | ||
23 | __rpm_cb = dev->type->pm->cb; \ | ||
24 | else if (dev->class && dev->class->pm) \ | ||
25 | __rpm_cb = dev->class->pm->cb; \ | ||
26 | else if (dev->bus && dev->bus->pm) \ | ||
27 | __rpm_cb = dev->bus->pm->cb; \ | ||
28 | else \ | ||
29 | __rpm_cb = NULL; \ | ||
30 | \ | ||
31 | if (!__rpm_cb && dev->driver && dev->driver->pm) \ | ||
32 | __rpm_cb = dev->driver->pm->cb; \ | ||
33 | \ | ||
34 | __rpm_cb; \ | ||
35 | }) | ||
36 | |||
37 | static int (*rpm_get_suspend_cb(struct device *dev))(struct device *) | ||
38 | { | ||
39 | return RPM_GET_CALLBACK(dev, runtime_suspend); | ||
40 | } | ||
41 | |||
42 | static int (*rpm_get_resume_cb(struct device *dev))(struct device *) | ||
43 | { | ||
44 | return RPM_GET_CALLBACK(dev, runtime_resume); | ||
45 | } | ||
46 | |||
47 | static int (*rpm_get_idle_cb(struct device *dev))(struct device *) | ||
48 | { | ||
49 | return RPM_GET_CALLBACK(dev, runtime_idle); | ||
50 | } | ||
51 | |||
16 | static int rpm_resume(struct device *dev, int rpmflags); | 52 | static int rpm_resume(struct device *dev, int rpmflags); |
17 | static int rpm_suspend(struct device *dev, int rpmflags); | 53 | static int rpm_suspend(struct device *dev, int rpmflags); |
18 | 54 | ||
@@ -310,19 +346,7 @@ static int rpm_idle(struct device *dev, int rpmflags) | |||
310 | 346 | ||
311 | dev->power.idle_notification = true; | 347 | dev->power.idle_notification = true; |
312 | 348 | ||
313 | if (dev->pm_domain) | 349 | callback = rpm_get_idle_cb(dev); |
314 | callback = dev->pm_domain->ops.runtime_idle; | ||
315 | else if (dev->type && dev->type->pm) | ||
316 | callback = dev->type->pm->runtime_idle; | ||
317 | else if (dev->class && dev->class->pm) | ||
318 | callback = dev->class->pm->runtime_idle; | ||
319 | else if (dev->bus && dev->bus->pm) | ||
320 | callback = dev->bus->pm->runtime_idle; | ||
321 | else | ||
322 | callback = NULL; | ||
323 | |||
324 | if (!callback && dev->driver && dev->driver->pm) | ||
325 | callback = dev->driver->pm->runtime_idle; | ||
326 | 350 | ||
327 | if (callback) | 351 | if (callback) |
328 | retval = __rpm_callback(callback, dev); | 352 | retval = __rpm_callback(callback, dev); |
@@ -492,19 +516,7 @@ static int rpm_suspend(struct device *dev, int rpmflags) | |||
492 | 516 | ||
493 | __update_runtime_status(dev, RPM_SUSPENDING); | 517 | __update_runtime_status(dev, RPM_SUSPENDING); |
494 | 518 | ||
495 | if (dev->pm_domain) | 519 | callback = rpm_get_suspend_cb(dev); |
496 | callback = dev->pm_domain->ops.runtime_suspend; | ||
497 | else if (dev->type && dev->type->pm) | ||
498 | callback = dev->type->pm->runtime_suspend; | ||
499 | else if (dev->class && dev->class->pm) | ||
500 | callback = dev->class->pm->runtime_suspend; | ||
501 | else if (dev->bus && dev->bus->pm) | ||
502 | callback = dev->bus->pm->runtime_suspend; | ||
503 | else | ||
504 | callback = NULL; | ||
505 | |||
506 | if (!callback && dev->driver && dev->driver->pm) | ||
507 | callback = dev->driver->pm->runtime_suspend; | ||
508 | 520 | ||
509 | retval = rpm_callback(callback, dev); | 521 | retval = rpm_callback(callback, dev); |
510 | if (retval) | 522 | if (retval) |
@@ -724,19 +736,7 @@ static int rpm_resume(struct device *dev, int rpmflags) | |||
724 | 736 | ||
725 | __update_runtime_status(dev, RPM_RESUMING); | 737 | __update_runtime_status(dev, RPM_RESUMING); |
726 | 738 | ||
727 | if (dev->pm_domain) | 739 | callback = rpm_get_resume_cb(dev); |
728 | callback = dev->pm_domain->ops.runtime_resume; | ||
729 | else if (dev->type && dev->type->pm) | ||
730 | callback = dev->type->pm->runtime_resume; | ||
731 | else if (dev->class && dev->class->pm) | ||
732 | callback = dev->class->pm->runtime_resume; | ||
733 | else if (dev->bus && dev->bus->pm) | ||
734 | callback = dev->bus->pm->runtime_resume; | ||
735 | else | ||
736 | callback = NULL; | ||
737 | |||
738 | if (!callback && dev->driver && dev->driver->pm) | ||
739 | callback = dev->driver->pm->runtime_resume; | ||
740 | 740 | ||
741 | retval = rpm_callback(callback, dev); | 741 | retval = rpm_callback(callback, dev); |
742 | if (retval) { | 742 | if (retval) { |