Commit 7e225d7f authored by Len Brown's avatar Len Brown Committed by Len Brown

[ACPI] fix reboot on poweroff regression due to enabled wakeup GPEs

http://bugzilla.kernel.org/show_bug.cgi?id=3669Signed-off-by: default avatarDavid Shaohua Li <shaohua.li@intel.com>
Signed-off-by: default avatarLen Brown <len.brown@intel.com>
parent f3ed4eac
obj-y := poweroff.o obj-y := poweroff.o wakeup.o
obj-$(CONFIG_ACPI_SLEEP) += main.o wakeup.o obj-$(CONFIG_ACPI_SLEEP) += main.o
obj-$(CONFIG_ACPI_SLEEP_PROC_FS) += proc.o obj-$(CONFIG_ACPI_SLEEP_PROC_FS) += proc.o
EXTRA_CFLAGS += $(ACPI_CFLAGS) EXTRA_CFLAGS += $(ACPI_CFLAGS)
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <acpi/acpi_bus.h> #include <acpi/acpi_bus.h>
#include <linux/sched.h> #include <linux/sched.h>
#include "sleep.h"
static void static void
acpi_power_off (void) acpi_power_off (void)
...@@ -16,6 +17,7 @@ acpi_power_off (void) ...@@ -16,6 +17,7 @@ acpi_power_off (void)
printk("%s called\n",__FUNCTION__); printk("%s called\n",__FUNCTION__);
/* Some SMP machines only can poweroff in boot CPU */ /* Some SMP machines only can poweroff in boot CPU */
set_cpus_allowed(current, cpumask_of_cpu(0)); set_cpus_allowed(current, cpumask_of_cpu(0));
acpi_wakeup_gpe_poweroff_prepare();
acpi_enter_sleep_state_prep(ACPI_STATE_S5); acpi_enter_sleep_state_prep(ACPI_STATE_S5);
ACPI_DISABLE_IRQS(); ACPI_DISABLE_IRQS();
acpi_enter_sleep_state(ACPI_STATE_S5); acpi_enter_sleep_state(ACPI_STATE_S5);
......
...@@ -5,3 +5,4 @@ extern int acpi_suspend (u32 state); ...@@ -5,3 +5,4 @@ extern int acpi_suspend (u32 state);
extern void acpi_enable_wakeup_device_prep(u8 sleep_state); extern void acpi_enable_wakeup_device_prep(u8 sleep_state);
extern void acpi_enable_wakeup_device(u8 sleep_state); extern void acpi_enable_wakeup_device(u8 sleep_state);
extern void acpi_disable_wakeup_device(u8 sleep_state); extern void acpi_disable_wakeup_device(u8 sleep_state);
extern void acpi_wakeup_gpe_poweroff_prepare(void);
/* /*
* wakeup.c - support wakeup devices * wakeup.c - support wakeup devices
* Copyright (C) 2004 Li Shaohua <shaohua.li@intel.com>
*/ */
#include <linux/init.h> #include <linux/init.h>
...@@ -13,14 +14,16 @@ ...@@ -13,14 +14,16 @@
#define _COMPONENT ACPI_SYSTEM_COMPONENT #define _COMPONENT ACPI_SYSTEM_COMPONENT
ACPI_MODULE_NAME ("wakeup_devices") ACPI_MODULE_NAME ("wakeup_devices")
extern struct list_head acpi_wakeup_device_list;
extern spinlock_t acpi_device_lock;
#ifdef CONFIG_ACPI_SLEEP
/** /**
* acpi_enable_wakeup_device_prep - prepare wakeup devices * acpi_enable_wakeup_device_prep - prepare wakeup devices
* @sleep_state: ACPI state * @sleep_state: ACPI state
* Enable all wakup devices power if the devices' wakeup level * Enable all wakup devices power if the devices' wakeup level
* is higher than requested sleep level * is higher than requested sleep level
*/ */
extern struct list_head acpi_wakeup_device_list;
extern spinlock_t acpi_device_lock;
void void
acpi_enable_wakeup_device_prep( acpi_enable_wakeup_device_prep(
...@@ -179,3 +182,28 @@ static int __init acpi_wakeup_device_init(void) ...@@ -179,3 +182,28 @@ static int __init acpi_wakeup_device_init(void)
} }
late_initcall(acpi_wakeup_device_init); late_initcall(acpi_wakeup_device_init);
#endif
/*
* Disable all wakeup GPEs before power off.
*
* Since acpi_enter_sleep_state() will disable all
* RUNTIME GPEs, we simply mark all GPES that
* are not enabled for wakeup from S5 as RUNTIME.
*/
void acpi_wakeup_gpe_poweroff_prepare(void)
{
struct list_head * node, * next;
list_for_each_safe(node, next, &acpi_wakeup_device_list) {
struct acpi_device * dev = container_of(node,
struct acpi_device, wakeup_list);
/* The GPE can wakeup system from S5, don't touch it */
if ((u32)dev->wakeup.sleep_state == ACPI_STATE_S5)
continue;
/* acpi_set_gpe_type will automatically disable GPE */
acpi_set_gpe_type(dev->wakeup.gpe_device,
dev->wakeup.gpe_number, ACPI_GPE_TYPE_RUNTIME);
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment