diff options
| -rw-r--r-- | drivers/acpi/device_pm.c | 74 | ||||
| -rw-r--r-- | drivers/acpi/sleep.c | 8 | ||||
| -rw-r--r-- | include/acpi/acpi_bus.h | 11 |
3 files changed, 71 insertions, 22 deletions
diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c index 81052981045e..b4f03f91b0b0 100644 --- a/drivers/acpi/device_pm.c +++ b/drivers/acpi/device_pm.c | |||
| @@ -200,38 +200,78 @@ EXPORT_SYMBOL_GPL(acpi_device_power_state); | |||
| 200 | 200 | ||
| 201 | #ifdef CONFIG_PM_RUNTIME | 201 | #ifdef CONFIG_PM_RUNTIME |
| 202 | /** | 202 | /** |
| 203 | * acpi_pm_device_run_wake - Enable/disable remote wakeup for given device. | 203 | * __acpi_device_run_wake - Enable/disable runtime remote wakeup for device. |
| 204 | * @phys_dev: Device to enable/disable the platform to wake up. | 204 | * @adev: ACPI device to enable/disable the remote wakeup for. |
| 205 | * @enable: Whether to enable or disable the wakeup functionality. | 205 | * @enable: Whether to enable or disable the wakeup functionality. |
| 206 | * | 206 | * |
| 207 | * Find the ACPI device object corresponding to @phys_dev and try to | 207 | * Enable/disable the GPE associated with @adev so that it can generate |
| 208 | * enable/disable the GPE associated with it, so that it can generate | 208 | * wakeup signals for the device in response to external (remote) events and |
| 209 | * wakeup signals for the device in response to external (remote) events. | 209 | * enable/disable device wakeup power. |
| 210 | * | ||
| 211 | * Callers must ensure that @adev is a valid ACPI device node before executing | ||
| 212 | * this function. | ||
| 213 | */ | ||
| 214 | int __acpi_device_run_wake(struct acpi_device *adev, bool enable) | ||
| 215 | { | ||
| 216 | struct acpi_device_wakeup *wakeup = &adev->wakeup; | ||
| 217 | |||
| 218 | if (enable) { | ||
| 219 | acpi_status res; | ||
| 220 | int error; | ||
| 221 | |||
| 222 | error = acpi_enable_wakeup_device_power(adev, ACPI_STATE_S0); | ||
| 223 | if (error) | ||
| 224 | return error; | ||
| 225 | |||
| 226 | res = acpi_enable_gpe(wakeup->gpe_device, wakeup->gpe_number); | ||
| 227 | if (ACPI_FAILURE(res)) { | ||
| 228 | acpi_disable_wakeup_device_power(adev); | ||
| 229 | return -EIO; | ||
| 230 | } | ||
| 231 | } else { | ||
| 232 | acpi_disable_gpe(wakeup->gpe_device, wakeup->gpe_number); | ||
| 233 | acpi_disable_wakeup_device_power(adev); | ||
| 234 | } | ||
| 235 | return 0; | ||
| 236 | } | ||
| 237 | |||
| 238 | /** | ||
| 239 | * acpi_pm_device_run_wake - Enable/disable remote wakeup for given device. | ||
| 240 | * @dev: Device to enable/disable the platform to wake up. | ||
| 241 | * @enable: Whether to enable or disable the wakeup functionality. | ||
| 210 | */ | 242 | */ |
| 211 | int acpi_pm_device_run_wake(struct device *phys_dev, bool enable) | 243 | int acpi_pm_device_run_wake(struct device *phys_dev, bool enable) |
| 212 | { | 244 | { |
| 213 | struct acpi_device *dev; | 245 | struct acpi_device *adev; |
| 214 | acpi_handle handle; | 246 | acpi_handle handle; |
| 215 | 247 | ||
| 216 | if (!device_run_wake(phys_dev)) | 248 | if (!device_run_wake(phys_dev)) |
| 217 | return -EINVAL; | 249 | return -EINVAL; |
| 218 | 250 | ||
| 219 | handle = DEVICE_ACPI_HANDLE(phys_dev); | 251 | handle = DEVICE_ACPI_HANDLE(phys_dev); |
| 220 | if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &dev))) { | 252 | if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &adev))) { |
| 221 | dev_dbg(phys_dev, "ACPI handle has no context in %s!\n", | 253 | dev_dbg(phys_dev, "ACPI handle without context in %s!\n", |
| 222 | __func__); | 254 | __func__); |
| 223 | return -ENODEV; | 255 | return -ENODEV; |
| 224 | } | 256 | } |
| 225 | 257 | ||
| 226 | if (enable) { | 258 | return __acpi_device_run_wake(adev, enable); |
| 227 | acpi_enable_wakeup_device_power(dev, ACPI_STATE_S0); | ||
| 228 | acpi_enable_gpe(dev->wakeup.gpe_device, dev->wakeup.gpe_number); | ||
| 229 | } else { | ||
| 230 | acpi_disable_gpe(dev->wakeup.gpe_device, dev->wakeup.gpe_number); | ||
| 231 | acpi_disable_wakeup_device_power(dev); | ||
| 232 | } | ||
| 233 | |||
| 234 | return 0; | ||
| 235 | } | 259 | } |
| 236 | EXPORT_SYMBOL(acpi_pm_device_run_wake); | 260 | EXPORT_SYMBOL(acpi_pm_device_run_wake); |
| 237 | #endif /* CONFIG_PM_RUNTIME */ | 261 | #endif /* CONFIG_PM_RUNTIME */ |
| 262 | |||
| 263 | #ifdef CONFIG_PM_SLEEP | ||
| 264 | /** | ||
| 265 | * __acpi_device_sleep_wake - Enable or disable device to wake up the system. | ||
| 266 | * @dev: Device to enable/desible to wake up the system. | ||
| 267 | * @target_state: System state the device is supposed to wake up from. | ||
| 268 | * @enable: Whether to enable or disable @dev to wake up the system. | ||
| 269 | */ | ||
| 270 | int __acpi_device_sleep_wake(struct acpi_device *adev, u32 target_state, | ||
| 271 | bool enable) | ||
| 272 | { | ||
| 273 | return enable ? | ||
| 274 | acpi_enable_wakeup_device_power(adev, target_state) : | ||
| 275 | acpi_disable_wakeup_device_power(adev); | ||
| 276 | } | ||
| 277 | #endif /* CONFIG_PM_SLEEP */ | ||
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 241304ee4068..77c517f6f6d0 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c | |||
| @@ -724,15 +724,13 @@ int acpi_pm_device_sleep_wake(struct device *dev, bool enable) | |||
| 724 | 724 | ||
| 725 | handle = DEVICE_ACPI_HANDLE(dev); | 725 | handle = DEVICE_ACPI_HANDLE(dev); |
| 726 | if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &adev))) { | 726 | if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &adev))) { |
| 727 | dev_dbg(dev, "ACPI handle has no context in %s!\n", __func__); | 727 | dev_dbg(dev, "ACPI handle without context in %s!\n", __func__); |
| 728 | return -ENODEV; | 728 | return -ENODEV; |
| 729 | } | 729 | } |
| 730 | 730 | ||
| 731 | error = enable ? | 731 | error = __acpi_device_sleep_wake(adev, acpi_target_sleep_state, enable); |
| 732 | acpi_enable_wakeup_device_power(adev, acpi_target_sleep_state) : | ||
| 733 | acpi_disable_wakeup_device_power(adev); | ||
| 734 | if (!error) | 732 | if (!error) |
| 735 | dev_info(dev, "wake-up capability %s by ACPI\n", | 733 | dev_info(dev, "System wakeup %s by ACPI\n", |
| 736 | enable ? "enabled" : "disabled"); | 734 | enable ? "enabled" : "disabled"); |
| 737 | 735 | ||
| 738 | return error; | 736 | return error; |
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index a8080dfe7183..a635942bcd51 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h | |||
| @@ -455,8 +455,13 @@ static inline int acpi_pm_device_sleep_state(struct device *d, int *p, int m) | |||
| 455 | #endif | 455 | #endif |
| 456 | 456 | ||
| 457 | #ifdef CONFIG_PM_RUNTIME | 457 | #ifdef CONFIG_PM_RUNTIME |
| 458 | int __acpi_device_run_wake(struct acpi_device *, bool); | ||
| 458 | int acpi_pm_device_run_wake(struct device *, bool); | 459 | int acpi_pm_device_run_wake(struct device *, bool); |
| 459 | #else | 460 | #else |
| 461 | static inline int __acpi_device_run_wake(struct acpi_device *adev, bool en) | ||
| 462 | { | ||
| 463 | return -ENODEV; | ||
| 464 | } | ||
| 460 | static inline int acpi_pm_device_run_wake(struct device *dev, bool enable) | 465 | static inline int acpi_pm_device_run_wake(struct device *dev, bool enable) |
| 461 | { | 466 | { |
| 462 | return -ENODEV; | 467 | return -ENODEV; |
| @@ -464,8 +469,14 @@ static inline int acpi_pm_device_run_wake(struct device *dev, bool enable) | |||
| 464 | #endif | 469 | #endif |
| 465 | 470 | ||
| 466 | #ifdef CONFIG_PM_SLEEP | 471 | #ifdef CONFIG_PM_SLEEP |
| 472 | int __acpi_device_sleep_wake(struct acpi_device *, u32, bool); | ||
| 467 | int acpi_pm_device_sleep_wake(struct device *, bool); | 473 | int acpi_pm_device_sleep_wake(struct device *, bool); |
| 468 | #else | 474 | #else |
| 475 | static inline int __acpi_device_sleep_wake(struct acpi_device *adev, | ||
| 476 | u32 target_state, bool enable) | ||
| 477 | { | ||
| 478 | return -ENODEV; | ||
| 479 | } | ||
| 469 | static inline int acpi_pm_device_sleep_wake(struct device *dev, bool enable) | 480 | static inline int acpi_pm_device_sleep_wake(struct device *dev, bool enable) |
| 470 | { | 481 | { |
| 471 | return -ENODEV; | 482 | return -ENODEV; |
