diff options
Diffstat (limited to 'drivers/acpi')
-rw-r--r-- | drivers/acpi/bus.c | 11 | ||||
-rw-r--r-- | drivers/acpi/glue.c | 2 | ||||
-rw-r--r-- | drivers/acpi/sleep/main.c | 25 | ||||
-rw-r--r-- | drivers/acpi/sleep/wakeup.c | 11 |
4 files changed, 45 insertions, 4 deletions
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index b9b69d9629b5..fc1110d6a078 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c | |||
@@ -306,6 +306,17 @@ bool acpi_bus_power_manageable(acpi_handle handle) | |||
306 | 306 | ||
307 | EXPORT_SYMBOL(acpi_bus_power_manageable); | 307 | EXPORT_SYMBOL(acpi_bus_power_manageable); |
308 | 308 | ||
309 | bool acpi_bus_can_wakeup(acpi_handle handle) | ||
310 | { | ||
311 | struct acpi_device *device; | ||
312 | int result; | ||
313 | |||
314 | result = acpi_bus_get_device(handle, &device); | ||
315 | return result ? false : device->wakeup.flags.valid; | ||
316 | } | ||
317 | |||
318 | EXPORT_SYMBOL(acpi_bus_can_wakeup); | ||
319 | |||
309 | /* -------------------------------------------------------------------------- | 320 | /* -------------------------------------------------------------------------- |
310 | Event Management | 321 | Event Management |
311 | -------------------------------------------------------------------------- */ | 322 | -------------------------------------------------------------------------- */ |
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index 06f8634fe58b..87c5d456e180 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c | |||
@@ -166,6 +166,8 @@ static int acpi_bind_one(struct device *dev, acpi_handle handle) | |||
166 | "firmware_node"); | 166 | "firmware_node"); |
167 | ret = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj, | 167 | ret = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj, |
168 | "physical_node"); | 168 | "physical_node"); |
169 | if (acpi_dev->wakeup.flags.valid) | ||
170 | device_set_wakeup_capable(dev, true); | ||
169 | } | 171 | } |
170 | 172 | ||
171 | return 0; | 173 | return 0; |
diff --git a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c index 4addf8ad50ae..af7f4663deaa 100644 --- a/drivers/acpi/sleep/main.c +++ b/drivers/acpi/sleep/main.c | |||
@@ -468,6 +468,31 @@ int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p) | |||
468 | *d_min_p = d_min; | 468 | *d_min_p = d_min; |
469 | return d_max; | 469 | return d_max; |
470 | } | 470 | } |
471 | |||
472 | /** | ||
473 | * acpi_pm_device_sleep_wake - enable or disable the system wake-up | ||
474 | * capability of given device | ||
475 | * @dev: device to handle | ||
476 | * @enable: 'true' - enable, 'false' - disable the wake-up capability | ||
477 | */ | ||
478 | int acpi_pm_device_sleep_wake(struct device *dev, bool enable) | ||
479 | { | ||
480 | acpi_handle handle; | ||
481 | struct acpi_device *adev; | ||
482 | |||
483 | if (!device_may_wakeup(dev)) | ||
484 | return -EINVAL; | ||
485 | |||
486 | handle = DEVICE_ACPI_HANDLE(dev); | ||
487 | if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &adev))) { | ||
488 | printk(KERN_DEBUG "ACPI handle has no context!\n"); | ||
489 | return -ENODEV; | ||
490 | } | ||
491 | |||
492 | return enable ? | ||
493 | acpi_enable_wakeup_device_power(adev, acpi_target_sleep_state) : | ||
494 | acpi_disable_wakeup_device_power(adev); | ||
495 | } | ||
471 | #endif | 496 | #endif |
472 | 497 | ||
473 | static void acpi_power_off_prepare(void) | 498 | static void acpi_power_off_prepare(void) |
diff --git a/drivers/acpi/sleep/wakeup.c b/drivers/acpi/sleep/wakeup.c index 7422a2213944..38655eb132dc 100644 --- a/drivers/acpi/sleep/wakeup.c +++ b/drivers/acpi/sleep/wakeup.c | |||
@@ -66,13 +66,15 @@ void acpi_enable_wakeup_device(u8 sleep_state) | |||
66 | list_for_each_safe(node, next, &acpi_wakeup_device_list) { | 66 | list_for_each_safe(node, next, &acpi_wakeup_device_list) { |
67 | struct acpi_device *dev = | 67 | struct acpi_device *dev = |
68 | container_of(node, struct acpi_device, wakeup_list); | 68 | container_of(node, struct acpi_device, wakeup_list); |
69 | |||
69 | if (!dev->wakeup.flags.valid) | 70 | if (!dev->wakeup.flags.valid) |
70 | continue; | 71 | continue; |
72 | |||
71 | /* If users want to disable run-wake GPE, | 73 | /* If users want to disable run-wake GPE, |
72 | * we only disable it for wake and leave it for runtime | 74 | * we only disable it for wake and leave it for runtime |
73 | */ | 75 | */ |
74 | if (!dev->wakeup.state.enabled || | 76 | if ((!dev->wakeup.state.enabled && !dev->wakeup.flags.prepared) |
75 | sleep_state > (u32) dev->wakeup.sleep_state) { | 77 | || sleep_state > (u32) dev->wakeup.sleep_state) { |
76 | if (dev->wakeup.flags.run_wake) { | 78 | if (dev->wakeup.flags.run_wake) { |
77 | spin_unlock(&acpi_device_lock); | 79 | spin_unlock(&acpi_device_lock); |
78 | /* set_gpe_type will disable GPE, leave it like that */ | 80 | /* set_gpe_type will disable GPE, leave it like that */ |
@@ -110,8 +112,9 @@ void acpi_disable_wakeup_device(u8 sleep_state) | |||
110 | 112 | ||
111 | if (!dev->wakeup.flags.valid) | 113 | if (!dev->wakeup.flags.valid) |
112 | continue; | 114 | continue; |
113 | if (!dev->wakeup.state.enabled || | 115 | |
114 | sleep_state > (u32) dev->wakeup.sleep_state) { | 116 | if ((!dev->wakeup.state.enabled && !dev->wakeup.flags.prepared) |
117 | || sleep_state > (u32) dev->wakeup.sleep_state) { | ||
115 | if (dev->wakeup.flags.run_wake) { | 118 | if (dev->wakeup.flags.run_wake) { |
116 | spin_unlock(&acpi_device_lock); | 119 | spin_unlock(&acpi_device_lock); |
117 | acpi_set_gpe_type(dev->wakeup.gpe_device, | 120 | acpi_set_gpe_type(dev->wakeup.gpe_device, |