diff -puN drivers/acpi/sleep/wakeup.c~poweroff-gpe drivers/acpi/sleep/wakeup.c --- 2.6/drivers/acpi/sleep/wakeup.c~poweroff-gpe 2004-11-16 10:36:56.094034984 +0800 +++ 2.6-root/drivers/acpi/sleep/wakeup.c 2004-11-16 11:01:21.933193560 +0800 @@ -1,5 +1,6 @@ /* * wakeup.c - support wakeup devices + * Copyright (C) 2004 Li Shaohua */ #include @@ -147,6 +148,26 @@ acpi_disable_wakeup_device ( spin_unlock(&acpi_device_lock); } +/* + * Disable all wakeup GPEs before power off - some buggy systems require it + */ +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); + } +} + static int __init acpi_wakeup_device_init(void) { struct list_head * node, * next; diff -puN drivers/acpi/sleep/poweroff.c~poweroff-gpe drivers/acpi/sleep/poweroff.c --- 2.6/drivers/acpi/sleep/poweroff.c~poweroff-gpe 2004-11-16 10:36:56.107033008 +0800 +++ 2.6-root/drivers/acpi/sleep/poweroff.c 2004-11-16 10:48:55.381686640 +0800 @@ -16,6 +16,7 @@ acpi_power_off (void) printk("%s called\n",__FUNCTION__); /* Some SMP machines only can poweroff in boot CPU */ set_cpus_allowed(current, cpumask_of_cpu(0)); + acpi_wakeup_gpe_poweroff_prepare(); acpi_enter_sleep_state_prep(ACPI_STATE_S5); ACPI_DISABLE_IRQS(); acpi_enter_sleep_state(ACPI_STATE_S5); diff -puN drivers/acpi/sleep/sleep.h~poweroff-gpe drivers/acpi/sleep/sleep.h --- 2.6/drivers/acpi/sleep/sleep.h~poweroff-gpe 2004-11-16 10:36:56.121030880 +0800 +++ 2.6-root/drivers/acpi/sleep/sleep.h 2004-11-16 10:47:22.363827504 +0800 @@ -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(u8 sleep_state); extern void acpi_disable_wakeup_device(u8 sleep_state); +extern void acpi_wakeup_gpe_poweroff_prepare(void); _