diff options
author | Rafael J. Wysocki <rjw@sisk.pl> | 2009-08-18 17:38:32 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rjw@sisk.pl> | 2009-08-22 18:04:44 -0400 |
commit | 5e928f77a09a07f9dd595bb8a489965d69a83458 (patch) | |
tree | ef53ec90fa3214fd22e36b07c11c06b09e373d8d /drivers/base/power/main.c | |
parent | 8400146d0dc03590bba051399e4bb7e1cbf1c010 (diff) |
PM: Introduce core framework for run-time PM of I/O devices (rev. 17)
Introduce a core framework for run-time power management of I/O
devices. Add device run-time PM fields to 'struct dev_pm_info'
and device run-time PM callbacks to 'struct dev_pm_ops'. Introduce
a run-time PM workqueue and define some device run-time PM helper
functions at the core level. Document all these things.
Special thanks to Alan Stern for his help with the design and
multiple detailed reviews of the pereceding versions of this patch
and to Magnus Damm for testing feedback.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Magnus Damm <damm@igel.co.jp>
Diffstat (limited to 'drivers/base/power/main.c')
-rw-r--r-- | drivers/base/power/main.c | 22 |
1 files changed, 21 insertions, 1 deletions
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index 1b1a786b7dec..86990011277b 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/kallsyms.h> | 21 | #include <linux/kallsyms.h> |
22 | #include <linux/mutex.h> | 22 | #include <linux/mutex.h> |
23 | #include <linux/pm.h> | 23 | #include <linux/pm.h> |
24 | #include <linux/pm_runtime.h> | ||
24 | #include <linux/resume-trace.h> | 25 | #include <linux/resume-trace.h> |
25 | #include <linux/rwsem.h> | 26 | #include <linux/rwsem.h> |
26 | #include <linux/interrupt.h> | 27 | #include <linux/interrupt.h> |
@@ -49,6 +50,16 @@ static DEFINE_MUTEX(dpm_list_mtx); | |||
49 | static bool transition_started; | 50 | static bool transition_started; |
50 | 51 | ||
51 | /** | 52 | /** |
53 | * device_pm_init - Initialize the PM-related part of a device object | ||
54 | * @dev: Device object being initialized. | ||
55 | */ | ||
56 | void device_pm_init(struct device *dev) | ||
57 | { | ||
58 | dev->power.status = DPM_ON; | ||
59 | pm_runtime_init(dev); | ||
60 | } | ||
61 | |||
62 | /** | ||
52 | * device_pm_lock - lock the list of active devices used by the PM core | 63 | * device_pm_lock - lock the list of active devices used by the PM core |
53 | */ | 64 | */ |
54 | void device_pm_lock(void) | 65 | void device_pm_lock(void) |
@@ -105,6 +116,7 @@ void device_pm_remove(struct device *dev) | |||
105 | mutex_lock(&dpm_list_mtx); | 116 | mutex_lock(&dpm_list_mtx); |
106 | list_del_init(&dev->power.entry); | 117 | list_del_init(&dev->power.entry); |
107 | mutex_unlock(&dpm_list_mtx); | 118 | mutex_unlock(&dpm_list_mtx); |
119 | pm_runtime_remove(dev); | ||
108 | } | 120 | } |
109 | 121 | ||
110 | /** | 122 | /** |
@@ -512,6 +524,7 @@ static void dpm_complete(pm_message_t state) | |||
512 | mutex_unlock(&dpm_list_mtx); | 524 | mutex_unlock(&dpm_list_mtx); |
513 | 525 | ||
514 | device_complete(dev, state); | 526 | device_complete(dev, state); |
527 | pm_runtime_put_noidle(dev); | ||
515 | 528 | ||
516 | mutex_lock(&dpm_list_mtx); | 529 | mutex_lock(&dpm_list_mtx); |
517 | } | 530 | } |
@@ -757,7 +770,14 @@ static int dpm_prepare(pm_message_t state) | |||
757 | dev->power.status = DPM_PREPARING; | 770 | dev->power.status = DPM_PREPARING; |
758 | mutex_unlock(&dpm_list_mtx); | 771 | mutex_unlock(&dpm_list_mtx); |
759 | 772 | ||
760 | error = device_prepare(dev, state); | 773 | pm_runtime_get_noresume(dev); |
774 | if (pm_runtime_barrier(dev) && device_may_wakeup(dev)) { | ||
775 | /* Wake-up requested during system sleep transition. */ | ||
776 | pm_runtime_put_noidle(dev); | ||
777 | error = -EBUSY; | ||
778 | } else { | ||
779 | error = device_prepare(dev, state); | ||
780 | } | ||
761 | 781 | ||
762 | mutex_lock(&dpm_list_mtx); | 782 | mutex_lock(&dpm_list_mtx); |
763 | if (error) { | 783 | if (error) { |