diff options
Diffstat (limited to 'drivers/acpi/wakeup.c')
| -rw-r--r-- | drivers/acpi/wakeup.c | 119 |
1 files changed, 34 insertions, 85 deletions
diff --git a/drivers/acpi/wakeup.c b/drivers/acpi/wakeup.c index e0ee0c036f5..1638401ab28 100644 --- a/drivers/acpi/wakeup.c +++ b/drivers/acpi/wakeup.c @@ -5,7 +5,6 @@ #include <linux/init.h> #include <linux/acpi.h> -#include <acpi/acpi_drivers.h> #include <linux/kernel.h> #include <linux/types.h> @@ -21,75 +20,41 @@ ACPI_MODULE_NAME("wakeup_devices") /** - * acpi_enable_wakeup_device_prep - prepare wakeup devices - * @sleep_state: ACPI state - * Enable all wakup devices power if the devices' wakeup level - * is higher than requested sleep level + * acpi_enable_wakeup_devices - Enable wake-up device GPEs. + * @sleep_state: ACPI system sleep state. + * + * Enable wakeup device power of devices with the state.enable flag set and set + * the wakeup enable mask bits in the GPE registers that correspond to wakeup + * devices. */ - -void acpi_enable_wakeup_device_prep(u8 sleep_state) -{ - 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); - - if (!dev->wakeup.flags.valid || - !dev->wakeup.state.enabled || - (sleep_state > (u32) dev->wakeup.sleep_state)) - continue; - - acpi_enable_wakeup_device_power(dev, sleep_state); - } -} - -/** - * acpi_enable_wakeup_device - enable wakeup devices - * @sleep_state: ACPI state - * Enable all wakup devices's GPE - */ -void acpi_enable_wakeup_device(u8 sleep_state) +void acpi_enable_wakeup_devices(u8 sleep_state) { struct list_head *node, *next; - /* - * Caution: this routine must be invoked when interrupt is disabled - * Refer ACPI2.0: P212 - */ list_for_each_safe(node, next, &acpi_wakeup_device_list) { struct acpi_device *dev = container_of(node, struct acpi_device, wakeup_list); - if (!dev->wakeup.flags.valid) + if (!dev->wakeup.flags.valid + || sleep_state > (u32) dev->wakeup.sleep_state + || !(device_may_wakeup(&dev->dev) + || dev->wakeup.prepare_count)) continue; - /* If users want to disable run-wake GPE, - * we only disable it for wake and leave it for runtime - */ - if ((!dev->wakeup.state.enabled && !dev->wakeup.prepare_count) - || sleep_state > (u32) dev->wakeup.sleep_state) { - if (dev->wakeup.flags.run_wake) { - /* set_gpe_type will disable GPE, leave it like that */ - acpi_set_gpe_type(dev->wakeup.gpe_device, - dev->wakeup.gpe_number, - ACPI_GPE_TYPE_RUNTIME); - } - continue; - } - if (!dev->wakeup.flags.run_wake) - acpi_enable_gpe(dev->wakeup.gpe_device, - dev->wakeup.gpe_number); + if (device_may_wakeup(&dev->dev)) + acpi_enable_wakeup_device_power(dev, sleep_state); + + /* The wake-up power should have been enabled already. */ + acpi_set_gpe_wake_mask(dev->wakeup.gpe_device, dev->wakeup.gpe_number, + ACPI_GPE_ENABLE); } } /** - * acpi_disable_wakeup_device - disable devices' wakeup capability - * @sleep_state: ACPI state - * Disable all wakup devices's GPE and wakeup capability + * acpi_disable_wakeup_devices - Disable devices' wakeup capability. + * @sleep_state: ACPI system sleep state. */ -void acpi_disable_wakeup_device(u8 sleep_state) +void acpi_disable_wakeup_devices(u8 sleep_state) { struct list_head *node, *next; @@ -97,30 +62,17 @@ void acpi_disable_wakeup_device(u8 sleep_state) struct acpi_device *dev = container_of(node, struct acpi_device, wakeup_list); - if (!dev->wakeup.flags.valid) + if (!dev->wakeup.flags.valid + || sleep_state > (u32) dev->wakeup.sleep_state + || !(device_may_wakeup(&dev->dev) + || dev->wakeup.prepare_count)) continue; - if ((!dev->wakeup.state.enabled && !dev->wakeup.prepare_count) - || sleep_state > (u32) dev->wakeup.sleep_state) { - if (dev->wakeup.flags.run_wake) { - acpi_set_gpe_type(dev->wakeup.gpe_device, - dev->wakeup.gpe_number, - ACPI_GPE_TYPE_WAKE_RUN); - /* Re-enable it, since set_gpe_type will disable it */ - acpi_enable_gpe(dev->wakeup.gpe_device, - dev->wakeup.gpe_number); - } - continue; - } + acpi_set_gpe_wake_mask(dev->wakeup.gpe_device, dev->wakeup.gpe_number, + ACPI_GPE_DISABLE); - acpi_disable_wakeup_device_power(dev); - /* Never disable run-wake GPE */ - if (!dev->wakeup.flags.run_wake) { - acpi_disable_gpe(dev->wakeup.gpe_device, - dev->wakeup.gpe_number); - acpi_clear_gpe(dev->wakeup.gpe_device, - dev->wakeup.gpe_number, ACPI_NOT_ISR); - } + if (device_may_wakeup(&dev->dev)) + acpi_disable_wakeup_device_power(dev); } } @@ -133,15 +85,12 @@ int __init acpi_wakeup_device_init(void) struct acpi_device *dev = container_of(node, struct acpi_device, wakeup_list); - /* In case user doesn't load button driver */ - if (!dev->wakeup.flags.run_wake || dev->wakeup.state.enabled) - continue; - acpi_set_gpe_type(dev->wakeup.gpe_device, - dev->wakeup.gpe_number, - ACPI_GPE_TYPE_WAKE_RUN); - acpi_enable_gpe(dev->wakeup.gpe_device, - dev->wakeup.gpe_number); - dev->wakeup.state.enabled = 1; + if (device_can_wakeup(&dev->dev)) { + /* Button GPEs are supposed to be always enabled. */ + acpi_enable_gpe(dev->wakeup.gpe_device, + dev->wakeup.gpe_number); + device_set_wakeup_enable(&dev->dev, true); + } } mutex_unlock(&acpi_device_lock); return 0; |
