Merge git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-2.6-irqflags
[pandora-kernel.git] / drivers / base / power / wakeup.c
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  */
20 bool events_check_enabled;
21
22 /* The counter of registered wakeup events. */
23 static unsigned long event_count;
24 /* A preserved old value of event_count. */
25 static unsigned long saved_event_count;
26 /* The counter of wakeup events being processed. */
27 static unsigned long events_in_progress;
28
29 static DEFINE_SPINLOCK(events_lock);
30
31 static void pm_wakeup_timer_fn(unsigned long data);
32
33 static DEFINE_TIMER(events_timer, pm_wakeup_timer_fn, 0, 0);
34 static 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  */
74 void 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  */
98 void 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  */
116 static 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  */
144 void 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  */
180 bool 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  */
205 bool 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  */
235 bool 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 }