aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/power/runtime.c
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@sisk.pl>2011-02-16 15:53:17 -0500
committerRafael J. Wysocki <rjw@sisk.pl>2011-03-14 19:43:16 -0400
commit7538e3db6e015e890825fbd9f8659952896ddd5b (patch)
tree01a6d8c97599474d9c5fc1ed0eb6f0addaec5652 /drivers/base/power/runtime.c
parent6831c6edc7b272a08dd2a6c71bb183a48fe98ae6 (diff)
PM: Add support for device power domains
The platform bus type is often used to handle Systems-on-a-Chip (SoC) where all devices are represented by objects of type struct platform_device. In those cases the same "platform" device driver may be used with multiple different system configurations, but the actions needed to put the devices it handles into a low-power state and back into the full-power state may depend on the design of the given SoC. The driver, however, cannot possibly include all the information necessary for the power management of its device on all the systems it is used with. Moreover, the device hierarchy in its current form also is not suitable for representing this kind of information. The patch below attempts to address this problem by introducing objects of type struct dev_power_domain that can be used for representing power domains within a SoC. Every struct dev_power_domain object provides a sets of device power management callbacks that can be used to perform what's needed for device power management in addition to the operations carried out by the device's driver and subsystem. Namely, if a struct dev_power_domain object is pointed to by the pwr_domain field in a struct device, the callbacks provided by its ops member will be executed in addition to the corresponding callbacks provided by the device's subsystem and driver during all power transitions. Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl> Tested-and-acked-by: Kevin Hilman <khilman@ti.com>
Diffstat (limited to 'drivers/base/power/runtime.c')
-rw-r--r--drivers/base/power/runtime.c19
1 files changed, 17 insertions, 2 deletions
diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
index 42615b419dfb..25edc9a3a489 100644
--- a/drivers/base/power/runtime.c
+++ b/drivers/base/power/runtime.c
@@ -168,6 +168,7 @@ static int rpm_check_suspend_allowed(struct device *dev)
168static int rpm_idle(struct device *dev, int rpmflags) 168static int rpm_idle(struct device *dev, int rpmflags)
169{ 169{
170 int (*callback)(struct device *); 170 int (*callback)(struct device *);
171 int (*domain_callback)(struct device *);
171 int retval; 172 int retval;
172 173
173 retval = rpm_check_suspend_allowed(dev); 174 retval = rpm_check_suspend_allowed(dev);
@@ -222,10 +223,19 @@ static int rpm_idle(struct device *dev, int rpmflags)
222 else 223 else
223 callback = NULL; 224 callback = NULL;
224 225
225 if (callback) { 226 if (dev->pwr_domain)
227 domain_callback = dev->pwr_domain->ops.runtime_idle;
228 else
229 domain_callback = NULL;
230
231 if (callback || domain_callback) {
226 spin_unlock_irq(&dev->power.lock); 232 spin_unlock_irq(&dev->power.lock);
227 233
228 callback(dev); 234 if (domain_callback)
235 retval = domain_callback(dev);
236
237 if (!retval && callback)
238 callback(dev);
229 239
230 spin_lock_irq(&dev->power.lock); 240 spin_lock_irq(&dev->power.lock);
231 } 241 }
@@ -390,6 +400,8 @@ static int rpm_suspend(struct device *dev, int rpmflags)
390 else 400 else
391 pm_runtime_cancel_pending(dev); 401 pm_runtime_cancel_pending(dev);
392 } else { 402 } else {
403 if (dev->pwr_domain)
404 rpm_callback(dev->pwr_domain->ops.runtime_suspend, dev);
393 no_callback: 405 no_callback:
394 __update_runtime_status(dev, RPM_SUSPENDED); 406 __update_runtime_status(dev, RPM_SUSPENDED);
395 pm_runtime_deactivate_timer(dev); 407 pm_runtime_deactivate_timer(dev);
@@ -569,6 +581,9 @@ static int rpm_resume(struct device *dev, int rpmflags)
569 581
570 __update_runtime_status(dev, RPM_RESUMING); 582 __update_runtime_status(dev, RPM_RESUMING);
571 583
584 if (dev->pwr_domain)
585 rpm_callback(dev->pwr_domain->ops.runtime_resume, dev);
586
572 if (dev->bus && dev->bus->pm && dev->bus->pm->runtime_resume) 587 if (dev->bus && dev->bus->pm && dev->bus->pm->runtime_resume)
573 callback = dev->bus->pm->runtime_resume; 588 callback = dev->bus->pm->runtime_resume;
574 else if (dev->type && dev->type->pm && dev->type->pm->runtime_resume) 589 else if (dev->type && dev->type->pm && dev->type->pm->runtime_resume)