aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/sleep.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/sleep.c')
-rw-r--r--drivers/acpi/sleep.c46
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
74static 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
79static u32 acpi_target_sleep_state = ACPI_STATE_S0; 86static 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
748static void acpi_sleep_hibernate_setup(void) 746static 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
801int __init acpi_sleep_init(void) 795int __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;