aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-08-04 14:14:36 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-08-04 14:14:36 -0400
commitf46e9913faeebcb6bd29edf795f12b60acbff171 (patch)
tree1ed8871d0ebd638094d27317de1d8a53712ae15a /drivers
parent8d91530c5fd7f0b1e8c4ddfea2905e55a178569b (diff)
parent8d4b9d1bfef117862a2889dec4dac227068544c9 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/suspend-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/suspend-2.6: PM / Runtime: Add runtime PM statistics (v3) PM / Runtime: Make runtime_status attribute not debug-only (v. 2) PM: Do not use dynamically allocated objects in pm_wakeup_event() PM / Suspend: Fix ordering of calls in suspend error paths PM / Hibernate: Fix snapshot error code path PM / Hibernate: Fix hibernation_platform_enter() pm_qos: Get rid of the allocation in pm_qos_add_request() pm_qos: Reimplement using plists plist: Add plist_last PM: Make it possible to avoid races between wakeup and system sleep PNPACPI: Add support for remote wakeup PM: describe kernel policy regarding wakeup defaults (v. 2) PM / Hibernate: Fix typos in comments in kernel/power/swap.c
Diffstat (limited to 'drivers')
-rw-r--r--drivers/base/power/Makefile2
-rw-r--r--drivers/base/power/main.c1
-rw-r--r--drivers/base/power/runtime.c54
-rw-r--r--drivers/base/power/sysfs.c98
-rw-r--r--drivers/base/power/wakeup.c247
-rw-r--r--drivers/net/e1000e/netdev.c17
-rw-r--r--drivers/net/igbvf/netdev.c9
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2100.c12
-rw-r--r--drivers/pci/pci-acpi.c1
-rw-r--r--drivers/pci/pci.c20
-rw-r--r--drivers/pci/pci.h1
-rw-r--r--drivers/pci/pcie/pme/pcie_pme.c5
-rw-r--r--drivers/pnp/core.c3
-rw-r--r--drivers/pnp/pnpacpi/core.c23
14 files changed, 442 insertions, 51 deletions
diff --git a/drivers/base/power/Makefile b/drivers/base/power/Makefile
index 89de75325cea..cbccf9a3cee4 100644
--- a/drivers/base/power/Makefile
+++ b/drivers/base/power/Makefile
@@ -1,5 +1,5 @@
1obj-$(CONFIG_PM) += sysfs.o 1obj-$(CONFIG_PM) += sysfs.o
2obj-$(CONFIG_PM_SLEEP) += main.o 2obj-$(CONFIG_PM_SLEEP) += main.o wakeup.o
3obj-$(CONFIG_PM_RUNTIME) += runtime.o 3obj-$(CONFIG_PM_RUNTIME) += runtime.o
4obj-$(CONFIG_PM_OPS) += generic_ops.o 4obj-$(CONFIG_PM_OPS) += generic_ops.o
5obj-$(CONFIG_PM_TRACE_RTC) += trace.o 5obj-$(CONFIG_PM_TRACE_RTC) += trace.o
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index 941fcb87e52a..5419a49ff135 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -59,6 +59,7 @@ void device_pm_init(struct device *dev)
59{ 59{
60 dev->power.status = DPM_ON; 60 dev->power.status = DPM_ON;
61 init_completion(&dev->power.completion); 61 init_completion(&dev->power.completion);
62 dev->power.wakeup_count = 0;
62 pm_runtime_init(dev); 63 pm_runtime_init(dev);
63} 64}
64 65
diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
index b0ec0e9f27e9..b78c401ffa73 100644
--- a/drivers/base/power/runtime.c
+++ b/drivers/base/power/runtime.c
@@ -123,6 +123,45 @@ int pm_runtime_idle(struct device *dev)
123} 123}
124EXPORT_SYMBOL_GPL(pm_runtime_idle); 124EXPORT_SYMBOL_GPL(pm_runtime_idle);
125 125
126
127/**
128 * update_pm_runtime_accounting - Update the time accounting of power states
129 * @dev: Device to update the accounting for
130 *
131 * In order to be able to have time accounting of the various power states
132 * (as used by programs such as PowerTOP to show the effectiveness of runtime
133 * PM), we need to track the time spent in each state.
134 * update_pm_runtime_accounting must be called each time before the
135 * runtime_status field is updated, to account the time in the old state
136 * correctly.
137 */
138void update_pm_runtime_accounting(struct device *dev)
139{
140 unsigned long now = jiffies;
141 int delta;
142
143 delta = now - dev->power.accounting_timestamp;
144
145 if (delta < 0)
146 delta = 0;
147
148 dev->power.accounting_timestamp = now;
149
150 if (dev->power.disable_depth > 0)
151 return;
152
153 if (dev->power.runtime_status == RPM_SUSPENDED)
154 dev->power.suspended_jiffies += delta;
155 else
156 dev->power.active_jiffies += delta;
157}
158
159static void __update_runtime_status(struct device *dev, enum rpm_status status)
160{
161 update_pm_runtime_accounting(dev);
162 dev->power.runtime_status = status;
163}
164
126/** 165/**
127 * __pm_runtime_suspend - Carry out run-time suspend of given device. 166 * __pm_runtime_suspend - Carry out run-time suspend of given device.
128 * @dev: Device to suspend. 167 * @dev: Device to suspend.
@@ -197,7 +236,7 @@ int __pm_runtime_suspend(struct device *dev, bool from_wq)
197 goto repeat; 236 goto repeat;
198 } 237 }
199 238
200 dev->power.runtime_status = RPM_SUSPENDING; 239 __update_runtime_status(dev, RPM_SUSPENDING);
201 dev->power.deferred_resume = false; 240 dev->power.deferred_resume = false;
202 241
203 if (dev->bus && dev->bus->pm && dev->bus->pm->runtime_suspend) { 242 if (dev->bus && dev->bus->pm && dev->bus->pm->runtime_suspend) {
@@ -228,7 +267,7 @@ int __pm_runtime_suspend(struct device *dev, bool from_wq)
228 } 267 }
229 268
230 if (retval) { 269 if (retval) {
231 dev->power.runtime_status = RPM_ACTIVE; 270 __update_runtime_status(dev, RPM_ACTIVE);
232 if (retval == -EAGAIN || retval == -EBUSY) { 271 if (retval == -EAGAIN || retval == -EBUSY) {
233 if (dev->power.timer_expires == 0) 272 if (dev->power.timer_expires == 0)
234 notify = true; 273 notify = true;
@@ -237,7 +276,7 @@ int __pm_runtime_suspend(struct device *dev, bool from_wq)
237 pm_runtime_cancel_pending(dev); 276 pm_runtime_cancel_pending(dev);
238 } 277 }
239 } else { 278 } else {
240 dev->power.runtime_status = RPM_SUSPENDED; 279 __update_runtime_status(dev, RPM_SUSPENDED);
241 pm_runtime_deactivate_timer(dev); 280 pm_runtime_deactivate_timer(dev);
242 281
243 if (dev->parent) { 282 if (dev->parent) {
@@ -381,7 +420,7 @@ int __pm_runtime_resume(struct device *dev, bool from_wq)
381 goto repeat; 420 goto repeat;
382 } 421 }
383 422
384 dev->power.runtime_status = RPM_RESUMING; 423 __update_runtime_status(dev, RPM_RESUMING);
385 424
386 if (dev->bus && dev->bus->pm && dev->bus->pm->runtime_resume) { 425 if (dev->bus && dev->bus->pm && dev->bus->pm->runtime_resume) {
387 spin_unlock_irq(&dev->power.lock); 426 spin_unlock_irq(&dev->power.lock);
@@ -411,10 +450,10 @@ int __pm_runtime_resume(struct device *dev, bool from_wq)
411 } 450 }
412 451
413 if (retval) { 452 if (retval) {
414 dev->power.runtime_status = RPM_SUSPENDED; 453 __update_runtime_status(dev, RPM_SUSPENDED);
415 pm_runtime_cancel_pending(dev); 454 pm_runtime_cancel_pending(dev);
416 } else { 455 } else {
417 dev->power.runtime_status = RPM_ACTIVE; 456 __update_runtime_status(dev, RPM_ACTIVE);
418 if (parent) 457 if (parent)
419 atomic_inc(&parent->power.child_count); 458 atomic_inc(&parent->power.child_count);
420 } 459 }
@@ -848,7 +887,7 @@ int __pm_runtime_set_status(struct device *dev, unsigned int status)
848 } 887 }
849 888
850 out_set: 889 out_set:
851 dev->power.runtime_status = status; 890 __update_runtime_status(dev, status);
852 dev->power.runtime_error = 0; 891 dev->power.runtime_error = 0;
853 out: 892 out:
854 spin_unlock_irqrestore(&dev->power.lock, flags); 893 spin_unlock_irqrestore(&dev->power.lock, flags);
@@ -1077,6 +1116,7 @@ void pm_runtime_init(struct device *dev)
1077 dev->power.request_pending = false; 1116 dev->power.request_pending = false;
1078 dev->power.request = RPM_REQ_NONE; 1117 dev->power.request = RPM_REQ_NONE;
1079 dev->power.deferred_resume = false; 1118 dev->power.deferred_resume = false;
1119 dev->power.accounting_timestamp = jiffies;
1080 INIT_WORK(&dev->power.work, pm_runtime_work); 1120 INIT_WORK(&dev->power.work, pm_runtime_work);
1081 1121
1082 dev->power.timer_expires = 0; 1122 dev->power.timer_expires = 0;
diff --git a/drivers/base/power/sysfs.c b/drivers/base/power/sysfs.c
index a4c33bc51257..e56b4388fe61 100644
--- a/drivers/base/power/sysfs.c
+++ b/drivers/base/power/sysfs.c
@@ -6,6 +6,7 @@
6#include <linux/string.h> 6#include <linux/string.h>
7#include <linux/pm_runtime.h> 7#include <linux/pm_runtime.h>
8#include <asm/atomic.h> 8#include <asm/atomic.h>
9#include <linux/jiffies.h>
9#include "power.h" 10#include "power.h"
10 11
11/* 12/*
@@ -73,6 +74,8 @@
73 * device are known to the PM core. However, for some devices this 74 * device are known to the PM core. However, for some devices this
74 * attribute is set to "enabled" by bus type code or device drivers and in 75 * attribute is set to "enabled" by bus type code or device drivers and in
75 * that cases it should be safe to leave the default value. 76 * that cases it should be safe to leave the default value.
77 *
78 * wakeup_count - Report the number of wakeup events related to the device
76 */ 79 */
77 80
78static const char enabled[] = "enabled"; 81static const char enabled[] = "enabled";
@@ -108,6 +111,65 @@ static ssize_t control_store(struct device * dev, struct device_attribute *attr,
108} 111}
109 112
110static DEVICE_ATTR(control, 0644, control_show, control_store); 113static DEVICE_ATTR(control, 0644, control_show, control_store);
114
115static ssize_t rtpm_active_time_show(struct device *dev,
116 struct device_attribute *attr, char *buf)
117{
118 int ret;
119 spin_lock_irq(&dev->power.lock);
120 update_pm_runtime_accounting(dev);
121 ret = sprintf(buf, "%i\n", jiffies_to_msecs(dev->power.active_jiffies));
122 spin_unlock_irq(&dev->power.lock);
123 return ret;
124}
125
126static DEVICE_ATTR(runtime_active_time, 0444, rtpm_active_time_show, NULL);
127
128static ssize_t rtpm_suspended_time_show(struct device *dev,
129 struct device_attribute *attr, char *buf)
130{
131 int ret;
132 spin_lock_irq(&dev->power.lock);
133 update_pm_runtime_accounting(dev);
134 ret = sprintf(buf, "%i\n",
135 jiffies_to_msecs(dev->power.suspended_jiffies));
136 spin_unlock_irq(&dev->power.lock);
137 return ret;
138}
139
140static DEVICE_ATTR(runtime_suspended_time, 0444, rtpm_suspended_time_show, NULL);
141
142static ssize_t rtpm_status_show(struct device *dev,
143 struct device_attribute *attr, char *buf)
144{
145 const char *p;
146
147 if (dev->power.runtime_error) {
148 p = "error\n";
149 } else if (dev->power.disable_depth) {
150 p = "unsupported\n";
151 } else {
152 switch (dev->power.runtime_status) {
153 case RPM_SUSPENDED:
154 p = "suspended\n";
155 break;
156 case RPM_SUSPENDING:
157 p = "suspending\n";
158 break;
159 case RPM_RESUMING:
160 p = "resuming\n";
161 break;
162 case RPM_ACTIVE:
163 p = "active\n";
164 break;
165 default:
166 return -EIO;
167 }
168 }
169 return sprintf(buf, p);
170}
171
172static DEVICE_ATTR(runtime_status, 0444, rtpm_status_show, NULL);
111#endif 173#endif
112 174
113static ssize_t 175static ssize_t
@@ -144,6 +206,16 @@ wake_store(struct device * dev, struct device_attribute *attr,
144 206
145static DEVICE_ATTR(wakeup, 0644, wake_show, wake_store); 207static DEVICE_ATTR(wakeup, 0644, wake_show, wake_store);
146 208
209#ifdef CONFIG_PM_SLEEP
210static ssize_t wakeup_count_show(struct device *dev,
211 struct device_attribute *attr, char *buf)
212{
213 return sprintf(buf, "%lu\n", dev->power.wakeup_count);
214}
215
216static DEVICE_ATTR(wakeup_count, 0444, wakeup_count_show, NULL);
217#endif
218
147#ifdef CONFIG_PM_ADVANCED_DEBUG 219#ifdef CONFIG_PM_ADVANCED_DEBUG
148#ifdef CONFIG_PM_RUNTIME 220#ifdef CONFIG_PM_RUNTIME
149 221
@@ -172,27 +244,8 @@ static ssize_t rtpm_enabled_show(struct device *dev,
172 return sprintf(buf, "enabled\n"); 244 return sprintf(buf, "enabled\n");
173} 245}
174 246
175static ssize_t rtpm_status_show(struct device *dev,
176 struct device_attribute *attr, char *buf)
177{
178 if (dev->power.runtime_error)
179 return sprintf(buf, "error\n");
180 switch (dev->power.runtime_status) {
181 case RPM_SUSPENDED:
182 return sprintf(buf, "suspended\n");
183 case RPM_SUSPENDING:
184 return sprintf(buf, "suspending\n");
185 case RPM_RESUMING:
186 return sprintf(buf, "resuming\n");
187 case RPM_ACTIVE:
188 return sprintf(buf, "active\n");
189 }
190 return -EIO;
191}
192
193static DEVICE_ATTR(runtime_usage, 0444, rtpm_usagecount_show, NULL); 247static DEVICE_ATTR(runtime_usage, 0444, rtpm_usagecount_show, NULL);
194static DEVICE_ATTR(runtime_active_kids, 0444, rtpm_children_show, NULL); 248static DEVICE_ATTR(runtime_active_kids, 0444, rtpm_children_show, NULL);
195static DEVICE_ATTR(runtime_status, 0444, rtpm_status_show, NULL);
196static DEVICE_ATTR(runtime_enabled, 0444, rtpm_enabled_show, NULL); 249static DEVICE_ATTR(runtime_enabled, 0444, rtpm_enabled_show, NULL);
197 250
198#endif 251#endif
@@ -228,14 +281,19 @@ static DEVICE_ATTR(async, 0644, async_show, async_store);
228static struct attribute * power_attrs[] = { 281static struct attribute * power_attrs[] = {
229#ifdef CONFIG_PM_RUNTIME 282#ifdef CONFIG_PM_RUNTIME
230 &dev_attr_control.attr, 283 &dev_attr_control.attr,
284 &dev_attr_runtime_status.attr,
285 &dev_attr_runtime_suspended_time.attr,
286 &dev_attr_runtime_active_time.attr,
231#endif 287#endif
232 &dev_attr_wakeup.attr, 288 &dev_attr_wakeup.attr,
289#ifdef CONFIG_PM_SLEEP
290 &dev_attr_wakeup_count.attr,
291#endif
233#ifdef CONFIG_PM_ADVANCED_DEBUG 292#ifdef CONFIG_PM_ADVANCED_DEBUG
234 &dev_attr_async.attr, 293 &dev_attr_async.attr,
235#ifdef CONFIG_PM_RUNTIME 294#ifdef CONFIG_PM_RUNTIME
236 &dev_attr_runtime_usage.attr, 295 &dev_attr_runtime_usage.attr,
237 &dev_attr_runtime_active_kids.attr, 296 &dev_attr_runtime_active_kids.attr,
238 &dev_attr_runtime_status.attr,
239 &dev_attr_runtime_enabled.attr, 297 &dev_attr_runtime_enabled.attr,
240#endif 298#endif
241#endif 299#endif
diff --git a/drivers/base/power/wakeup.c b/drivers/base/power/wakeup.c
new file mode 100644
index 000000000000..eb594facfc3f
--- /dev/null
+++ b/drivers/base/power/wakeup.c
@@ -0,0 +1,247 @@
1/*
2 * drivers/base/power/wakeup.c - System wakeup events framework
3 *
4 * Copyright (c) 2010 Rafael J. Wysocki <rjw@sisk.pl>, Novell Inc.
5 *
6 * This file is released under the GPLv2.
7 */
8
9#include <linux/device.h>
10#include <linux/slab.h>
11#include <linux/sched.h>
12#include <linux/capability.h>
13#include <linux/suspend.h>
14#include <linux/pm.h>
15
16/*
17 * If set, the suspend/hibernate code will abort transitions to a sleep state
18 * if wakeup events are registered during or immediately before the transition.
19 */
20bool events_check_enabled;
21
22/* The counter of registered wakeup events. */
23static unsigned long event_count;
24/* A preserved old value of event_count. */
25static unsigned long saved_event_count;
26/* The counter of wakeup events being processed. */
27static unsigned long events_in_progress;
28
29static DEFINE_SPINLOCK(events_lock);
30
31static void pm_wakeup_timer_fn(unsigned long data);
32
33static DEFINE_TIMER(events_timer, pm_wakeup_timer_fn, 0, 0);
34static unsigned long events_timer_expires;
35
36/*
37 * The functions below use the observation that each wakeup event starts a
38 * period in which the system should not be suspended. The moment this period
39 * will end depends on how the wakeup event is going to be processed after being
40 * detected and all of the possible cases can be divided into two distinct
41 * groups.
42 *
43 * First, a wakeup event may be detected by the same functional unit that will
44 * carry out the entire processing of it and possibly will pass it to user space
45 * for further processing. In that case the functional unit that has detected
46 * the event may later "close" the "no suspend" period associated with it
47 * directly as soon as it has been dealt with. The pair of pm_stay_awake() and
48 * pm_relax(), balanced with each other, is supposed to be used in such
49 * situations.
50 *
51 * Second, a wakeup event may be detected by one functional unit and processed
52 * by another one. In that case the unit that has detected it cannot really
53 * "close" the "no suspend" period associated with it, unless it knows in
54 * advance what's going to happen to the event during processing. This
55 * knowledge, however, may not be available to it, so it can simply specify time
56 * to wait before the system can be suspended and pass it as the second
57 * argument of pm_wakeup_event().
58 */
59
60/**
61 * pm_stay_awake - Notify the PM core that a wakeup event is being processed.
62 * @dev: Device the wakeup event is related to.
63 *
64 * Notify the PM core of a wakeup event (signaled by @dev) by incrementing the
65 * counter of wakeup events being processed. If @dev is not NULL, the counter
66 * of wakeup events related to @dev is incremented too.
67 *
68 * Call this function after detecting of a wakeup event if pm_relax() is going
69 * to be called directly after processing the event (and possibly passing it to
70 * user space for further processing).
71 *
72 * It is safe to call this function from interrupt context.
73 */
74void pm_stay_awake(struct device *dev)
75{
76 unsigned long flags;
77
78 spin_lock_irqsave(&events_lock, flags);
79 if (dev)
80 dev->power.wakeup_count++;
81
82 events_in_progress++;
83 spin_unlock_irqrestore(&events_lock, flags);
84}
85
86/**
87 * pm_relax - Notify the PM core that processing of a wakeup event has ended.
88 *
89 * Notify the PM core that a wakeup event has been processed by decrementing
90 * the counter of wakeup events being processed and incrementing the counter
91 * of registered wakeup events.
92 *
93 * Call this function for wakeup events whose processing started with calling
94 * pm_stay_awake().
95 *
96 * It is safe to call it from interrupt context.
97 */
98void pm_relax(void)
99{
100 unsigned long flags;
101
102 spin_lock_irqsave(&events_lock, flags);
103 if (events_in_progress) {
104 events_in_progress--;
105 event_count++;
106 }
107 spin_unlock_irqrestore(&events_lock, flags);
108}
109
110/**
111 * pm_wakeup_timer_fn - Delayed finalization of a wakeup event.
112 *
113 * Decrease the counter of wakeup events being processed after it was increased
114 * by pm_wakeup_event().
115 */
116static void pm_wakeup_timer_fn(unsigned long data)
117{
118 unsigned long flags;
119
120 spin_lock_irqsave(&events_lock, flags);
121 if (events_timer_expires
122 && time_before_eq(events_timer_expires, jiffies)) {
123 events_in_progress--;
124 events_timer_expires = 0;
125 }
126 spin_unlock_irqrestore(&events_lock, flags);
127}
128
129/**
130 * pm_wakeup_event - Notify the PM core of a wakeup event.
131 * @dev: Device the wakeup event is related to.
132 * @msec: Anticipated event processing time (in milliseconds).
133 *
134 * Notify the PM core of a wakeup event (signaled by @dev) that will take
135 * approximately @msec milliseconds to be processed by the kernel. Increment
136 * the counter of registered wakeup events and (if @msec is nonzero) set up
137 * the wakeup events timer to execute pm_wakeup_timer_fn() in future (if the
138 * timer has not been set up already, increment the counter of wakeup events
139 * being processed). If @dev is not NULL, the counter of wakeup events related
140 * to @dev is incremented too.
141 *
142 * It is safe to call this function from interrupt context.
143 */
144void pm_wakeup_event(struct device *dev, unsigned int msec)
145{
146 unsigned long flags;
147
148 spin_lock_irqsave(&events_lock, flags);
149 event_count++;
150 if (dev)
151 dev->power.wakeup_count++;
152
153 if (msec) {
154 unsigned long expires;
155
156 expires = jiffies + msecs_to_jiffies(msec);
157 if (!expires)
158 expires = 1;
159
160 if (!events_timer_expires
161 || time_after(expires, events_timer_expires)) {
162 if (!events_timer_expires)
163 events_in_progress++;
164
165 mod_timer(&events_timer, expires);
166 events_timer_expires = expires;
167 }
168 }
169 spin_unlock_irqrestore(&events_lock, flags);
170}
171
172/**
173 * pm_check_wakeup_events - Check for new wakeup events.
174 *
175 * Compare the current number of registered wakeup events with its preserved
176 * value from the past to check if new wakeup events have been registered since
177 * the old value was stored. Check if the current number of wakeup events being
178 * processed is zero.
179 */
180bool pm_check_wakeup_events(void)
181{
182 unsigned long flags;
183 bool ret = true;
184
185 spin_lock_irqsave(&events_lock, flags);
186 if (events_check_enabled) {
187 ret = (event_count == saved_event_count) && !events_in_progress;
188 events_check_enabled = ret;
189 }
190 spin_unlock_irqrestore(&events_lock, flags);
191 return ret;
192}
193
194/**
195 * pm_get_wakeup_count - Read the number of registered wakeup events.
196 * @count: Address to store the value at.
197 *
198 * Store the number of registered wakeup events at the address in @count. Block
199 * if the current number of wakeup events being processed is nonzero.
200 *
201 * Return false if the wait for the number of wakeup events being processed to
202 * drop down to zero has been interrupted by a signal (and the current number
203 * of wakeup events being processed is still nonzero). Otherwise return true.
204 */
205bool pm_get_wakeup_count(unsigned long *count)
206{
207 bool ret;
208
209 spin_lock_irq(&events_lock);
210 if (capable(CAP_SYS_ADMIN))
211 events_check_enabled = false;
212
213 while (events_in_progress && !signal_pending(current)) {
214 spin_unlock_irq(&events_lock);
215
216 schedule_timeout_interruptible(msecs_to_jiffies(100));
217
218 spin_lock_irq(&events_lock);
219 }
220 *count = event_count;
221 ret = !events_in_progress;
222 spin_unlock_irq(&events_lock);
223 return ret;
224}
225
226/**
227 * pm_save_wakeup_count - Save the current number of registered wakeup events.
228 * @count: Value to compare with the current number of registered wakeup events.
229 *
230 * If @count is equal to the current number of registered wakeup events and the
231 * current number of wakeup events being processed is zero, store @count as the
232 * old number of registered wakeup events to be used by pm_check_wakeup_events()
233 * and return true. Otherwise return false.
234 */
235bool pm_save_wakeup_count(unsigned long count)
236{
237 bool ret = false;
238
239 spin_lock_irq(&events_lock);
240 if (count == event_count && !events_in_progress) {
241 saved_event_count = count;
242 events_check_enabled = true;
243 ret = true;
244 }
245 spin_unlock_irq(&events_lock);
246 return ret;
247}
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index 57a7e41da69e..9f13b660b801 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -2901,10 +2901,10 @@ static void e1000_configure_rx(struct e1000_adapter *adapter)
2901 * dropped transactions. 2901 * dropped transactions.
2902 */ 2902 */
2903 pm_qos_update_request( 2903 pm_qos_update_request(
2904 adapter->netdev->pm_qos_req, 55); 2904 &adapter->netdev->pm_qos_req, 55);
2905 } else { 2905 } else {
2906 pm_qos_update_request( 2906 pm_qos_update_request(
2907 adapter->netdev->pm_qos_req, 2907 &adapter->netdev->pm_qos_req,
2908 PM_QOS_DEFAULT_VALUE); 2908 PM_QOS_DEFAULT_VALUE);
2909 } 2909 }
2910 } 2910 }
@@ -3196,9 +3196,9 @@ int e1000e_up(struct e1000_adapter *adapter)
3196 3196
3197 /* DMA latency requirement to workaround early-receive/jumbo issue */ 3197 /* DMA latency requirement to workaround early-receive/jumbo issue */
3198 if (adapter->flags & FLAG_HAS_ERT) 3198 if (adapter->flags & FLAG_HAS_ERT)
3199 adapter->netdev->pm_qos_req = 3199 pm_qos_add_request(&adapter->netdev->pm_qos_req,
3200 pm_qos_add_request(PM_QOS_CPU_DMA_LATENCY, 3200 PM_QOS_CPU_DMA_LATENCY,
3201 PM_QOS_DEFAULT_VALUE); 3201 PM_QOS_DEFAULT_VALUE);
3202 3202
3203 /* hardware has been reset, we need to reload some things */ 3203 /* hardware has been reset, we need to reload some things */
3204 e1000_configure(adapter); 3204 e1000_configure(adapter);
@@ -3263,11 +3263,8 @@ void e1000e_down(struct e1000_adapter *adapter)
3263 e1000_clean_tx_ring(adapter); 3263 e1000_clean_tx_ring(adapter);
3264 e1000_clean_rx_ring(adapter); 3264 e1000_clean_rx_ring(adapter);
3265 3265
3266 if (adapter->flags & FLAG_HAS_ERT) { 3266 if (adapter->flags & FLAG_HAS_ERT)
3267 pm_qos_remove_request( 3267 pm_qos_remove_request(&adapter->netdev->pm_qos_req);
3268 adapter->netdev->pm_qos_req);
3269 adapter->netdev->pm_qos_req = NULL;
3270 }
3271 3268
3272 /* 3269 /*
3273 * TODO: for power management, we could drop the link and 3270 * TODO: for power management, we could drop the link and
diff --git a/drivers/net/igbvf/netdev.c b/drivers/net/igbvf/netdev.c
index 5e2b2a8c56c6..add6197d3bcb 100644
--- a/drivers/net/igbvf/netdev.c
+++ b/drivers/net/igbvf/netdev.c
@@ -48,7 +48,7 @@
48#define DRV_VERSION "1.0.0-k0" 48#define DRV_VERSION "1.0.0-k0"
49char igbvf_driver_name[] = "igbvf"; 49char igbvf_driver_name[] = "igbvf";
50const char igbvf_driver_version[] = DRV_VERSION; 50const char igbvf_driver_version[] = DRV_VERSION;
51struct pm_qos_request_list *igbvf_driver_pm_qos_req; 51static struct pm_qos_request_list igbvf_driver_pm_qos_req;
52static const char igbvf_driver_string[] = 52static const char igbvf_driver_string[] =
53 "Intel(R) Virtual Function Network Driver"; 53 "Intel(R) Virtual Function Network Driver";
54static const char igbvf_copyright[] = "Copyright (c) 2009 Intel Corporation."; 54static const char igbvf_copyright[] = "Copyright (c) 2009 Intel Corporation.";
@@ -2902,8 +2902,8 @@ static int __init igbvf_init_module(void)
2902 printk(KERN_INFO "%s\n", igbvf_copyright); 2902 printk(KERN_INFO "%s\n", igbvf_copyright);
2903 2903
2904 ret = pci_register_driver(&igbvf_driver); 2904 ret = pci_register_driver(&igbvf_driver);
2905 igbvf_driver_pm_qos_req = pm_qos_add_request(PM_QOS_CPU_DMA_LATENCY, 2905 pm_qos_add_request(&igbvf_driver_pm_qos_req, PM_QOS_CPU_DMA_LATENCY,
2906 PM_QOS_DEFAULT_VALUE); 2906 PM_QOS_DEFAULT_VALUE);
2907 2907
2908 return ret; 2908 return ret;
2909} 2909}
@@ -2918,8 +2918,7 @@ module_init(igbvf_init_module);
2918static void __exit igbvf_exit_module(void) 2918static void __exit igbvf_exit_module(void)
2919{ 2919{
2920 pci_unregister_driver(&igbvf_driver); 2920 pci_unregister_driver(&igbvf_driver);
2921 pm_qos_remove_request(igbvf_driver_pm_qos_req); 2921 pm_qos_remove_request(&igbvf_driver_pm_qos_req);
2922 igbvf_driver_pm_qos_req = NULL;
2923} 2922}
2924module_exit(igbvf_exit_module); 2923module_exit(igbvf_exit_module);
2925 2924
diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c
index 0bd4dfa59a8a..7f0d98b885bc 100644
--- a/drivers/net/wireless/ipw2x00/ipw2100.c
+++ b/drivers/net/wireless/ipw2x00/ipw2100.c
@@ -174,7 +174,7 @@ that only one external action is invoked at a time.
174#define DRV_DESCRIPTION "Intel(R) PRO/Wireless 2100 Network Driver" 174#define DRV_DESCRIPTION "Intel(R) PRO/Wireless 2100 Network Driver"
175#define DRV_COPYRIGHT "Copyright(c) 2003-2006 Intel Corporation" 175#define DRV_COPYRIGHT "Copyright(c) 2003-2006 Intel Corporation"
176 176
177struct pm_qos_request_list *ipw2100_pm_qos_req; 177struct pm_qos_request_list ipw2100_pm_qos_req;
178 178
179/* Debugging stuff */ 179/* Debugging stuff */
180#ifdef CONFIG_IPW2100_DEBUG 180#ifdef CONFIG_IPW2100_DEBUG
@@ -1741,7 +1741,7 @@ static int ipw2100_up(struct ipw2100_priv *priv, int deferred)
1741 /* the ipw2100 hardware really doesn't want power management delays 1741 /* the ipw2100 hardware really doesn't want power management delays
1742 * longer than 175usec 1742 * longer than 175usec
1743 */ 1743 */
1744 pm_qos_update_request(ipw2100_pm_qos_req, 175); 1744 pm_qos_update_request(&ipw2100_pm_qos_req, 175);
1745 1745
1746 /* If the interrupt is enabled, turn it off... */ 1746 /* If the interrupt is enabled, turn it off... */
1747 spin_lock_irqsave(&priv->low_lock, flags); 1747 spin_lock_irqsave(&priv->low_lock, flags);
@@ -1889,7 +1889,7 @@ static void ipw2100_down(struct ipw2100_priv *priv)
1889 ipw2100_disable_interrupts(priv); 1889 ipw2100_disable_interrupts(priv);
1890 spin_unlock_irqrestore(&priv->low_lock, flags); 1890 spin_unlock_irqrestore(&priv->low_lock, flags);
1891 1891
1892 pm_qos_update_request(ipw2100_pm_qos_req, PM_QOS_DEFAULT_VALUE); 1892 pm_qos_update_request(&ipw2100_pm_qos_req, PM_QOS_DEFAULT_VALUE);
1893 1893
1894 /* We have to signal any supplicant if we are disassociating */ 1894 /* We have to signal any supplicant if we are disassociating */
1895 if (associated) 1895 if (associated)
@@ -6669,8 +6669,8 @@ static int __init ipw2100_init(void)
6669 if (ret) 6669 if (ret)
6670 goto out; 6670 goto out;
6671 6671
6672 ipw2100_pm_qos_req = pm_qos_add_request(PM_QOS_CPU_DMA_LATENCY, 6672 pm_qos_add_request(&ipw2100_pm_qos_req, PM_QOS_CPU_DMA_LATENCY,
6673 PM_QOS_DEFAULT_VALUE); 6673 PM_QOS_DEFAULT_VALUE);
6674#ifdef CONFIG_IPW2100_DEBUG 6674#ifdef CONFIG_IPW2100_DEBUG
6675 ipw2100_debug_level = debug; 6675 ipw2100_debug_level = debug;
6676 ret = driver_create_file(&ipw2100_pci_driver.driver, 6676 ret = driver_create_file(&ipw2100_pci_driver.driver,
@@ -6692,7 +6692,7 @@ static void __exit ipw2100_exit(void)
6692 &driver_attr_debug_level); 6692 &driver_attr_debug_level);
6693#endif 6693#endif
6694 pci_unregister_driver(&ipw2100_pci_driver); 6694 pci_unregister_driver(&ipw2100_pci_driver);
6695 pm_qos_remove_request(ipw2100_pm_qos_req); 6695 pm_qos_remove_request(&ipw2100_pm_qos_req);
6696} 6696}
6697 6697
6698module_init(ipw2100_init); 6698module_init(ipw2100_init);
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
index 2e7a3bf13824..1ab98bbe58dd 100644
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -48,6 +48,7 @@ static void pci_acpi_wake_dev(acpi_handle handle, u32 event, void *context)
48 if (event == ACPI_NOTIFY_DEVICE_WAKE && pci_dev) { 48 if (event == ACPI_NOTIFY_DEVICE_WAKE && pci_dev) {
49 pci_check_pme_status(pci_dev); 49 pci_check_pme_status(pci_dev);
50 pm_runtime_resume(&pci_dev->dev); 50 pm_runtime_resume(&pci_dev->dev);
51 pci_wakeup_event(pci_dev);
51 if (pci_dev->subordinate) 52 if (pci_dev->subordinate)
52 pci_pme_wakeup_bus(pci_dev->subordinate); 53 pci_pme_wakeup_bus(pci_dev->subordinate);
53 } 54 }
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 740fb4ea9669..130ed1daf0f8 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -1275,6 +1275,22 @@ bool pci_check_pme_status(struct pci_dev *dev)
1275 return ret; 1275 return ret;
1276} 1276}
1277 1277
1278/*
1279 * Time to wait before the system can be put into a sleep state after reporting
1280 * a wakeup event signaled by a PCI device.
1281 */
1282#define PCI_WAKEUP_COOLDOWN 100
1283
1284/**
1285 * pci_wakeup_event - Report a wakeup event related to a given PCI device.
1286 * @dev: Device to report the wakeup event for.
1287 */
1288void pci_wakeup_event(struct pci_dev *dev)
1289{
1290 if (device_may_wakeup(&dev->dev))
1291 pm_wakeup_event(&dev->dev, PCI_WAKEUP_COOLDOWN);
1292}
1293
1278/** 1294/**
1279 * pci_pme_wakeup - Wake up a PCI device if its PME Status bit is set. 1295 * pci_pme_wakeup - Wake up a PCI device if its PME Status bit is set.
1280 * @dev: Device to handle. 1296 * @dev: Device to handle.
@@ -1285,8 +1301,10 @@ bool pci_check_pme_status(struct pci_dev *dev)
1285 */ 1301 */
1286static int pci_pme_wakeup(struct pci_dev *dev, void *ign) 1302static int pci_pme_wakeup(struct pci_dev *dev, void *ign)
1287{ 1303{
1288 if (pci_check_pme_status(dev)) 1304 if (pci_check_pme_status(dev)) {
1289 pm_request_resume(&dev->dev); 1305 pm_request_resume(&dev->dev);
1306 pci_wakeup_event(dev);
1307 }
1290 return 0; 1308 return 0;
1291} 1309}
1292 1310
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index f8077b3c8c8c..c8b7fd056ccd 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -56,6 +56,7 @@ extern void pci_update_current_state(struct pci_dev *dev, pci_power_t state);
56extern void pci_disable_enabled_device(struct pci_dev *dev); 56extern void pci_disable_enabled_device(struct pci_dev *dev);
57extern bool pci_check_pme_status(struct pci_dev *dev); 57extern bool pci_check_pme_status(struct pci_dev *dev);
58extern int pci_finish_runtime_suspend(struct pci_dev *dev); 58extern int pci_finish_runtime_suspend(struct pci_dev *dev);
59extern void pci_wakeup_event(struct pci_dev *dev);
59extern int __pci_pme_wakeup(struct pci_dev *dev, void *ign); 60extern int __pci_pme_wakeup(struct pci_dev *dev, void *ign);
60extern void pci_pme_wakeup_bus(struct pci_bus *bus); 61extern void pci_pme_wakeup_bus(struct pci_bus *bus);
61extern void pci_pm_init(struct pci_dev *dev); 62extern void pci_pm_init(struct pci_dev *dev);
diff --git a/drivers/pci/pcie/pme/pcie_pme.c b/drivers/pci/pcie/pme/pcie_pme.c
index d672a0a63816..bbdea18693d9 100644
--- a/drivers/pci/pcie/pme/pcie_pme.c
+++ b/drivers/pci/pcie/pme/pcie_pme.c
@@ -154,6 +154,7 @@ static bool pcie_pme_walk_bus(struct pci_bus *bus)
154 /* Skip PCIe devices in case we started from a root port. */ 154 /* Skip PCIe devices in case we started from a root port. */
155 if (!pci_is_pcie(dev) && pci_check_pme_status(dev)) { 155 if (!pci_is_pcie(dev) && pci_check_pme_status(dev)) {
156 pm_request_resume(&dev->dev); 156 pm_request_resume(&dev->dev);
157 pci_wakeup_event(dev);
157 ret = true; 158 ret = true;
158 } 159 }
159 160
@@ -254,8 +255,10 @@ static void pcie_pme_handle_request(struct pci_dev *port, u16 req_id)
254 if (found) { 255 if (found) {
255 /* The device is there, but we have to check its PME status. */ 256 /* The device is there, but we have to check its PME status. */
256 found = pci_check_pme_status(dev); 257 found = pci_check_pme_status(dev);
257 if (found) 258 if (found) {
258 pm_request_resume(&dev->dev); 259 pm_request_resume(&dev->dev);
260 pci_wakeup_event(dev);
261 }
259 pci_dev_put(dev); 262 pci_dev_put(dev);
260 } else if (devfn) { 263 } else if (devfn) {
261 /* 264 /*
diff --git a/drivers/pnp/core.c b/drivers/pnp/core.c
index 5dba90995d9e..88b3cde52596 100644
--- a/drivers/pnp/core.c
+++ b/drivers/pnp/core.c
@@ -164,6 +164,9 @@ int __pnp_add_device(struct pnp_dev *dev)
164 list_add_tail(&dev->global_list, &pnp_global); 164 list_add_tail(&dev->global_list, &pnp_global);
165 list_add_tail(&dev->protocol_list, &dev->protocol->devices); 165 list_add_tail(&dev->protocol_list, &dev->protocol->devices);
166 spin_unlock(&pnp_lock); 166 spin_unlock(&pnp_lock);
167 if (dev->protocol->can_wakeup)
168 device_set_wakeup_capable(&dev->dev,
169 dev->protocol->can_wakeup(dev));
167 return device_register(&dev->dev); 170 return device_register(&dev->dev);
168} 171}
169 172
diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c
index f7ff628b7d94..dc4e32e031e9 100644
--- a/drivers/pnp/pnpacpi/core.c
+++ b/drivers/pnp/pnpacpi/core.c
@@ -122,17 +122,37 @@ static int pnpacpi_disable_resources(struct pnp_dev *dev)
122} 122}
123 123
124#ifdef CONFIG_ACPI_SLEEP 124#ifdef CONFIG_ACPI_SLEEP
125static bool pnpacpi_can_wakeup(struct pnp_dev *dev)
126{
127 struct acpi_device *acpi_dev = dev->data;
128 acpi_handle handle = acpi_dev->handle;
129
130 return acpi_bus_can_wakeup(handle);
131}
132
125static int pnpacpi_suspend(struct pnp_dev *dev, pm_message_t state) 133static int pnpacpi_suspend(struct pnp_dev *dev, pm_message_t state)
126{ 134{
127 struct acpi_device *acpi_dev = dev->data; 135 struct acpi_device *acpi_dev = dev->data;
128 acpi_handle handle = acpi_dev->handle; 136 acpi_handle handle = acpi_dev->handle;
129 int power_state; 137 int power_state;
130 138
139 if (device_can_wakeup(&dev->dev)) {
140 int rc = acpi_pm_device_sleep_wake(&dev->dev,
141 device_may_wakeup(&dev->dev));
142
143 if (rc)
144 return rc;
145 }
131 power_state = acpi_pm_device_sleep_state(&dev->dev, NULL); 146 power_state = acpi_pm_device_sleep_state(&dev->dev, NULL);
132 if (power_state < 0) 147 if (power_state < 0)
133 power_state = (state.event == PM_EVENT_ON) ? 148 power_state = (state.event == PM_EVENT_ON) ?
134 ACPI_STATE_D0 : ACPI_STATE_D3; 149 ACPI_STATE_D0 : ACPI_STATE_D3;
135 150
151 /* acpi_bus_set_power() often fails (keyboard port can't be
152 * powered-down?), and in any case, our return value is ignored
153 * by pnp_bus_suspend(). Hence we don't revert the wakeup
154 * setting if the set_power fails.
155 */
136 return acpi_bus_set_power(handle, power_state); 156 return acpi_bus_set_power(handle, power_state);
137} 157}
138 158
@@ -141,6 +161,8 @@ static int pnpacpi_resume(struct pnp_dev *dev)
141 struct acpi_device *acpi_dev = dev->data; 161 struct acpi_device *acpi_dev = dev->data;
142 acpi_handle handle = acpi_dev->handle; 162 acpi_handle handle = acpi_dev->handle;
143 163
164 if (device_may_wakeup(&dev->dev))
165 acpi_pm_device_sleep_wake(&dev->dev, false);
144 return acpi_bus_set_power(handle, ACPI_STATE_D0); 166 return acpi_bus_set_power(handle, ACPI_STATE_D0);
145} 167}
146#endif 168#endif
@@ -151,6 +173,7 @@ struct pnp_protocol pnpacpi_protocol = {
151 .set = pnpacpi_set_resources, 173 .set = pnpacpi_set_resources,
152 .disable = pnpacpi_disable_resources, 174 .disable = pnpacpi_disable_resources,
153#ifdef CONFIG_ACPI_SLEEP 175#ifdef CONFIG_ACPI_SLEEP
176 .can_wakeup = pnpacpi_can_wakeup,
154 .suspend = pnpacpi_suspend, 177 .suspend = pnpacpi_suspend,
155 .resume = pnpacpi_resume, 178 .resume = pnpacpi_resume,
156#endif 179#endif