Linux 2.6.19-rc1
[linux-2.6/next.git] / drivers / acpi / sleep / wakeup.c
blobaf1dbabaf0b1d299277fe65727eed95778751c1d
1 /*
2 * wakeup.c - support wakeup devices
3 * Copyright (C) 2004 Li Shaohua <shaohua.li@intel.com>
4 */
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"
14 #define _COMPONENT ACPI_SYSTEM_COMPONENT
15 ACPI_MODULE_NAME("wakeup_devices")
17 extern struct list_head acpi_wakeup_device_list;
18 extern spinlock_t acpi_device_lock;
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
28 void acpi_enable_wakeup_device_prep(u8 sleep_state)
30 struct list_head *node, *next;
32 ACPI_FUNCTION_TRACE("acpi_enable_wakeup_device_prep");
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);
40 if (!dev->wakeup.flags.valid ||
41 !dev->wakeup.state.enabled ||
42 (sleep_state > (u32) dev->wakeup.sleep_state))
43 continue;
45 spin_unlock(&acpi_device_lock);
46 acpi_enable_wakeup_device_power(dev);
47 spin_lock(&acpi_device_lock);
49 spin_unlock(&acpi_device_lock);
52 /**
53 * acpi_enable_wakeup_device - enable wakeup devices
54 * @sleep_state: ACPI state
55 * Enable all wakup devices's GPE
57 void acpi_enable_wakeup_device(u8 sleep_state)
59 struct list_head *node, *next;
61 /*
62 * Caution: this routine must be invoked when interrupt is disabled
63 * Refer ACPI2.0: P212
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);
72 /* If users want to disable run-wake GPE,
73 * we only disable it for wake and leave it for runtime
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;
87 if (!dev->wakeup.flags.valid ||
88 !dev->wakeup.state.enabled ||
89 (sleep_state > (u32) dev->wakeup.sleep_state))
90 continue;
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);
100 spin_unlock(&acpi_device_lock);
104 * acpi_disable_wakeup_device - disable devices' wakeup capability
105 * @sleep_state: ACPI state
106 * Disable all wakup devices's GPE and wakeup capability
108 void acpi_disable_wakeup_device(u8 sleep_state)
110 struct list_head *node, *next;
112 ACPI_FUNCTION_TRACE("acpi_disable_wakeup_device");
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);
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;
132 if (!dev->wakeup.flags.valid ||
133 !dev->wakeup.state.active ||
134 (sleep_state > (u32) dev->wakeup.sleep_state))
135 continue;
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);
146 dev->wakeup.state.active = 0;
147 spin_lock(&acpi_device_lock);
149 spin_unlock(&acpi_device_lock);
152 static int __init acpi_wakeup_device_init(void)
154 struct list_head *node, *next;
156 if (acpi_disabled)
157 return 0;
159 spin_lock(&acpi_device_lock);
160 list_for_each_safe(node, next, &acpi_wakeup_device_list) {
161 struct acpi_device *dev = container_of(node,
162 struct acpi_device,
163 wakeup_list);
165 /* In case user doesn't load button driver */
166 if (dev->wakeup.flags.run_wake && !dev->wakeup.state.enabled) {
167 spin_unlock(&acpi_device_lock);
168 acpi_set_gpe_type(dev->wakeup.gpe_device,
169 dev->wakeup.gpe_number,
170 ACPI_GPE_TYPE_WAKE_RUN);
171 acpi_enable_gpe(dev->wakeup.gpe_device,
172 dev->wakeup.gpe_number, ACPI_NOT_ISR);
173 dev->wakeup.state.enabled = 1;
174 spin_lock(&acpi_device_lock);
177 spin_unlock(&acpi_device_lock);
179 return 0;
182 late_initcall(acpi_wakeup_device_init);
183 #endif
186 * Disable all wakeup GPEs before power off.
188 * Since acpi_enter_sleep_state() will disable all
189 * RUNTIME GPEs, we simply mark all GPES that
190 * are not enabled for wakeup from S5 as RUNTIME.
192 void acpi_gpe_sleep_prepare(u32 sleep_state)
194 struct list_head *node, *next;
196 list_for_each_safe(node, next, &acpi_wakeup_device_list) {
197 struct acpi_device *dev = container_of(node,
198 struct acpi_device,
199 wakeup_list);
201 /* The GPE can wakeup system from this state, don't touch it */
202 if ((u32) dev->wakeup.sleep_state >= sleep_state)
203 continue;
204 /* acpi_set_gpe_type will automatically disable GPE */
205 acpi_set_gpe_type(dev->wakeup.gpe_device,
206 dev->wakeup.gpe_number,
207 ACPI_GPE_TYPE_RUNTIME);