2 * wakeup.c - support wakeup devices
3 * Copyright (C) 2004 Li Shaohua <shaohua.li@intel.com>
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>
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
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,
40 if (!dev->wakeup.flags.valid ||
41 !dev->wakeup.state.enabled ||
42 (sleep_state > (u32) dev->wakeup.sleep_state))
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);
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;
62 * Caution: this routine must be invoked when interrupt is disabled
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,
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);
87 if (!dev->wakeup.flags.valid ||
88 !dev->wakeup.state.enabled ||
89 (sleep_state > (u32) dev->wakeup.sleep_state))
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,
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);
132 if (!dev->wakeup.flags.valid ||
133 !dev->wakeup.state.active ||
134 (sleep_state > (u32) dev->wakeup.sleep_state))
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;
158 printk("ACPI wakeup devices: \n");
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,
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);
177 printk("%4s ", dev->pnp.bus_id);
179 spin_unlock(&acpi_device_lock);
185 late_initcall(acpi_wakeup_device_init);
189 * Disable all wakeup GPEs before power off.
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.
195 void acpi_gpe_sleep_prepare(u32 sleep_state)
197 struct list_head *node, *next;
199 list_for_each_safe(node, next, &acpi_wakeup_device_list) {
200 struct acpi_device *dev = container_of(node,
204 /* The GPE can wakeup system from this state, don't touch it */
205 if ((u32) dev->wakeup.sleep_state >= sleep_state)
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);