diff options
-rw-r--r-- | drivers/base/dd.c | 14 | ||||
-rw-r--r-- | include/linux/pm.h | 8 |
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 | */ |
607 | struct dev_pm_domain { | 612 | struct 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 | /* |