aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-11-26 19:37:53 -0500
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-11-26 19:37:53 -0500
commitaf261127e94c286c08bba162711307863fd4e68c (patch)
treed6dda7ab34c353a5d42653531b99fc30dd41721e /drivers/base
parent5d01410fe4d92081f349b013a2e7a95429e4f2c9 (diff)
parentb2b49ccbdd547135c69371ed066cffa44912060a (diff)
Merge back earlier 'pm-runtime' material for 3.19-rc1.
Diffstat (limited to 'drivers/base')
-rw-r--r--drivers/base/power/runtime.c69
1 files changed, 33 insertions, 36 deletions
diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
index 67c7938e430b..8f1ab8446caa 100644
--- a/drivers/base/power/runtime.c
+++ b/drivers/base/power/runtime.c
@@ -13,42 +13,39 @@
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) \ 16typedef int (*pm_callback_t)(struct device *);
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
37static int (*rpm_get_suspend_cb(struct device *dev))(struct device *)
38{
39 return RPM_GET_CALLBACK(dev, runtime_suspend);
40}
41 17
42static int (*rpm_get_resume_cb(struct device *dev))(struct device *) 18static pm_callback_t __rpm_get_callback(struct device *dev, size_t cb_offset)
43{ 19{
44 return RPM_GET_CALLBACK(dev, runtime_resume); 20 pm_callback_t cb;
21 const struct dev_pm_ops *ops;
22
23 if (dev->pm_domain)
24 ops = &dev->pm_domain->ops;
25 else if (dev->type && dev->type->pm)
26 ops = dev->type->pm;
27 else if (dev->class && dev->class->pm)
28 ops = dev->class->pm;
29 else if (dev->bus && dev->bus->pm)
30 ops = dev->bus->pm;
31 else
32 ops = NULL;
33
34 if (ops)
35 cb = *(pm_callback_t *)((void *)ops + cb_offset);
36 else
37 cb = NULL;
38
39 if (!cb && dev->driver && dev->driver->pm)
40 cb = *(pm_callback_t *)((void *)dev->driver->pm + cb_offset);
41
42 return cb;
45} 43}
46 44
45#define RPM_GET_CALLBACK(dev, callback) \
46 __rpm_get_callback(dev, offsetof(struct dev_pm_ops, callback))
47
47#ifdef CONFIG_PM_RUNTIME 48#ifdef CONFIG_PM_RUNTIME
48static int (*rpm_get_idle_cb(struct device *dev))(struct device *)
49{
50 return RPM_GET_CALLBACK(dev, runtime_idle);
51}
52 49
53static int rpm_resume(struct device *dev, int rpmflags); 50static int rpm_resume(struct device *dev, int rpmflags);
54static int rpm_suspend(struct device *dev, int rpmflags); 51static int rpm_suspend(struct device *dev, int rpmflags);
@@ -347,7 +344,7 @@ static int rpm_idle(struct device *dev, int rpmflags)
347 344
348 dev->power.idle_notification = true; 345 dev->power.idle_notification = true;
349 346
350 callback = rpm_get_idle_cb(dev); 347 callback = RPM_GET_CALLBACK(dev, runtime_idle);
351 348
352 if (callback) 349 if (callback)
353 retval = __rpm_callback(callback, dev); 350 retval = __rpm_callback(callback, dev);
@@ -517,7 +514,7 @@ static int rpm_suspend(struct device *dev, int rpmflags)
517 514
518 __update_runtime_status(dev, RPM_SUSPENDING); 515 __update_runtime_status(dev, RPM_SUSPENDING);
519 516
520 callback = rpm_get_suspend_cb(dev); 517 callback = RPM_GET_CALLBACK(dev, runtime_suspend);
521 518
522 retval = rpm_callback(callback, dev); 519 retval = rpm_callback(callback, dev);
523 if (retval) 520 if (retval)
@@ -737,7 +734,7 @@ static int rpm_resume(struct device *dev, int rpmflags)
737 734
738 __update_runtime_status(dev, RPM_RESUMING); 735 __update_runtime_status(dev, RPM_RESUMING);
739 736
740 callback = rpm_get_resume_cb(dev); 737 callback = RPM_GET_CALLBACK(dev, runtime_resume);
741 738
742 retval = rpm_callback(callback, dev); 739 retval = rpm_callback(callback, dev);
743 if (retval) { 740 if (retval) {
@@ -1431,7 +1428,7 @@ int pm_runtime_force_suspend(struct device *dev)
1431 if (pm_runtime_status_suspended(dev)) 1428 if (pm_runtime_status_suspended(dev))
1432 return 0; 1429 return 0;
1433 1430
1434 callback = rpm_get_suspend_cb(dev); 1431 callback = RPM_GET_CALLBACK(dev, runtime_suspend);
1435 1432
1436 if (!callback) { 1433 if (!callback) {
1437 ret = -ENOSYS; 1434 ret = -ENOSYS;
@@ -1467,7 +1464,7 @@ int pm_runtime_force_resume(struct device *dev)
1467 int (*callback)(struct device *); 1464 int (*callback)(struct device *);
1468 int ret = 0; 1465 int ret = 0;
1469 1466
1470 callback = rpm_get_resume_cb(dev); 1467 callback = RPM_GET_CALLBACK(dev, runtime_resume);
1471 1468
1472 if (!callback) { 1469 if (!callback) {
1473 ret = -ENOSYS; 1470 ret = -ENOSYS;