aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/sleep/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/sleep/main.c')
-rw-r--r--drivers/acpi/sleep/main.c57
1 files changed, 51 insertions, 6 deletions
diff --git a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c
index c52ade816fb4..85633c585aab 100644
--- a/drivers/acpi/sleep/main.c
+++ b/drivers/acpi/sleep/main.c
@@ -15,6 +15,9 @@
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
19#include <asm/io.h>
20
18#include <acpi/acpi_bus.h> 21#include <acpi/acpi_bus.h>
19#include <acpi/acpi_drivers.h> 22#include <acpi/acpi_drivers.h>
20#include "sleep.h" 23#include "sleep.h"
@@ -57,6 +60,27 @@ static int acpi_pm_set_target(suspend_state_t pm_state)
57 return error; 60 return error;
58} 61}
59 62
63int acpi_sleep_prepare(u32 acpi_state)
64{
65#ifdef CONFIG_ACPI_SLEEP
66 /* do we have a wakeup address for S2 and S3? */
67 if (acpi_state == ACPI_STATE_S3) {
68 if (!acpi_wakeup_address) {
69 return -EFAULT;
70 }
71 acpi_set_firmware_waking_vector((acpi_physical_address)
72 virt_to_phys((void *)
73 acpi_wakeup_address));
74
75 }
76 ACPI_FLUSH_CPU_CACHE();
77 acpi_enable_wakeup_device_prep(acpi_state);
78#endif
79 acpi_gpe_sleep_prepare(acpi_state);
80 acpi_enter_sleep_state_prep(acpi_state);
81 return 0;
82}
83
60/** 84/**
61 * acpi_pm_prepare - Do preliminary suspend work. 85 * acpi_pm_prepare - Do preliminary suspend work.
62 * @pm_state: ignored 86 * @pm_state: ignored
@@ -350,6 +374,20 @@ int acpi_pm_device_sleep_state(struct device *dev, int wake, int *d_min_p)
350 return d_max; 374 return d_max;
351} 375}
352 376
377static void acpi_power_off_prepare(void)
378{
379 /* Prepare to power off the system */
380 acpi_sleep_prepare(ACPI_STATE_S5);
381}
382
383static void acpi_power_off(void)
384{
385 /* acpi_sleep_prepare(ACPI_STATE_S5) should have already been called */
386 printk("%s called\n", __FUNCTION__);
387 local_irq_disable();
388 acpi_enter_sleep_state(ACPI_STATE_S5);
389}
390
353int __init acpi_sleep_init(void) 391int __init acpi_sleep_init(void)
354{ 392{
355 acpi_status status; 393 acpi_status status;
@@ -363,16 +401,17 @@ int __init acpi_sleep_init(void)
363 if (acpi_disabled) 401 if (acpi_disabled)
364 return 0; 402 return 0;
365 403
404 sleep_states[ACPI_STATE_S0] = 1;
405 printk(KERN_INFO PREFIX "(supports S0");
406
366#ifdef CONFIG_SUSPEND 407#ifdef CONFIG_SUSPEND
367 printk(KERN_INFO PREFIX "(supports"); 408 for (i = ACPI_STATE_S1; i < ACPI_STATE_S4; i++) {
368 for (i = ACPI_STATE_S0; i < ACPI_STATE_S4; i++) {
369 status = acpi_get_sleep_type_data(i, &type_a, &type_b); 409 status = acpi_get_sleep_type_data(i, &type_a, &type_b);
370 if (ACPI_SUCCESS(status)) { 410 if (ACPI_SUCCESS(status)) {
371 sleep_states[i] = 1; 411 sleep_states[i] = 1;
372 printk(" S%d", i); 412 printk(" S%d", i);
373 } 413 }
374 } 414 }
375 printk(")\n");
376 415
377 pm_set_ops(&acpi_pm_ops); 416 pm_set_ops(&acpi_pm_ops);
378#endif 417#endif
@@ -382,10 +421,16 @@ int __init acpi_sleep_init(void)
382 if (ACPI_SUCCESS(status)) { 421 if (ACPI_SUCCESS(status)) {
383 hibernation_set_ops(&acpi_hibernation_ops); 422 hibernation_set_ops(&acpi_hibernation_ops);
384 sleep_states[ACPI_STATE_S4] = 1; 423 sleep_states[ACPI_STATE_S4] = 1;
424 printk(" S4");
385 } 425 }
386#else
387 sleep_states[ACPI_STATE_S4] = 0;
388#endif 426#endif
389 427 status = acpi_get_sleep_type_data(ACPI_STATE_S5, &type_a, &type_b);
428 if (ACPI_SUCCESS(status)) {
429 sleep_states[ACPI_STATE_S5] = 1;
430 printk(" S5");
431 pm_power_off_prepare = acpi_power_off_prepare;
432 pm_power_off = acpi_power_off;
433 }
434 printk(")\n");
390 return 0; 435 return 0;
391} 436}