PM: Allow device drivers to use dpm_wait()
authorRafael J. Wysocki <rjw@sisk.pl>
Wed, 27 Jan 2010 22:47:38 +0000 (23:47 +0100)
committerRafael J. Wysocki <rjw@sisk.pl>
Fri, 26 Feb 2010 19:39:11 +0000 (20:39 +0100)
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>
drivers/base/power/main.c
include/linux/pm.h

index 6efef9fb23a1f166e3d98900c1f5393044ae6584..0e26a6f6fd48193e5c5fd3cec6a20269a4a5ddc9 100644 (file)
@@ -1046,3 +1046,14 @@ void __suspend_report_result(const char *function, void *fn, int ret)
                printk(KERN_ERR "%s(): %pF returns %d\n", function, fn, ret);
 }
 EXPORT_SYMBOL_GPL(__suspend_report_result);
+
+/**
+ * device_pm_wait_for_dev - Wait for suspend/resume of a device to complete.
+ * @dev: Device to wait for.
+ * @subordinate: Device that needs to wait for @dev.
+ */
+void device_pm_wait_for_dev(struct device *subordinate, struct device *dev)
+{
+       dpm_wait(dev, subordinate->power.async_suspend);
+}
+EXPORT_SYMBOL_GPL(device_pm_wait_for_dev);
index 9c16cd20fc96d644be02b7eac7845345ce26c865..e80df06ad22ab1aaa7d86a76434a4a5b9a2aadf8 100644 (file)
@@ -512,6 +512,7 @@ extern void __suspend_report_result(const char *function, void *fn, int ret);
                __suspend_report_result(__func__, fn, ret);             \
        } while (0)
 
+extern void device_pm_wait_for_dev(struct device *sub, struct device *dev);
 #else /* !CONFIG_PM_SLEEP */
 
 #define device_pm_lock() do {} while (0)
@@ -524,6 +525,7 @@ static inline int dpm_suspend_start(pm_message_t state)
 
 #define suspend_report_result(fn, ret)         do {} while (0)
 
+static inline void device_pm_wait_for_dev(struct device *a, struct device *b) {}
 #endif /* !CONFIG_PM_SLEEP */
 
 /* How to reorder dpm_list after device_move() */