Commit f8824cee405c62ba465b85365201166d9cf86a14

Authored by Rafael J. Wysocki
1 parent 97df8c1299

PM: Allow device drivers to use dpm_wait()

There are some dependencies between devices (in particular, between
EHCI USB controllers and their OHCI/UHCI siblings) which are not
reflected by the structure of the device tree.  With synchronous
suspend and resume these dependencies are taken into accout
automatically, because the devices in question are always registered
in the right order, but to meet these constraints with asynchronous
suspend and resume the drivers of these devices will need to use
dpm_wait() in their suspend/resume routines, so introduce a helper
function allowing them to do that.

Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>

Showing 2 changed files with 13 additions and 0 deletions Side-by-side Diff

drivers/base/power/main.c
... ... @@ -1046,4 +1046,15 @@
1046 1046 printk(KERN_ERR "%s(): %pF returns %d\n", function, fn, ret);
1047 1047 }
1048 1048 EXPORT_SYMBOL_GPL(__suspend_report_result);
  1049 +
  1050 +/**
  1051 + * device_pm_wait_for_dev - Wait for suspend/resume of a device to complete.
  1052 + * @dev: Device to wait for.
  1053 + * @subordinate: Device that needs to wait for @dev.
  1054 + */
  1055 +void device_pm_wait_for_dev(struct device *subordinate, struct device *dev)
  1056 +{
  1057 + dpm_wait(dev, subordinate->power.async_suspend);
  1058 +}
  1059 +EXPORT_SYMBOL_GPL(device_pm_wait_for_dev);
... ... @@ -512,6 +512,7 @@
512 512 __suspend_report_result(__func__, fn, ret); \
513 513 } while (0)
514 514  
  515 +extern void device_pm_wait_for_dev(struct device *sub, struct device *dev);
515 516 #else /* !CONFIG_PM_SLEEP */
516 517  
517 518 #define device_pm_lock() do {} while (0)
... ... @@ -524,6 +525,7 @@
524 525  
525 526 #define suspend_report_result(fn, ret) do {} while (0)
526 527  
  528 +static inline void device_pm_wait_for_dev(struct device *a, struct device *b) {}
527 529 #endif /* !CONFIG_PM_SLEEP */
528 530  
529 531 /* How to reorder dpm_list after device_move() */