diff options
Diffstat (limited to 'drivers/acpi/sleep.c')
-rw-r--r-- | drivers/acpi/sleep.c | 46 |
1 files changed, 17 insertions, 29 deletions
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 721e949e606e..c40fb2e81bbc 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c | |||
@@ -18,12 +18,8 @@ | |||
18 | #include <linux/reboot.h> | 18 | #include <linux/reboot.h> |
19 | #include <linux/acpi.h> | 19 | #include <linux/acpi.h> |
20 | #include <linux/module.h> | 20 | #include <linux/module.h> |
21 | |||
22 | #include <asm/io.h> | 21 | #include <asm/io.h> |
23 | 22 | ||
24 | #include <acpi/acpi_bus.h> | ||
25 | #include <acpi/acpi_drivers.h> | ||
26 | |||
27 | #include "internal.h" | 23 | #include "internal.h" |
28 | #include "sleep.h" | 24 | #include "sleep.h" |
29 | 25 | ||
@@ -75,6 +71,17 @@ static int acpi_sleep_prepare(u32 acpi_state) | |||
75 | return 0; | 71 | return 0; |
76 | } | 72 | } |
77 | 73 | ||
74 | static bool acpi_sleep_state_supported(u8 sleep_state) | ||
75 | { | ||
76 | acpi_status status; | ||
77 | u8 type_a, type_b; | ||
78 | |||
79 | status = acpi_get_sleep_type_data(sleep_state, &type_a, &type_b); | ||
80 | return ACPI_SUCCESS(status) && (!acpi_gbl_reduced_hardware | ||
81 | || (acpi_gbl_FADT.sleep_control.address | ||
82 | && acpi_gbl_FADT.sleep_status.address)); | ||
83 | } | ||
84 | |||
78 | #ifdef CONFIG_ACPI_SLEEP | 85 | #ifdef CONFIG_ACPI_SLEEP |
79 | static u32 acpi_target_sleep_state = ACPI_STATE_S0; | 86 | static u32 acpi_target_sleep_state = ACPI_STATE_S0; |
80 | 87 | ||
@@ -608,15 +615,9 @@ static void acpi_sleep_suspend_setup(void) | |||
608 | { | 615 | { |
609 | int i; | 616 | int i; |
610 | 617 | ||
611 | for (i = ACPI_STATE_S1; i < ACPI_STATE_S4; i++) { | 618 | for (i = ACPI_STATE_S1; i < ACPI_STATE_S4; i++) |
612 | acpi_status status; | 619 | if (acpi_sleep_state_supported(i)) |
613 | u8 type_a, type_b; | ||
614 | |||
615 | status = acpi_get_sleep_type_data(i, &type_a, &type_b); | ||
616 | if (ACPI_SUCCESS(status)) { | ||
617 | sleep_states[i] = 1; | 620 | sleep_states[i] = 1; |
618 | } | ||
619 | } | ||
620 | 621 | ||
621 | suspend_set_ops(old_suspend_ordering ? | 622 | suspend_set_ops(old_suspend_ordering ? |
622 | &acpi_suspend_ops_old : &acpi_suspend_ops); | 623 | &acpi_suspend_ops_old : &acpi_suspend_ops); |
@@ -670,11 +671,8 @@ static void acpi_hibernation_leave(void) | |||
670 | /* Reprogram control registers */ | 671 | /* Reprogram control registers */ |
671 | acpi_leave_sleep_state_prep(ACPI_STATE_S4); | 672 | acpi_leave_sleep_state_prep(ACPI_STATE_S4); |
672 | /* Check the hardware signature */ | 673 | /* Check the hardware signature */ |
673 | if (facs && s4_hardware_signature != facs->hardware_signature) { | 674 | if (facs && s4_hardware_signature != facs->hardware_signature) |
674 | printk(KERN_EMERG "ACPI: Hardware changed while hibernated, " | 675 | pr_crit("ACPI: Hardware changed while hibernated, success doubtful!\n"); |
675 | "cannot resume!\n"); | ||
676 | panic("ACPI S4 hardware signature mismatch"); | ||
677 | } | ||
678 | /* Restore the NVS memory area */ | 676 | /* Restore the NVS memory area */ |
679 | suspend_nvs_restore(); | 677 | suspend_nvs_restore(); |
680 | /* Allow EC transactions to happen. */ | 678 | /* Allow EC transactions to happen. */ |
@@ -747,11 +745,7 @@ static const struct platform_hibernation_ops acpi_hibernation_ops_old = { | |||
747 | 745 | ||
748 | static void acpi_sleep_hibernate_setup(void) | 746 | static void acpi_sleep_hibernate_setup(void) |
749 | { | 747 | { |
750 | acpi_status status; | 748 | if (!acpi_sleep_state_supported(ACPI_STATE_S4)) |
751 | u8 type_a, type_b; | ||
752 | |||
753 | status = acpi_get_sleep_type_data(ACPI_STATE_S4, &type_a, &type_b); | ||
754 | if (ACPI_FAILURE(status)) | ||
755 | return; | 749 | return; |
756 | 750 | ||
757 | hibernation_set_ops(old_suspend_ordering ? | 751 | hibernation_set_ops(old_suspend_ordering ? |
@@ -800,15 +794,10 @@ static void acpi_power_off(void) | |||
800 | 794 | ||
801 | int __init acpi_sleep_init(void) | 795 | int __init acpi_sleep_init(void) |
802 | { | 796 | { |
803 | acpi_status status; | ||
804 | u8 type_a, type_b; | ||
805 | char supported[ACPI_S_STATE_COUNT * 3 + 1]; | 797 | char supported[ACPI_S_STATE_COUNT * 3 + 1]; |
806 | char *pos = supported; | 798 | char *pos = supported; |
807 | int i; | 799 | int i; |
808 | 800 | ||
809 | if (acpi_disabled) | ||
810 | return 0; | ||
811 | |||
812 | acpi_sleep_dmi_check(); | 801 | acpi_sleep_dmi_check(); |
813 | 802 | ||
814 | sleep_states[ACPI_STATE_S0] = 1; | 803 | sleep_states[ACPI_STATE_S0] = 1; |
@@ -816,8 +805,7 @@ int __init acpi_sleep_init(void) | |||
816 | acpi_sleep_suspend_setup(); | 805 | acpi_sleep_suspend_setup(); |
817 | acpi_sleep_hibernate_setup(); | 806 | acpi_sleep_hibernate_setup(); |
818 | 807 | ||
819 | status = acpi_get_sleep_type_data(ACPI_STATE_S5, &type_a, &type_b); | 808 | if (acpi_sleep_state_supported(ACPI_STATE_S5)) { |
820 | if (ACPI_SUCCESS(status)) { | ||
821 | sleep_states[ACPI_STATE_S5] = 1; | 809 | sleep_states[ACPI_STATE_S5] = 1; |
822 | pm_power_off_prepare = acpi_power_off_prepare; | 810 | pm_power_off_prepare = acpi_power_off_prepare; |
823 | pm_power_off = acpi_power_off; | 811 | pm_power_off = acpi_power_off; |