aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/sleep
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/sleep')
-rw-r--r--drivers/acpi/sleep/main.c43
-rw-r--r--drivers/acpi/sleep/sleep.h1
-rw-r--r--drivers/acpi/sleep/wakeup.c117
3 files changed, 72 insertions, 89 deletions
diff --git a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c
index 5055acf2163c..f3d3867303ec 100644
--- a/drivers/acpi/sleep/main.c
+++ b/drivers/acpi/sleep/main.c
@@ -44,13 +44,12 @@ int acpi_sleep_prepare(u32 acpi_state)
44 ACPI_FLUSH_CPU_CACHE(); 44 ACPI_FLUSH_CPU_CACHE();
45 acpi_enable_wakeup_device_prep(acpi_state); 45 acpi_enable_wakeup_device_prep(acpi_state);
46#endif 46#endif
47 acpi_gpe_sleep_prepare(acpi_state);
48 acpi_enter_sleep_state_prep(acpi_state); 47 acpi_enter_sleep_state_prep(acpi_state);
49 return 0; 48 return 0;
50} 49}
51 50
52#ifdef CONFIG_SUSPEND 51#ifdef CONFIG_SUSPEND
53static struct pm_ops acpi_pm_ops; 52static struct platform_suspend_ops acpi_pm_ops;
54 53
55extern void do_suspend_lowlevel(void); 54extern void do_suspend_lowlevel(void);
56 55
@@ -85,13 +84,12 @@ static int acpi_pm_set_target(suspend_state_t pm_state)
85 84
86/** 85/**
87 * acpi_pm_prepare - Do preliminary suspend work. 86 * acpi_pm_prepare - Do preliminary suspend work.
88 * @pm_state: ignored
89 * 87 *
90 * If necessary, set the firmware waking vector and do arch-specific 88 * If necessary, set the firmware waking vector and do arch-specific
91 * nastiness to get the wakeup code to the waking vector. 89 * nastiness to get the wakeup code to the waking vector.
92 */ 90 */
93 91
94static int acpi_pm_prepare(suspend_state_t pm_state) 92static int acpi_pm_prepare(void)
95{ 93{
96 int error = acpi_sleep_prepare(acpi_target_sleep_state); 94 int error = acpi_sleep_prepare(acpi_target_sleep_state);
97 95
@@ -160,13 +158,12 @@ static int acpi_pm_enter(suspend_state_t pm_state)
160 158
161/** 159/**
162 * acpi_pm_finish - Finish up suspend sequence. 160 * acpi_pm_finish - Finish up suspend sequence.
163 * @pm_state: ignored
164 * 161 *
165 * This is called after we wake back up (or if entering the sleep state 162 * This is called after we wake back up (or if entering the sleep state
166 * failed). 163 * failed).
167 */ 164 */
168 165
169static int acpi_pm_finish(suspend_state_t pm_state) 166static void acpi_pm_finish(void)
170{ 167{
171 u32 acpi_state = acpi_target_sleep_state; 168 u32 acpi_state = acpi_target_sleep_state;
172 169
@@ -184,7 +181,6 @@ static int acpi_pm_finish(suspend_state_t pm_state)
184 init_8259A(0); 181 init_8259A(0);
185 } 182 }
186#endif 183#endif
187 return 0;
188} 184}
189 185
190static int acpi_pm_state_valid(suspend_state_t pm_state) 186static int acpi_pm_state_valid(suspend_state_t pm_state)
@@ -203,7 +199,7 @@ static int acpi_pm_state_valid(suspend_state_t pm_state)
203 } 199 }
204} 200}
205 201
206static struct pm_ops acpi_pm_ops = { 202static struct platform_suspend_ops acpi_pm_ops = {
207 .valid = acpi_pm_state_valid, 203 .valid = acpi_pm_state_valid,
208 .set_target = acpi_pm_set_target, 204 .set_target = acpi_pm_set_target,
209 .prepare = acpi_pm_prepare, 205 .prepare = acpi_pm_prepare,
@@ -233,6 +229,12 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
233#endif /* CONFIG_SUSPEND */ 229#endif /* CONFIG_SUSPEND */
234 230
235#ifdef CONFIG_HIBERNATION 231#ifdef CONFIG_HIBERNATION
232static int acpi_hibernation_start(void)
233{
234 acpi_target_sleep_state = ACPI_STATE_S4;
235 return 0;
236}
237
236static int acpi_hibernation_prepare(void) 238static int acpi_hibernation_prepare(void)
237{ 239{
238 return acpi_sleep_prepare(ACPI_STATE_S4); 240 return acpi_sleep_prepare(ACPI_STATE_S4);
@@ -254,13 +256,29 @@ static int acpi_hibernation_enter(void)
254 return ACPI_SUCCESS(status) ? 0 : -EFAULT; 256 return ACPI_SUCCESS(status) ? 0 : -EFAULT;
255} 257}
256 258
259static void acpi_hibernation_leave(void)
260{
261 /*
262 * If ACPI is not enabled by the BIOS and the boot kernel, we need to
263 * enable it here.
264 */
265 acpi_enable();
266}
267
257static void acpi_hibernation_finish(void) 268static void acpi_hibernation_finish(void)
258{ 269{
270 /*
271 * If ACPI is not enabled by the BIOS and the boot kernel, we need to
272 * enable it here.
273 */
274 acpi_enable();
259 acpi_leave_sleep_state(ACPI_STATE_S4); 275 acpi_leave_sleep_state(ACPI_STATE_S4);
260 acpi_disable_wakeup_device(ACPI_STATE_S4); 276 acpi_disable_wakeup_device(ACPI_STATE_S4);
261 277
262 /* reset firmware waking vector */ 278 /* reset firmware waking vector */
263 acpi_set_firmware_waking_vector((acpi_physical_address) 0); 279 acpi_set_firmware_waking_vector((acpi_physical_address) 0);
280
281 acpi_target_sleep_state = ACPI_STATE_S0;
264} 282}
265 283
266static int acpi_hibernation_pre_restore(void) 284static int acpi_hibernation_pre_restore(void)
@@ -277,10 +295,13 @@ static void acpi_hibernation_restore_cleanup(void)
277 acpi_hw_enable_all_runtime_gpes(); 295 acpi_hw_enable_all_runtime_gpes();
278} 296}
279 297
280static struct hibernation_ops acpi_hibernation_ops = { 298static struct platform_hibernation_ops acpi_hibernation_ops = {
299 .start = acpi_hibernation_start,
300 .pre_snapshot = acpi_hibernation_prepare,
301 .finish = acpi_hibernation_finish,
281 .prepare = acpi_hibernation_prepare, 302 .prepare = acpi_hibernation_prepare,
282 .enter = acpi_hibernation_enter, 303 .enter = acpi_hibernation_enter,
283 .finish = acpi_hibernation_finish, 304 .leave = acpi_hibernation_leave,
284 .pre_restore = acpi_hibernation_pre_restore, 305 .pre_restore = acpi_hibernation_pre_restore,
285 .restore_cleanup = acpi_hibernation_restore_cleanup, 306 .restore_cleanup = acpi_hibernation_restore_cleanup,
286}; 307};
@@ -417,7 +438,7 @@ int __init acpi_sleep_init(void)
417 } 438 }
418 } 439 }
419 440
420 pm_set_ops(&acpi_pm_ops); 441 suspend_set_ops(&acpi_pm_ops);
421#endif 442#endif
422 443
423#ifdef CONFIG_HIBERNATION 444#ifdef CONFIG_HIBERNATION
diff --git a/drivers/acpi/sleep/sleep.h b/drivers/acpi/sleep/sleep.h
index ff1f8504f497..a2ea125ae2d0 100644
--- a/drivers/acpi/sleep/sleep.h
+++ b/drivers/acpi/sleep/sleep.h
@@ -5,6 +5,5 @@ extern int acpi_suspend (u32 state);
5extern void acpi_enable_wakeup_device_prep(u8 sleep_state); 5extern void acpi_enable_wakeup_device_prep(u8 sleep_state);
6extern void acpi_enable_wakeup_device(u8 sleep_state); 6extern void acpi_enable_wakeup_device(u8 sleep_state);
7extern void acpi_disable_wakeup_device(u8 sleep_state); 7extern void acpi_disable_wakeup_device(u8 sleep_state);
8extern void acpi_gpe_sleep_prepare(u32 sleep_state);
9 8
10extern int acpi_sleep_prepare(u32 acpi_state); 9extern int acpi_sleep_prepare(u32 acpi_state);
diff --git a/drivers/acpi/sleep/wakeup.c b/drivers/acpi/sleep/wakeup.c
index 97c27ddb144d..ed8e41becf0c 100644
--- a/drivers/acpi/sleep/wakeup.c
+++ b/drivers/acpi/sleep/wakeup.c
@@ -64,36 +64,29 @@ void acpi_enable_wakeup_device(u8 sleep_state)
64 ACPI_FUNCTION_TRACE("acpi_enable_wakeup_device"); 64 ACPI_FUNCTION_TRACE("acpi_enable_wakeup_device");
65 spin_lock(&acpi_device_lock); 65 spin_lock(&acpi_device_lock);
66 list_for_each_safe(node, next, &acpi_wakeup_device_list) { 66 list_for_each_safe(node, next, &acpi_wakeup_device_list) {
67 struct acpi_device *dev = container_of(node, 67 struct acpi_device *dev =
68 struct acpi_device, 68 container_of(node, struct acpi_device, wakeup_list);
69 wakeup_list); 69 if (!dev->wakeup.flags.valid)
70 70 continue;
71 /* If users want to disable run-wake GPE, 71 /* If users want to disable run-wake GPE,
72 * we only disable it for wake and leave it for runtime 72 * we only disable it for wake and leave it for runtime
73 */ 73 */
74 if (dev->wakeup.flags.run_wake && !dev->wakeup.state.enabled) { 74 if (!dev->wakeup.state.enabled ||
75 spin_unlock(&acpi_device_lock); 75 sleep_state > (u32) dev->wakeup.sleep_state) {
76 acpi_set_gpe_type(dev->wakeup.gpe_device, 76 if (dev->wakeup.flags.run_wake) {
77 dev->wakeup.gpe_number, 77 spin_unlock(&acpi_device_lock);
78 ACPI_GPE_TYPE_RUNTIME); 78 /* set_gpe_type will disable GPE, leave it like that */
79 /* Re-enable it, since set_gpe_type will disable it */ 79 acpi_set_gpe_type(dev->wakeup.gpe_device,
80 acpi_enable_gpe(dev->wakeup.gpe_device, 80 dev->wakeup.gpe_number,
81 dev->wakeup.gpe_number, ACPI_ISR); 81 ACPI_GPE_TYPE_RUNTIME);
82 spin_lock(&acpi_device_lock); 82 spin_lock(&acpi_device_lock);
83 }
83 continue; 84 continue;
84 } 85 }
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); 86 spin_unlock(&acpi_device_lock);
92 /* run-wake GPE has been enabled */
93 if (!dev->wakeup.flags.run_wake) 87 if (!dev->wakeup.flags.run_wake)
94 acpi_enable_gpe(dev->wakeup.gpe_device, 88 acpi_enable_gpe(dev->wakeup.gpe_device,
95 dev->wakeup.gpe_number, ACPI_ISR); 89 dev->wakeup.gpe_number, ACPI_ISR);
96 dev->wakeup.state.active = 1;
97 spin_lock(&acpi_device_lock); 90 spin_lock(&acpi_device_lock);
98 } 91 }
99 spin_unlock(&acpi_device_lock); 92 spin_unlock(&acpi_device_lock);
@@ -112,26 +105,25 @@ void acpi_disable_wakeup_device(u8 sleep_state)
112 105
113 spin_lock(&acpi_device_lock); 106 spin_lock(&acpi_device_lock);
114 list_for_each_safe(node, next, &acpi_wakeup_device_list) { 107 list_for_each_safe(node, next, &acpi_wakeup_device_list) {
115 struct acpi_device *dev = container_of(node, 108 struct acpi_device *dev =
116 struct acpi_device, 109 container_of(node, struct acpi_device, wakeup_list);
117 wakeup_list);
118 110
119 if (dev->wakeup.flags.run_wake && !dev->wakeup.state.enabled) { 111 if (!dev->wakeup.flags.valid)
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; 112 continue;
129 } 113 if (!dev->wakeup.state.enabled ||
130 114 sleep_state > (u32) dev->wakeup.sleep_state) {
131 if (!dev->wakeup.flags.valid || 115 if (dev->wakeup.flags.run_wake) {
132 !dev->wakeup.state.active || 116 spin_unlock(&acpi_device_lock);
133 (sleep_state > (u32) dev->wakeup.sleep_state)) 117 acpi_set_gpe_type(dev->wakeup.gpe_device,
118 dev->wakeup.gpe_number,
119 ACPI_GPE_TYPE_WAKE_RUN);
120 /* Re-enable it, since set_gpe_type will disable it */
121 acpi_enable_gpe(dev->wakeup.gpe_device,
122 dev->wakeup.gpe_number, ACPI_NOT_ISR);
123 spin_lock(&acpi_device_lock);
124 }
134 continue; 125 continue;
126 }
135 127
136 spin_unlock(&acpi_device_lock); 128 spin_unlock(&acpi_device_lock);
137 acpi_disable_wakeup_device_power(dev); 129 acpi_disable_wakeup_device_power(dev);
@@ -142,7 +134,6 @@ void acpi_disable_wakeup_device(u8 sleep_state)
142 acpi_clear_gpe(dev->wakeup.gpe_device, 134 acpi_clear_gpe(dev->wakeup.gpe_device,
143 dev->wakeup.gpe_number, ACPI_NOT_ISR); 135 dev->wakeup.gpe_number, ACPI_NOT_ISR);
144 } 136 }
145 dev->wakeup.state.active = 0;
146 spin_lock(&acpi_device_lock); 137 spin_lock(&acpi_device_lock);
147 } 138 }
148 spin_unlock(&acpi_device_lock); 139 spin_unlock(&acpi_device_lock);
@@ -160,48 +151,20 @@ static int __init acpi_wakeup_device_init(void)
160 struct acpi_device *dev = container_of(node, 151 struct acpi_device *dev = container_of(node,
161 struct acpi_device, 152 struct acpi_device,
162 wakeup_list); 153 wakeup_list);
163
164 /* In case user doesn't load button driver */ 154 /* In case user doesn't load button driver */
165 if (dev->wakeup.flags.run_wake && !dev->wakeup.state.enabled) { 155 if (!dev->wakeup.flags.run_wake || dev->wakeup.state.enabled)
166 spin_unlock(&acpi_device_lock); 156 continue;
167 acpi_set_gpe_type(dev->wakeup.gpe_device, 157 spin_unlock(&acpi_device_lock);
168 dev->wakeup.gpe_number, 158 acpi_set_gpe_type(dev->wakeup.gpe_device,
169 ACPI_GPE_TYPE_WAKE_RUN); 159 dev->wakeup.gpe_number,
170 acpi_enable_gpe(dev->wakeup.gpe_device, 160 ACPI_GPE_TYPE_WAKE_RUN);
171 dev->wakeup.gpe_number, ACPI_NOT_ISR); 161 acpi_enable_gpe(dev->wakeup.gpe_device,
172 dev->wakeup.state.enabled = 1; 162 dev->wakeup.gpe_number, ACPI_NOT_ISR);
173 spin_lock(&acpi_device_lock); 163 dev->wakeup.state.enabled = 1;
174 } 164 spin_lock(&acpi_device_lock);
175 } 165 }
176 spin_unlock(&acpi_device_lock); 166 spin_unlock(&acpi_device_lock);
177
178 return 0; 167 return 0;
179} 168}
180 169
181late_initcall(acpi_wakeup_device_init); 170late_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 */
190void 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}