Commit | Line | Data |
---|---|---|
1da177e4 LT |
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. | |
e2a5b420 AS |
6 | * |
7 | * Copyright (c) 2005 Alexey Starikovskiy <alexey.y.starikovskiy@intel.com> | |
8 | * | |
9 | * This file is released under the GPLv2. | |
1da177e4 LT |
10 | */ |
11 | ||
12 | #include <linux/pm.h> | |
13 | #include <linux/init.h> | |
14 | #include <acpi/acpi_bus.h> | |
e2a5b420 AS |
15 | #include <linux/sysdev.h> |
16 | #include <asm/io.h> | |
1da177e4 LT |
17 | #include "sleep.h" |
18 | ||
e2a5b420 AS |
19 | int acpi_sleep_prepare(u32 acpi_state) |
20 | { | |
e2a5b420 | 21 | /* do we have a wakeup address for S2 and S3? */ |
b01d8684 | 22 | if (acpi_state == ACPI_STATE_S3) { |
e2a5b420 AS |
23 | if (!acpi_wakeup_address) { |
24 | return -EFAULT; | |
25 | } | |
26 | acpi_set_firmware_waking_vector((acpi_physical_address) | |
27 | virt_to_phys((void *) | |
28 | acpi_wakeup_address)); | |
29 | ||
30 | } | |
31 | ACPI_FLUSH_CPU_CACHE(); | |
32 | acpi_enable_wakeup_device_prep(acpi_state); | |
729b4d4c | 33 | acpi_gpe_sleep_prepare(acpi_state); |
e2a5b420 AS |
34 | acpi_enter_sleep_state_prep(acpi_state); |
35 | return 0; | |
36 | } | |
37 | ||
b35c67a4 EB |
38 | #ifdef CONFIG_PM |
39 | ||
bd804eba RW |
40 | static void acpi_power_off_prepare(void) |
41 | { | |
42 | /* Prepare to power off the system */ | |
43 | acpi_sleep_prepare(ACPI_STATE_S5); | |
44 | } | |
45 | ||
46 | static void acpi_power_off(void) | |
1da177e4 | 47 | { |
b35c67a4 | 48 | /* acpi_sleep_prepare(ACPI_STATE_S5) should have already been called */ |
e2a5b420 | 49 | printk("%s called\n", __FUNCTION__); |
e2a5b420 | 50 | local_irq_disable(); |
1da177e4 | 51 | /* Some SMP machines only can poweroff in boot CPU */ |
1da177e4 LT |
52 | acpi_enter_sleep_state(ACPI_STATE_S5); |
53 | } | |
54 | ||
55 | static int acpi_poweroff_init(void) | |
56 | { | |
57 | if (!acpi_disabled) { | |
58 | u8 type_a, type_b; | |
59 | acpi_status status; | |
60 | ||
e2a5b420 AS |
61 | status = |
62 | acpi_get_sleep_type_data(ACPI_STATE_S5, &type_a, &type_b); | |
63 | if (ACPI_SUCCESS(status)) { | |
bd804eba RW |
64 | pm_power_off_prepare = acpi_power_off_prepare; |
65 | pm_power_off = acpi_power_off; | |
e2a5b420 | 66 | } |
1da177e4 LT |
67 | } |
68 | return 0; | |
69 | } | |
70 | ||
71 | late_initcall(acpi_poweroff_init); | |
b35c67a4 | 72 | |
4be44fcd | 73 | #endif /* CONFIG_PM */ |