Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux...
[pandora-kernel.git] / drivers / acpi / sleep / wakeup.c
1 /*
2  * wakeup.c - support wakeup devices
3  * Copyright (C) 2004 Li Shaohua <shaohua.li@intel.com>
4  */
5
6 #include <linux/init.h>
7 #include <linux/acpi.h>
8 #include <acpi/acpi_drivers.h>
9 #include <linux/kernel.h>
10 #include <linux/types.h>
11 #include <acpi/acevents.h>
12 #include "sleep.h"
13
14 #define _COMPONENT              ACPI_SYSTEM_COMPONENT
15 ACPI_MODULE_NAME("wakeup_devices")
16
17 extern struct list_head acpi_wakeup_device_list;
18 extern spinlock_t acpi_device_lock;
19
20 /**
21  * acpi_enable_wakeup_device_prep - prepare wakeup devices
22  *      @sleep_state:   ACPI state
23  * Enable all wakup devices power if the devices' wakeup level
24  * is higher than requested sleep level
25  */
26
27 void acpi_enable_wakeup_device_prep(u8 sleep_state)
28 {
29         struct list_head *node, *next;
30
31         ACPI_FUNCTION_TRACE("acpi_enable_wakeup_device_prep");
32
33         spin_lock(&acpi_device_lock);
34         list_for_each_safe(node, next, &acpi_wakeup_device_list) {
35                 struct acpi_device *dev = container_of(node,
36                                                        struct acpi_device,
37                                                        wakeup_list);
38
39                 if (!dev->wakeup.flags.valid ||
40                     !dev->wakeup.state.enabled ||
41                     (sleep_state > (u32) dev->wakeup.sleep_state))
42                         continue;
43
44                 spin_unlock(&acpi_device_lock);
45                 acpi_enable_wakeup_device_power(dev);
46                 spin_lock(&acpi_device_lock);
47         }
48         spin_unlock(&acpi_device_lock);
49 }
50
51 /**
52  * acpi_enable_wakeup_device - enable wakeup devices
53  *      @sleep_state:   ACPI state
54  * Enable all wakup devices's GPE
55  */
56 void acpi_enable_wakeup_device(u8 sleep_state)
57 {
58         struct list_head *node, *next;
59
60         /* 
61          * Caution: this routine must be invoked when interrupt is disabled 
62          * Refer ACPI2.0: P212
63          */
64         ACPI_FUNCTION_TRACE("acpi_enable_wakeup_device");
65         spin_lock(&acpi_device_lock);
66         list_for_each_safe(node, next, &acpi_wakeup_device_list) {
67                 struct acpi_device *dev = container_of(node,
68                                                        struct acpi_device,
69                                                        wakeup_list);
70
71                 /* If users want to disable run-wake GPE,
72                  * we only disable it for wake and leave it for runtime
73                  */
74                 if (dev->wakeup.flags.run_wake && !dev->wakeup.state.enabled) {
75                         spin_unlock(&acpi_device_lock);
76                         acpi_set_gpe_type(dev->wakeup.gpe_device,
77                                           dev->wakeup.gpe_number,
78                                           ACPI_GPE_TYPE_RUNTIME);
79                         /* Re-enable it, since set_gpe_type will disable it */
80                         acpi_enable_gpe(dev->wakeup.gpe_device,
81                                         dev->wakeup.gpe_number, ACPI_ISR);
82                         spin_lock(&acpi_device_lock);
83                         continue;
84                 }
85
86                 if (!dev->wakeup.flags.valid ||
87                     !dev->wakeup.state.enabled ||
88                     (sleep_state > (u32) dev->wakeup.sleep_state))
89                         continue;
90
91                 spin_unlock(&acpi_device_lock);
92                 /* run-wake GPE has been enabled */
93                 if (!dev->wakeup.flags.run_wake)
94                         acpi_enable_gpe(dev->wakeup.gpe_device,
95                                         dev->wakeup.gpe_number, ACPI_ISR);
96                 dev->wakeup.state.active = 1;
97                 spin_lock(&acpi_device_lock);
98         }
99         spin_unlock(&acpi_device_lock);
100 }
101
102 /**
103  * acpi_disable_wakeup_device - disable devices' wakeup capability
104  *      @sleep_state:   ACPI state
105  * Disable all wakup devices's GPE and wakeup capability
106  */
107 void acpi_disable_wakeup_device(u8 sleep_state)
108 {
109         struct list_head *node, *next;
110
111         ACPI_FUNCTION_TRACE("acpi_disable_wakeup_device");
112
113         spin_lock(&acpi_device_lock);
114         list_for_each_safe(node, next, &acpi_wakeup_device_list) {
115                 struct acpi_device *dev = container_of(node,
116                                                        struct acpi_device,
117                                                        wakeup_list);
118
119                 if (dev->wakeup.flags.run_wake && !dev->wakeup.state.enabled) {
120                         spin_unlock(&acpi_device_lock);
121                         acpi_set_gpe_type(dev->wakeup.gpe_device,
122                                           dev->wakeup.gpe_number,
123                                           ACPI_GPE_TYPE_WAKE_RUN);
124                         /* Re-enable it, since set_gpe_type will disable it */
125                         acpi_enable_gpe(dev->wakeup.gpe_device,
126                                         dev->wakeup.gpe_number, ACPI_NOT_ISR);
127                         spin_lock(&acpi_device_lock);
128                         continue;
129                 }
130
131                 if (!dev->wakeup.flags.valid ||
132                     !dev->wakeup.state.active ||
133                     (sleep_state > (u32) dev->wakeup.sleep_state))
134                         continue;
135
136                 spin_unlock(&acpi_device_lock);
137                 acpi_disable_wakeup_device_power(dev);
138                 /* Never disable run-wake GPE */
139                 if (!dev->wakeup.flags.run_wake) {
140                         acpi_disable_gpe(dev->wakeup.gpe_device,
141                                          dev->wakeup.gpe_number, ACPI_NOT_ISR);
142                         acpi_clear_gpe(dev->wakeup.gpe_device,
143                                        dev->wakeup.gpe_number, ACPI_NOT_ISR);
144                 }
145                 dev->wakeup.state.active = 0;
146                 spin_lock(&acpi_device_lock);
147         }
148         spin_unlock(&acpi_device_lock);
149 }
150
151 static int __init acpi_wakeup_device_init(void)
152 {
153         struct list_head *node, *next;
154
155         if (acpi_disabled)
156                 return 0;
157
158         spin_lock(&acpi_device_lock);
159         list_for_each_safe(node, next, &acpi_wakeup_device_list) {
160                 struct acpi_device *dev = container_of(node,
161                                                        struct acpi_device,
162                                                        wakeup_list);
163
164                 /* In case user doesn't load button driver */
165                 if (dev->wakeup.flags.run_wake && !dev->wakeup.state.enabled) {
166                         spin_unlock(&acpi_device_lock);
167                         acpi_set_gpe_type(dev->wakeup.gpe_device,
168                                           dev->wakeup.gpe_number,
169                                           ACPI_GPE_TYPE_WAKE_RUN);
170                         acpi_enable_gpe(dev->wakeup.gpe_device,
171                                         dev->wakeup.gpe_number, ACPI_NOT_ISR);
172                         dev->wakeup.state.enabled = 1;
173                         spin_lock(&acpi_device_lock);
174                 }
175         }
176         spin_unlock(&acpi_device_lock);
177
178         return 0;
179 }
180
181 late_initcall(acpi_wakeup_device_init);
182
183 /*
184  * Disable all wakeup GPEs before entering requested sleep state.
185  *      @sleep_state:   ACPI state
186  * Since acpi_enter_sleep_state() will disable all
187  * RUNTIME GPEs, we simply mark all GPES that
188  * are not enabled for wakeup from requested state as RUNTIME.
189  */
190 void acpi_gpe_sleep_prepare(u32 sleep_state)
191 {
192         struct list_head *node, *next;
193
194         list_for_each_safe(node, next, &acpi_wakeup_device_list) {
195                 struct acpi_device *dev = container_of(node,
196                                                        struct acpi_device,
197                                                        wakeup_list);
198
199                 /* The GPE can wakeup system from this state, don't touch it */
200                 if ((u32) dev->wakeup.sleep_state >= sleep_state)
201                         continue;
202                 /* acpi_set_gpe_type will automatically disable GPE */
203                 acpi_set_gpe_type(dev->wakeup.gpe_device,
204                                   dev->wakeup.gpe_number,
205                                   ACPI_GPE_TYPE_RUNTIME);
206         }
207 }