aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/dd.c
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2015-03-20 08:59:27 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2015-03-22 17:14:12 -0400
commite90d5532773e2bcccc538dd346b9fc3482cd700c (patch)
tree84ee8ca4022e8538f871cd89a5ee43bf21338fc7 /drivers/base/dd.c
parenteea97aed815ac25b9435a556fce345d257f47405 (diff)
driver core / PM: Add PM domain callbacks for device setup/cleanup
If PM domains are in use, it may be necessary to prepare the code handling a PM domain for driver probing. For example, in some cases device drivers rely on the ability to power on the devices with the help of the IO runtime PM framework and the PM domain code needs to be ready for that. Also, if that code has not been fully initialized yet, the driver probing should be deferred. Moreover, after the probing is complete, it may be necessary to put the PM domain in question into the state reflecting the current needs of the devices in it, for example, so that power is not drawn in vain. The same should be done after removing a driver from a device, as the PM domain state may need to be changed to reflect the new situation. For these reasons, introduce new PM domain callbacks, ->activate, ->sync and ->dismiss called, respectively, before probing for a device driver, after the probing has completed successfully and if the probing has failed or the driver has been removed. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Acked-by: Ulf Hansson <ulf.hansson@linaro.org> Reviewed-by: Kevin Hilman <khilman@linaro.org> Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/base/dd.c')
-rw-r--r--drivers/base/dd.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index cdc779cf79a3..aeb744891e44 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -298,6 +298,12 @@ static int really_probe(struct device *dev, struct device_driver *drv)
298 goto probe_failed; 298 goto probe_failed;
299 } 299 }
300 300
301 if (dev->pm_domain && dev->pm_domain->activate) {
302 ret = dev->pm_domain->activate(dev);
303 if (ret)
304 goto probe_failed;
305 }
306
301 if (dev->bus->probe) { 307 if (dev->bus->probe) {
302 ret = dev->bus->probe(dev); 308 ret = dev->bus->probe(dev);
303 if (ret) 309 if (ret)
@@ -308,6 +314,9 @@ static int really_probe(struct device *dev, struct device_driver *drv)
308 goto probe_failed; 314 goto probe_failed;
309 } 315 }
310 316
317 if (dev->pm_domain && dev->pm_domain->sync)
318 dev->pm_domain->sync(dev);
319
311 driver_bound(dev); 320 driver_bound(dev);
312 ret = 1; 321 ret = 1;
313 pr_debug("bus: '%s': %s: bound device %s to driver %s\n", 322 pr_debug("bus: '%s': %s: bound device %s to driver %s\n",
@@ -319,6 +328,8 @@ probe_failed:
319 driver_sysfs_remove(dev); 328 driver_sysfs_remove(dev);
320 dev->driver = NULL; 329 dev->driver = NULL;
321 dev_set_drvdata(dev, NULL); 330 dev_set_drvdata(dev, NULL);
331 if (dev->pm_domain && dev->pm_domain->dismiss)
332 dev->pm_domain->dismiss(dev);
322 333
323 if (ret == -EPROBE_DEFER) { 334 if (ret == -EPROBE_DEFER) {
324 /* Driver requested deferred probing */ 335 /* Driver requested deferred probing */
@@ -525,6 +536,9 @@ static void __device_release_driver(struct device *dev)
525 devres_release_all(dev); 536 devres_release_all(dev);
526 dev->driver = NULL; 537 dev->driver = NULL;
527 dev_set_drvdata(dev, NULL); 538 dev_set_drvdata(dev, NULL);
539 if (dev->pm_domain && dev->pm_domain->dismiss)
540 dev->pm_domain->dismiss(dev);
541
528 klist_remove(&dev->p->knode_driver); 542 klist_remove(&dev->p->knode_driver);
529 if (dev->bus) 543 if (dev->bus)
530 blocking_notifier_call_chain(&dev->bus->p->bus_notifier, 544 blocking_notifier_call_chain(&dev->bus->p->bus_notifier,