aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/sleep
diff options
context:
space:
mode:
authorLen Brown <len.brown@intel.com>2008-10-22 23:28:46 -0400
committerLen Brown <len.brown@intel.com>2008-10-22 23:28:46 -0400
commitacd41d36e5a813501da92156f325ce15ddcd58ff (patch)
treedaaca230153261b13e6d1989a977352e2c29a3d4 /drivers/acpi/sleep
parent4dff4e7f6cbcd2722b02dbb394ba87c4e05f8841 (diff)
parent4fb507b6b764195bb7821cf2baa988f6eb677d30 (diff)
Merge branch 'suspend' into test
Diffstat (limited to 'drivers/acpi/sleep')
-rw-r--r--drivers/acpi/sleep/main.c59
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 @@
25u8 sleep_states[ACPI_S_STATE_COUNT]; 26u8 sleep_states[ACPI_S_STATE_COUNT];
26static u32 acpi_target_sleep_state = ACPI_STATE_S0; 27static u32 acpi_target_sleep_state = ACPI_STATE_S0;
27 28
29static 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
46static 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
53static struct notifier_block tts_notifier = {
54 .notifier_call = tts_notify_reboot,
55 .next = NULL,
56 .priority = 0,
57};
58
28static int acpi_sleep_prepare(u32 acpi_state) 59static 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)
312static int acpi_hibernation_begin(void) 355static 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 */
376static int acpi_hibernation_begin_old(void) 420static 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}