diff options
author | Len Brown <len.brown@intel.com> | 2008-10-22 23:28:46 -0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2008-10-22 23:28:46 -0400 |
commit | acd41d36e5a813501da92156f325ce15ddcd58ff (patch) | |
tree | daaca230153261b13e6d1989a977352e2c29a3d4 /drivers/acpi/sleep/main.c | |
parent | 4dff4e7f6cbcd2722b02dbb394ba87c4e05f8841 (diff) | |
parent | 4fb507b6b764195bb7821cf2baa988f6eb677d30 (diff) |
Merge branch 'suspend' into test
Diffstat (limited to 'drivers/acpi/sleep/main.c')
-rw-r--r-- | drivers/acpi/sleep/main.c | 59 |
1 files changed, 58 insertions, 1 deletions
diff --git a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c index 4c21480b5820..cc344d4252c9 100644 --- a/drivers/acpi/sleep/main.c +++ b/drivers/acpi/sleep/main.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/dmi.h> | 15 | #include <linux/dmi.h> |
16 | #include <linux/device.h> | 16 | #include <linux/device.h> |
17 | #include <linux/suspend.h> | 17 | #include <linux/suspend.h> |
18 | #include <linux/reboot.h> | ||
18 | 19 | ||
19 | #include <asm/io.h> | 20 | #include <asm/io.h> |
20 | 21 | ||
@@ -25,6 +26,36 @@ | |||
25 | u8 sleep_states[ACPI_S_STATE_COUNT]; | 26 | u8 sleep_states[ACPI_S_STATE_COUNT]; |
26 | static u32 acpi_target_sleep_state = ACPI_STATE_S0; | 27 | static u32 acpi_target_sleep_state = ACPI_STATE_S0; |
27 | 28 | ||
29 | static void acpi_sleep_tts_switch(u32 acpi_state) | ||
30 | { | ||
31 | union acpi_object in_arg = { ACPI_TYPE_INTEGER }; | ||
32 | struct acpi_object_list arg_list = { 1, &in_arg }; | ||
33 | acpi_status status = AE_OK; | ||
34 | |||
35 | in_arg.integer.value = acpi_state; | ||
36 | status = acpi_evaluate_object(NULL, "\\_TTS", &arg_list, NULL); | ||
37 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { | ||
38 | /* | ||
39 | * OS can't evaluate the _TTS object correctly. Some warning | ||
40 | * message will be printed. But it won't break anything. | ||
41 | */ | ||
42 | printk(KERN_NOTICE "Failure in evaluating _TTS object\n"); | ||
43 | } | ||
44 | } | ||
45 | |||
46 | static int tts_notify_reboot(struct notifier_block *this, | ||
47 | unsigned long code, void *x) | ||
48 | { | ||
49 | acpi_sleep_tts_switch(ACPI_STATE_S5); | ||
50 | return NOTIFY_DONE; | ||
51 | } | ||
52 | |||
53 | static struct notifier_block tts_notifier = { | ||
54 | .notifier_call = tts_notify_reboot, | ||
55 | .next = NULL, | ||
56 | .priority = 0, | ||
57 | }; | ||
58 | |||
28 | static int acpi_sleep_prepare(u32 acpi_state) | 59 | static int acpi_sleep_prepare(u32 acpi_state) |
29 | { | 60 | { |
30 | #ifdef CONFIG_ACPI_SLEEP | 61 | #ifdef CONFIG_ACPI_SLEEP |
@@ -130,6 +161,7 @@ static void acpi_pm_end(void) | |||
130 | * failing transition to a sleep state. | 161 | * failing transition to a sleep state. |
131 | */ | 162 | */ |
132 | acpi_target_sleep_state = ACPI_STATE_S0; | 163 | acpi_target_sleep_state = ACPI_STATE_S0; |
164 | acpi_sleep_tts_switch(acpi_target_sleep_state); | ||
133 | } | 165 | } |
134 | #endif /* CONFIG_ACPI_SLEEP */ | 166 | #endif /* CONFIG_ACPI_SLEEP */ |
135 | 167 | ||
@@ -154,6 +186,7 @@ static int acpi_suspend_begin(suspend_state_t pm_state) | |||
154 | 186 | ||
155 | if (sleep_states[acpi_state]) { | 187 | if (sleep_states[acpi_state]) { |
156 | acpi_target_sleep_state = acpi_state; | 188 | acpi_target_sleep_state = acpi_state; |
189 | acpi_sleep_tts_switch(acpi_target_sleep_state); | ||
157 | } else { | 190 | } else { |
158 | printk(KERN_ERR "ACPI does not support this state: %d\n", | 191 | printk(KERN_ERR "ACPI does not support this state: %d\n", |
159 | pm_state); | 192 | pm_state); |
@@ -199,6 +232,8 @@ static int acpi_suspend_enter(suspend_state_t pm_state) | |||
199 | break; | 232 | break; |
200 | } | 233 | } |
201 | 234 | ||
235 | /* If ACPI is not enabled by the BIOS, we need to enable it here. */ | ||
236 | acpi_enable(); | ||
202 | /* Reprogram control registers and execute _BFS */ | 237 | /* Reprogram control registers and execute _BFS */ |
203 | acpi_leave_sleep_state_prep(acpi_state); | 238 | acpi_leave_sleep_state_prep(acpi_state); |
204 | 239 | ||
@@ -295,6 +330,14 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = { | |||
295 | DMI_MATCH(DMI_BOARD_NAME, "KN9 Series(NF-CK804)"), | 330 | DMI_MATCH(DMI_BOARD_NAME, "KN9 Series(NF-CK804)"), |
296 | }, | 331 | }, |
297 | }, | 332 | }, |
333 | { | ||
334 | .callback = init_old_suspend_ordering, | ||
335 | .ident = "HP xw4600 Workstation", | ||
336 | .matches = { | ||
337 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
338 | DMI_MATCH(DMI_PRODUCT_NAME, "HP xw4600 Workstation"), | ||
339 | }, | ||
340 | }, | ||
298 | {}, | 341 | {}, |
299 | }; | 342 | }; |
300 | #endif /* CONFIG_SUSPEND */ | 343 | #endif /* CONFIG_SUSPEND */ |
@@ -312,6 +355,7 @@ void __init acpi_no_s4_hw_signature(void) | |||
312 | static int acpi_hibernation_begin(void) | 355 | static int acpi_hibernation_begin(void) |
313 | { | 356 | { |
314 | acpi_target_sleep_state = ACPI_STATE_S4; | 357 | acpi_target_sleep_state = ACPI_STATE_S4; |
358 | acpi_sleep_tts_switch(acpi_target_sleep_state); | ||
315 | return 0; | 359 | return 0; |
316 | } | 360 | } |
317 | 361 | ||
@@ -375,7 +419,15 @@ static struct platform_hibernation_ops acpi_hibernation_ops = { | |||
375 | */ | 419 | */ |
376 | static int acpi_hibernation_begin_old(void) | 420 | static int acpi_hibernation_begin_old(void) |
377 | { | 421 | { |
378 | int error = acpi_sleep_prepare(ACPI_STATE_S4); | 422 | int error; |
423 | /* | ||
424 | * The _TTS object should always be evaluated before the _PTS object. | ||
425 | * When the old_suspended_ordering is true, the _PTS object is | ||
426 | * evaluated in the acpi_sleep_prepare. | ||
427 | */ | ||
428 | acpi_sleep_tts_switch(ACPI_STATE_S4); | ||
429 | |||
430 | error = acpi_sleep_prepare(ACPI_STATE_S4); | ||
379 | 431 | ||
380 | if (!error) | 432 | if (!error) |
381 | acpi_target_sleep_state = ACPI_STATE_S4; | 433 | acpi_target_sleep_state = ACPI_STATE_S4; |
@@ -595,5 +647,10 @@ int __init acpi_sleep_init(void) | |||
595 | pm_power_off = acpi_power_off; | 647 | pm_power_off = acpi_power_off; |
596 | } | 648 | } |
597 | printk(")\n"); | 649 | printk(")\n"); |
650 | /* | ||
651 | * Register the tts_notifier to reboot notifier list so that the _TTS | ||
652 | * object can also be evaluated when the system enters S5. | ||
653 | */ | ||
654 | register_reboot_notifier(&tts_notifier); | ||
598 | return 0; | 655 | return 0; |
599 | } | 656 | } |