diff options
Diffstat (limited to 'drivers/acpi/sleep')
| -rw-r--r-- | drivers/acpi/sleep/Makefile | 2 | ||||
| -rw-r--r-- | drivers/acpi/sleep/main.c | 57 | ||||
| -rw-r--r-- | drivers/acpi/sleep/poweroff.c | 75 |
3 files changed, 52 insertions, 82 deletions
diff --git a/drivers/acpi/sleep/Makefile b/drivers/acpi/sleep/Makefile index 195a4f69c0f7..ba9bd403d443 100644 --- a/drivers/acpi/sleep/Makefile +++ b/drivers/acpi/sleep/Makefile | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | obj-y := poweroff.o wakeup.o | 1 | obj-y := wakeup.o |
| 2 | obj-$(CONFIG_ACPI_SLEEP) += main.o | 2 | obj-$(CONFIG_ACPI_SLEEP) += main.o |
| 3 | obj-$(CONFIG_ACPI_SLEEP) += proc.o | 3 | obj-$(CONFIG_ACPI_SLEEP) += proc.o |
| 4 | 4 | ||
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 | ||
| 63 | int 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 | ||
| 377 | static void acpi_power_off_prepare(void) | ||
| 378 | { | ||
| 379 | /* Prepare to power off the system */ | ||
| 380 | acpi_sleep_prepare(ACPI_STATE_S5); | ||
| 381 | } | ||
| 382 | |||
| 383 | static 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 | |||
| 353 | int __init acpi_sleep_init(void) | 391 | int __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 | } |
diff --git a/drivers/acpi/sleep/poweroff.c b/drivers/acpi/sleep/poweroff.c deleted file mode 100644 index 39e40d56b034..000000000000 --- a/drivers/acpi/sleep/poweroff.c +++ /dev/null | |||
| @@ -1,75 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * poweroff.c - ACPI handler for powering off the system. | ||
| 3 | * | ||
| 4 | * AKA S5, but it is independent of whether or not the kernel supports | ||
| 5 | * any other sleep support in the system. | ||
| 6 | * | ||
| 7 | * Copyright (c) 2005 Alexey Starikovskiy <alexey.y.starikovskiy@intel.com> | ||
| 8 | * | ||
| 9 | * This file is released under the GPLv2. | ||
| 10 | */ | ||
| 11 | |||
| 12 | #include <linux/pm.h> | ||
| 13 | #include <linux/init.h> | ||
| 14 | #include <acpi/acpi_bus.h> | ||
| 15 | #include <linux/sysdev.h> | ||
| 16 | #include <asm/io.h> | ||
| 17 | #include "sleep.h" | ||
| 18 | |||
| 19 | int acpi_sleep_prepare(u32 acpi_state) | ||
| 20 | { | ||
| 21 | #ifdef CONFIG_ACPI_SLEEP | ||
| 22 | /* do we have a wakeup address for S2 and S3? */ | ||
| 23 | if (acpi_state == ACPI_STATE_S3) { | ||
| 24 | if (!acpi_wakeup_address) { | ||
| 25 | return -EFAULT; | ||
| 26 | } | ||
| 27 | acpi_set_firmware_waking_vector((acpi_physical_address) | ||
| 28 | virt_to_phys((void *) | ||
| 29 | acpi_wakeup_address)); | ||
| 30 | |||
| 31 | } | ||
| 32 | ACPI_FLUSH_CPU_CACHE(); | ||
| 33 | acpi_enable_wakeup_device_prep(acpi_state); | ||
| 34 | #endif | ||
| 35 | acpi_gpe_sleep_prepare(acpi_state); | ||
| 36 | acpi_enter_sleep_state_prep(acpi_state); | ||
| 37 | return 0; | ||
| 38 | } | ||
| 39 | |||
| 40 | #ifdef CONFIG_PM | ||
| 41 | |||
| 42 | static void acpi_power_off_prepare(void) | ||
| 43 | { | ||
| 44 | /* Prepare to power off the system */ | ||
| 45 | acpi_sleep_prepare(ACPI_STATE_S5); | ||
| 46 | } | ||
| 47 | |||
| 48 | static void acpi_power_off(void) | ||
| 49 | { | ||
| 50 | /* acpi_sleep_prepare(ACPI_STATE_S5) should have already been called */ | ||
| 51 | printk("%s called\n", __FUNCTION__); | ||
| 52 | local_irq_disable(); | ||
| 53 | /* Some SMP machines only can poweroff in boot CPU */ | ||
| 54 | acpi_enter_sleep_state(ACPI_STATE_S5); | ||
| 55 | } | ||
| 56 | |||
| 57 | static int acpi_poweroff_init(void) | ||
| 58 | { | ||
| 59 | if (!acpi_disabled) { | ||
| 60 | u8 type_a, type_b; | ||
| 61 | acpi_status status; | ||
| 62 | |||
| 63 | status = | ||
| 64 | acpi_get_sleep_type_data(ACPI_STATE_S5, &type_a, &type_b); | ||
| 65 | if (ACPI_SUCCESS(status)) { | ||
| 66 | pm_power_off_prepare = acpi_power_off_prepare; | ||
| 67 | pm_power_off = acpi_power_off; | ||
| 68 | } | ||
| 69 | } | ||
| 70 | return 0; | ||
| 71 | } | ||
| 72 | |||
| 73 | late_initcall(acpi_poweroff_init); | ||
| 74 | |||
| 75 | #endif /* CONFIG_PM */ | ||
