diff options
-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 @@ -obj-y := poweroff.o wakeup.o +obj-y := wakeup.o obj-$(CONFIG_ACPI_SLEEP) += main.o obj-$(CONFIG_ACPI_SLEEP) += proc.o 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 @@ #include <linux/dmi.h> #include <linux/device.h> #include <linux/suspend.h> + +#include <asm/io.h> + #include <acpi/acpi_bus.h> #include <acpi/acpi_drivers.h> #include "sleep.h" @@ -57,6 +60,27 @@ static int acpi_pm_set_target(suspend_state_t pm_state) return error; } +int acpi_sleep_prepare(u32 acpi_state) +{ +#ifdef CONFIG_ACPI_SLEEP + /* do we have a wakeup address for S2 and S3? */ + if (acpi_state == ACPI_STATE_S3) { + if (!acpi_wakeup_address) { + return -EFAULT; + } + acpi_set_firmware_waking_vector((acpi_physical_address) + virt_to_phys((void *) + acpi_wakeup_address)); + + } + ACPI_FLUSH_CPU_CACHE(); + acpi_enable_wakeup_device_prep(acpi_state); +#endif + acpi_gpe_sleep_prepare(acpi_state); + acpi_enter_sleep_state_prep(acpi_state); + return 0; +} + /** * acpi_pm_prepare - Do preliminary suspend work. * @pm_state: ignored @@ -350,6 +374,20 @@ int acpi_pm_device_sleep_state(struct device *dev, int wake, int *d_min_p) return d_max; } +static void acpi_power_off_prepare(void) +{ + /* Prepare to power off the system */ + acpi_sleep_prepare(ACPI_STATE_S5); +} + +static void acpi_power_off(void) +{ + /* acpi_sleep_prepare(ACPI_STATE_S5) should have already been called */ + printk("%s called\n", __FUNCTION__); + local_irq_disable(); + acpi_enter_sleep_state(ACPI_STATE_S5); +} + int __init acpi_sleep_init(void) { acpi_status status; @@ -363,16 +401,17 @@ int __init acpi_sleep_init(void) if (acpi_disabled) return 0; + sleep_states[ACPI_STATE_S0] = 1; + printk(KERN_INFO PREFIX "(supports S0"); + #ifdef CONFIG_SUSPEND - printk(KERN_INFO PREFIX "(supports"); - for (i = ACPI_STATE_S0; i < ACPI_STATE_S4; i++) { + for (i = ACPI_STATE_S1; i < ACPI_STATE_S4; i++) { status = acpi_get_sleep_type_data(i, &type_a, &type_b); if (ACPI_SUCCESS(status)) { sleep_states[i] = 1; printk(" S%d", i); } } - printk(")\n"); pm_set_ops(&acpi_pm_ops); #endif @@ -382,10 +421,16 @@ int __init acpi_sleep_init(void) if (ACPI_SUCCESS(status)) { hibernation_set_ops(&acpi_hibernation_ops); sleep_states[ACPI_STATE_S4] = 1; + printk(" S4"); } -#else - sleep_states[ACPI_STATE_S4] = 0; #endif - + status = acpi_get_sleep_type_data(ACPI_STATE_S5, &type_a, &type_b); + if (ACPI_SUCCESS(status)) { + sleep_states[ACPI_STATE_S5] = 1; + printk(" S5"); + pm_power_off_prepare = acpi_power_off_prepare; + pm_power_off = acpi_power_off; + } + printk(")\n"); return 0; } 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 @@ -/* - * poweroff.c - ACPI handler for powering off the system. - * - * AKA S5, but it is independent of whether or not the kernel supports - * any other sleep support in the system. - * - * Copyright (c) 2005 Alexey Starikovskiy <alexey.y.starikovskiy@intel.com> - * - * This file is released under the GPLv2. - */ - -#include <linux/pm.h> -#include <linux/init.h> -#include <acpi/acpi_bus.h> -#include <linux/sysdev.h> -#include <asm/io.h> -#include "sleep.h" - -int acpi_sleep_prepare(u32 acpi_state) -{ -#ifdef CONFIG_ACPI_SLEEP - /* do we have a wakeup address for S2 and S3? */ - if (acpi_state == ACPI_STATE_S3) { - if (!acpi_wakeup_address) { - return -EFAULT; - } - acpi_set_firmware_waking_vector((acpi_physical_address) - virt_to_phys((void *) - acpi_wakeup_address)); - - } - ACPI_FLUSH_CPU_CACHE(); - acpi_enable_wakeup_device_prep(acpi_state); -#endif - acpi_gpe_sleep_prepare(acpi_state); - acpi_enter_sleep_state_prep(acpi_state); - return 0; -} - -#ifdef CONFIG_PM - -static void acpi_power_off_prepare(void) -{ - /* Prepare to power off the system */ - acpi_sleep_prepare(ACPI_STATE_S5); -} - -static void acpi_power_off(void) -{ - /* acpi_sleep_prepare(ACPI_STATE_S5) should have already been called */ - printk("%s called\n", __FUNCTION__); - local_irq_disable(); - /* Some SMP machines only can poweroff in boot CPU */ - acpi_enter_sleep_state(ACPI_STATE_S5); -} - -static int acpi_poweroff_init(void) -{ - if (!acpi_disabled) { - u8 type_a, type_b; - acpi_status status; - - status = - acpi_get_sleep_type_data(ACPI_STATE_S5, &type_a, &type_b); - if (ACPI_SUCCESS(status)) { - pm_power_off_prepare = acpi_power_off_prepare; - pm_power_off = acpi_power_off; - } - } - return 0; -} - -late_initcall(acpi_poweroff_init); - -#endif /* CONFIG_PM */ |