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.c63
1 files changed, 56 insertions, 7 deletions
diff --git a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c
index e8cff5dd4cbc..2cbb9aabd00e 100644
--- a/drivers/acpi/sleep/main.c
+++ b/drivers/acpi/sleep/main.c
@@ -15,13 +15,39 @@
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"
21 24
22u8 sleep_states[ACPI_S_STATE_COUNT]; 25u8 sleep_states[ACPI_S_STATE_COUNT];
23 26
27#ifdef CONFIG_PM_SLEEP
24static u32 acpi_target_sleep_state = ACPI_STATE_S0; 28static u32 acpi_target_sleep_state = ACPI_STATE_S0;
29#endif
30
31int acpi_sleep_prepare(u32 acpi_state)
32{
33#ifdef CONFIG_ACPI_SLEEP
34 /* do we have a wakeup address for S2 and S3? */
35 if (acpi_state == ACPI_STATE_S3) {
36 if (!acpi_wakeup_address) {
37 return -EFAULT;
38 }
39 acpi_set_firmware_waking_vector((acpi_physical_address)
40 virt_to_phys((void *)
41 acpi_wakeup_address));
42
43 }
44 ACPI_FLUSH_CPU_CACHE();
45 acpi_enable_wakeup_device_prep(acpi_state);
46#endif
47 acpi_gpe_sleep_prepare(acpi_state);
48 acpi_enter_sleep_state_prep(acpi_state);
49 return 0;
50}
25 51
26#ifdef CONFIG_SUSPEND 52#ifdef CONFIG_SUSPEND
27static struct pm_ops acpi_pm_ops; 53static struct pm_ops acpi_pm_ops;
@@ -275,6 +301,7 @@ int acpi_suspend(u32 acpi_state)
275 return -EINVAL; 301 return -EINVAL;
276} 302}
277 303
304#ifdef CONFIG_PM_SLEEP
278/** 305/**
279 * acpi_pm_device_sleep_state - return preferred power state of ACPI device 306 * acpi_pm_device_sleep_state - return preferred power state of ACPI device
280 * in the system sleep state given by %acpi_target_sleep_state 307 * in the system sleep state given by %acpi_target_sleep_state
@@ -305,7 +332,7 @@ int acpi_pm_device_sleep_state(struct device *dev, int wake, int *d_min_p)
305 unsigned long d_min, d_max; 332 unsigned long d_min, d_max;
306 333
307 if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &adev))) { 334 if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &adev))) {
308 printk(KERN_ERR "ACPI handle has no context!\n"); 335 printk(KERN_DEBUG "ACPI handle has no context!\n");
309 return -ENODEV; 336 return -ENODEV;
310 } 337 }
311 338
@@ -349,6 +376,21 @@ int acpi_pm_device_sleep_state(struct device *dev, int wake, int *d_min_p)
349 *d_min_p = d_min; 376 *d_min_p = d_min;
350 return d_max; 377 return d_max;
351} 378}
379#endif
380
381static void acpi_power_off_prepare(void)
382{
383 /* Prepare to power off the system */
384 acpi_sleep_prepare(ACPI_STATE_S5);
385}
386
387static void acpi_power_off(void)
388{
389 /* acpi_sleep_prepare(ACPI_STATE_S5) should have already been called */
390 printk("%s called\n", __FUNCTION__);
391 local_irq_disable();
392 acpi_enter_sleep_state(ACPI_STATE_S5);
393}
352 394
353int __init acpi_sleep_init(void) 395int __init acpi_sleep_init(void)
354{ 396{
@@ -363,16 +405,17 @@ int __init acpi_sleep_init(void)
363 if (acpi_disabled) 405 if (acpi_disabled)
364 return 0; 406 return 0;
365 407
408 sleep_states[ACPI_STATE_S0] = 1;
409 printk(KERN_INFO PREFIX "(supports S0");
410
366#ifdef CONFIG_SUSPEND 411#ifdef CONFIG_SUSPEND
367 printk(KERN_INFO PREFIX "(supports"); 412 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); 413 status = acpi_get_sleep_type_data(i, &type_a, &type_b);
370 if (ACPI_SUCCESS(status)) { 414 if (ACPI_SUCCESS(status)) {
371 sleep_states[i] = 1; 415 sleep_states[i] = 1;
372 printk(" S%d", i); 416 printk(" S%d", i);
373 } 417 }
374 } 418 }
375 printk(")\n");
376 419
377 pm_set_ops(&acpi_pm_ops); 420 pm_set_ops(&acpi_pm_ops);
378#endif 421#endif
@@ -382,10 +425,16 @@ int __init acpi_sleep_init(void)
382 if (ACPI_SUCCESS(status)) { 425 if (ACPI_SUCCESS(status)) {
383 hibernation_set_ops(&acpi_hibernation_ops); 426 hibernation_set_ops(&acpi_hibernation_ops);
384 sleep_states[ACPI_STATE_S4] = 1; 427 sleep_states[ACPI_STATE_S4] = 1;
428 printk(" S4");
385 } 429 }
386#else
387 sleep_states[ACPI_STATE_S4] = 0;
388#endif 430#endif
389 431 status = acpi_get_sleep_type_data(ACPI_STATE_S5, &type_a, &type_b);
432 if (ACPI_SUCCESS(status)) {
433 sleep_states[ACPI_STATE_S5] = 1;
434 printk(" S5");
435 pm_power_off_prepare = acpi_power_off_prepare;
436 pm_power_off = acpi_power_off;
437 }
438 printk(")\n");
390 return 0; 439 return 0;
391} 440}