diff options
Diffstat (limited to 'drivers/acpi/sleep/main.c')
-rw-r--r-- | drivers/acpi/sleep/main.c | 71 |
1 files changed, 14 insertions, 57 deletions
diff --git a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c index d2f71a54726c..71183eea7906 100644 --- a/drivers/acpi/sleep/main.c +++ b/drivers/acpi/sleep/main.c | |||
@@ -26,21 +26,6 @@ u8 sleep_states[ACPI_S_STATE_COUNT]; | |||
26 | 26 | ||
27 | #ifdef CONFIG_PM_SLEEP | 27 | #ifdef CONFIG_PM_SLEEP |
28 | static u32 acpi_target_sleep_state = ACPI_STATE_S0; | 28 | static u32 acpi_target_sleep_state = ACPI_STATE_S0; |
29 | static bool acpi_sleep_finish_wake_up; | ||
30 | |||
31 | /* | ||
32 | * ACPI 2.0 and later want us to execute _PTS after suspending devices, so we | ||
33 | * allow the user to request that behavior by using the 'acpi_new_pts_ordering' | ||
34 | * kernel command line option that causes the following variable to be set. | ||
35 | */ | ||
36 | static bool new_pts_ordering; | ||
37 | |||
38 | static int __init acpi_new_pts_ordering(char *str) | ||
39 | { | ||
40 | new_pts_ordering = true; | ||
41 | return 1; | ||
42 | } | ||
43 | __setup("acpi_new_pts_ordering", acpi_new_pts_ordering); | ||
44 | #endif | 29 | #endif |
45 | 30 | ||
46 | static int acpi_sleep_prepare(u32 acpi_state) | 31 | static int acpi_sleep_prepare(u32 acpi_state) |
@@ -91,14 +76,6 @@ static int acpi_pm_begin(suspend_state_t pm_state) | |||
91 | 76 | ||
92 | if (sleep_states[acpi_state]) { | 77 | if (sleep_states[acpi_state]) { |
93 | acpi_target_sleep_state = acpi_state; | 78 | acpi_target_sleep_state = acpi_state; |
94 | if (new_pts_ordering) | ||
95 | return 0; | ||
96 | |||
97 | error = acpi_sleep_prepare(acpi_state); | ||
98 | if (error) | ||
99 | acpi_target_sleep_state = ACPI_STATE_S0; | ||
100 | else | ||
101 | acpi_sleep_finish_wake_up = true; | ||
102 | } else { | 79 | } else { |
103 | printk(KERN_ERR "ACPI does not support this state: %d\n", | 80 | printk(KERN_ERR "ACPI does not support this state: %d\n", |
104 | pm_state); | 81 | pm_state); |
@@ -116,14 +93,11 @@ static int acpi_pm_begin(suspend_state_t pm_state) | |||
116 | 93 | ||
117 | static int acpi_pm_prepare(void) | 94 | static int acpi_pm_prepare(void) |
118 | { | 95 | { |
119 | if (new_pts_ordering) { | 96 | int error = acpi_sleep_prepare(acpi_target_sleep_state); |
120 | int error = acpi_sleep_prepare(acpi_target_sleep_state); | ||
121 | 97 | ||
122 | if (error) { | 98 | if (error) { |
123 | acpi_target_sleep_state = ACPI_STATE_S0; | 99 | acpi_target_sleep_state = ACPI_STATE_S0; |
124 | return error; | 100 | return error; |
125 | } | ||
126 | acpi_sleep_finish_wake_up = true; | ||
127 | } | 101 | } |
128 | 102 | ||
129 | return ACPI_SUCCESS(acpi_hw_disable_all_gpes()) ? 0 : -EFAULT; | 103 | return ACPI_SUCCESS(acpi_hw_disable_all_gpes()) ? 0 : -EFAULT; |
@@ -212,7 +186,6 @@ static void acpi_pm_finish(void) | |||
212 | acpi_set_firmware_waking_vector((acpi_physical_address) 0); | 186 | acpi_set_firmware_waking_vector((acpi_physical_address) 0); |
213 | 187 | ||
214 | acpi_target_sleep_state = ACPI_STATE_S0; | 188 | acpi_target_sleep_state = ACPI_STATE_S0; |
215 | acpi_sleep_finish_wake_up = false; | ||
216 | 189 | ||
217 | #ifdef CONFIG_X86 | 190 | #ifdef CONFIG_X86 |
218 | if (init_8259A_after_S1) { | 191 | if (init_8259A_after_S1) { |
@@ -229,11 +202,10 @@ static void acpi_pm_finish(void) | |||
229 | static void acpi_pm_end(void) | 202 | static void acpi_pm_end(void) |
230 | { | 203 | { |
231 | /* | 204 | /* |
232 | * This is necessary in case acpi_pm_finish() is not called directly | 205 | * This is necessary in case acpi_pm_finish() is not called during a |
233 | * during a failing transition to a sleep state. | 206 | * failing transition to a sleep state. |
234 | */ | 207 | */ |
235 | if (acpi_sleep_finish_wake_up) | 208 | acpi_target_sleep_state = ACPI_STATE_S0; |
236 | acpi_pm_finish(); | ||
237 | } | 209 | } |
238 | 210 | ||
239 | static int acpi_pm_state_valid(suspend_state_t pm_state) | 211 | static int acpi_pm_state_valid(suspend_state_t pm_state) |
@@ -285,31 +257,18 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = { | |||
285 | #ifdef CONFIG_HIBERNATION | 257 | #ifdef CONFIG_HIBERNATION |
286 | static int acpi_hibernation_begin(void) | 258 | static int acpi_hibernation_begin(void) |
287 | { | 259 | { |
288 | int error; | ||
289 | |||
290 | acpi_target_sleep_state = ACPI_STATE_S4; | 260 | acpi_target_sleep_state = ACPI_STATE_S4; |
291 | if (new_pts_ordering) | ||
292 | return 0; | ||
293 | 261 | ||
294 | error = acpi_sleep_prepare(ACPI_STATE_S4); | 262 | return 0; |
295 | if (error) | ||
296 | acpi_target_sleep_state = ACPI_STATE_S0; | ||
297 | else | ||
298 | acpi_sleep_finish_wake_up = true; | ||
299 | |||
300 | return error; | ||
301 | } | 263 | } |
302 | 264 | ||
303 | static int acpi_hibernation_prepare(void) | 265 | static int acpi_hibernation_prepare(void) |
304 | { | 266 | { |
305 | if (new_pts_ordering) { | 267 | int error = acpi_sleep_prepare(ACPI_STATE_S4); |
306 | int error = acpi_sleep_prepare(ACPI_STATE_S4); | ||
307 | 268 | ||
308 | if (error) { | 269 | if (error) { |
309 | acpi_target_sleep_state = ACPI_STATE_S0; | 270 | acpi_target_sleep_state = ACPI_STATE_S0; |
310 | return error; | 271 | return error; |
311 | } | ||
312 | acpi_sleep_finish_wake_up = true; | ||
313 | } | 272 | } |
314 | 273 | ||
315 | return ACPI_SUCCESS(acpi_hw_disable_all_gpes()) ? 0 : -EFAULT; | 274 | return ACPI_SUCCESS(acpi_hw_disable_all_gpes()) ? 0 : -EFAULT; |
@@ -353,17 +312,15 @@ static void acpi_hibernation_finish(void) | |||
353 | acpi_set_firmware_waking_vector((acpi_physical_address) 0); | 312 | acpi_set_firmware_waking_vector((acpi_physical_address) 0); |
354 | 313 | ||
355 | acpi_target_sleep_state = ACPI_STATE_S0; | 314 | acpi_target_sleep_state = ACPI_STATE_S0; |
356 | acpi_sleep_finish_wake_up = false; | ||
357 | } | 315 | } |
358 | 316 | ||
359 | static void acpi_hibernation_end(void) | 317 | static void acpi_hibernation_end(void) |
360 | { | 318 | { |
361 | /* | 319 | /* |
362 | * This is necessary in case acpi_hibernation_finish() is not called | 320 | * This is necessary in case acpi_hibernation_finish() is not called |
363 | * directly during a failing transition to the sleep state. | 321 | * during a failing transition to the sleep state. |
364 | */ | 322 | */ |
365 | if (acpi_sleep_finish_wake_up) | 323 | acpi_target_sleep_state = ACPI_STATE_S0; |
366 | acpi_hibernation_finish(); | ||
367 | } | 324 | } |
368 | 325 | ||
369 | static int acpi_hibernation_pre_restore(void) | 326 | static int acpi_hibernation_pre_restore(void) |