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