aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/base/dd.c14
-rw-r--r--include/linux/pm.h8
2 files changed, 22 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,
diff --git a/include/linux/pm.h b/include/linux/pm.h
index e2f1be6dd9dd..2d29c64f8fb1 100644
--- a/include/linux/pm.h
+++ b/include/linux/pm.h
@@ -603,10 +603,18 @@ extern void dev_pm_put_subsys_data(struct device *dev);
603 * Power domains provide callbacks that are executed during system suspend, 603 * Power domains provide callbacks that are executed during system suspend,
604 * hibernation, system resume and during runtime PM transitions along with 604 * hibernation, system resume and during runtime PM transitions along with
605 * subsystem-level and driver-level callbacks. 605 * subsystem-level and driver-level callbacks.
606 *
607 * @detach: Called when removing a device from the domain.
608 * @activate: Called before executing probe routines for bus types and drivers.
609 * @sync: Called after successful driver probe.
610 * @dismiss: Called after unsuccessful driver probe and after driver removal.
606 */ 611 */
607struct dev_pm_domain { 612struct dev_pm_domain {
608 struct dev_pm_ops ops; 613 struct dev_pm_ops ops;
609 void (*detach)(struct device *dev, bool power_off); 614 void (*detach)(struct device *dev, bool power_off);
615 int (*activate)(struct device *dev);
616 void (*sync)(struct device *dev);
617 void (*dismiss)(struct device *dev);
610}; 618};
611 619
612/* 620/*