From 4ea08118f10d5cb16459bea6d3795048b4c98564 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 19 Mar 2014 22:02:42 -0700 Subject: [PATCH] 3.10-stable patches added patches: acpi-sleep-add-extra-checks-for-hw-reduced-acpi-mode-sleep-states.patch --- ...or-hw-reduced-acpi-mode-sleep-states.patch | 110 ++++++++++++++++++ queue-3.10/series | 1 + 2 files changed, 111 insertions(+) create mode 100644 queue-3.10/acpi-sleep-add-extra-checks-for-hw-reduced-acpi-mode-sleep-states.patch diff --git a/queue-3.10/acpi-sleep-add-extra-checks-for-hw-reduced-acpi-mode-sleep-states.patch b/queue-3.10/acpi-sleep-add-extra-checks-for-hw-reduced-acpi-mode-sleep-states.patch new file mode 100644 index 00000000000..f13dfd2fdea --- /dev/null +++ b/queue-3.10/acpi-sleep-add-extra-checks-for-hw-reduced-acpi-mode-sleep-states.patch @@ -0,0 +1,110 @@ +From a4e90bed511220ff601d064c9e5d583e91308f65 Mon Sep 17 00:00:00 2001 +From: "Rafael J. Wysocki" +Date: Thu, 13 Mar 2014 22:11:39 +0100 +Subject: ACPI / sleep: Add extra checks for HW Reduced ACPI mode sleep states + +From: "Rafael J. Wysocki" + +commit a4e90bed511220ff601d064c9e5d583e91308f65 upstream. + +If the HW Reduced ACPI mode bit is set in the FADT, ACPICA uses +the optional sleep control and sleep status registers for making +the system enter sleep states (including S5), so it is not possible +to use system sleep states or power it off using ACPI if the HW +Reduced ACPI mode bit is set and those registers are not available. + +For this reason, add a new function, acpi_sleep_state_supported(), +checking if the HW Reduced ACPI mode bit is set and whether or not +system sleep states are usable in that case in addition to checking +the return value of acpi_get_sleep_type_data() and make the ACPI +sleep setup routines use that function to check the availability of +system sleep states. + +Among other things, this prevents the kernel from attempting to +use ACPI for powering off HW Reduced ACPI systems without the sleep +control and sleep status registers, because ACPI power off doesn't +have a chance to work on them. That allows alternative power off +mechanisms that may actually work to be used on those systems. The +affected machines include Dell Venue 8 Pro, Asus T100TA, Haswell +Desktop SDP and Ivy Bridge EP Demo depot. + +References: https://bugzilla.kernel.org/show_bug.cgi?id=70931 +Reported-by: Adam Williamson +Tested-by: Aubrey Li +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/acpi/sleep.c | 32 +++++++++++++++----------------- + 1 file changed, 15 insertions(+), 17 deletions(-) + +--- a/drivers/acpi/sleep.c ++++ b/drivers/acpi/sleep.c +@@ -78,6 +78,17 @@ static int acpi_sleep_prepare(u32 acpi_s + return 0; + } + ++static bool acpi_sleep_state_supported(u8 sleep_state) ++{ ++ acpi_status status; ++ u8 type_a, type_b; ++ ++ status = acpi_get_sleep_type_data(sleep_state, &type_a, &type_b); ++ return ACPI_SUCCESS(status) && (!acpi_gbl_reduced_hardware ++ || (acpi_gbl_FADT.sleep_control.address ++ && acpi_gbl_FADT.sleep_status.address)); ++} ++ + #ifdef CONFIG_ACPI_SLEEP + static u32 acpi_target_sleep_state = ACPI_STATE_S0; + +@@ -600,15 +611,9 @@ static void acpi_sleep_suspend_setup(voi + { + int i; + +- for (i = ACPI_STATE_S1; i < ACPI_STATE_S4; i++) { +- acpi_status status; +- u8 type_a, type_b; +- +- status = acpi_get_sleep_type_data(i, &type_a, &type_b); +- if (ACPI_SUCCESS(status)) { ++ for (i = ACPI_STATE_S1; i < ACPI_STATE_S4; i++) ++ if (acpi_sleep_state_supported(i)) + sleep_states[i] = 1; +- } +- } + + suspend_set_ops(old_suspend_ordering ? + &acpi_suspend_ops_old : &acpi_suspend_ops); +@@ -739,11 +744,7 @@ static const struct platform_hibernation + + static void acpi_sleep_hibernate_setup(void) + { +- acpi_status status; +- u8 type_a, type_b; +- +- status = acpi_get_sleep_type_data(ACPI_STATE_S4, &type_a, &type_b); +- if (ACPI_FAILURE(status)) ++ if (!acpi_sleep_state_supported(ACPI_STATE_S4)) + return; + + hibernation_set_ops(old_suspend_ordering ? +@@ -792,8 +793,6 @@ static void acpi_power_off(void) + + int __init acpi_sleep_init(void) + { +- acpi_status status; +- u8 type_a, type_b; + char supported[ACPI_S_STATE_COUNT * 3 + 1]; + char *pos = supported; + int i; +@@ -808,8 +807,7 @@ int __init acpi_sleep_init(void) + acpi_sleep_suspend_setup(); + acpi_sleep_hibernate_setup(); + +- status = acpi_get_sleep_type_data(ACPI_STATE_S5, &type_a, &type_b); +- if (ACPI_SUCCESS(status)) { ++ if (acpi_sleep_state_supported(ACPI_STATE_S5)) { + sleep_states[ACPI_STATE_S5] = 1; + pm_power_off_prepare = acpi_power_off_prepare; + pm_power_off = acpi_power_off; diff --git a/queue-3.10/series b/queue-3.10/series index ce4ff211049..973d09df85d 100644 --- a/queue-3.10/series +++ b/queue-3.10/series @@ -49,3 +49,4 @@ libata-add-ata_horkage_broken_fpdma_aa-quirk-for-seagate-momentus-spinpoint-m8-2 spi-spi-ath79-fix-initial-gpio-cs-line-setup.patch nfs-fix-a-delegation-callback-race.patch nfsv4-nfs4_stateid_is_current-should-return-true-for-an-invalid-stateid.patch +acpi-sleep-add-extra-checks-for-hw-reduced-acpi-mode-sleep-states.patch -- 2.47.3