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); #ifdef CONFIG_PM_RUNTIME /** - * acpi_pm_device_run_wake - Enable/disable remote wakeup for given device. - * @phys_dev: Device to enable/disable the platform to wake up. + * __acpi_device_run_wake - Enable/disable runtime remote wakeup for device. + * @adev: ACPI device to enable/disable the remote wakeup for. * @enable: Whether to enable or disable the wakeup functionality. * - * Find the ACPI device object corresponding to @phys_dev and try to - * enable/disable the GPE associated with it, so that it can generate - * wakeup signals for the device in response to external (remote) events. + * Enable/disable the GPE associated with @adev so that it can generate + * wakeup signals for the device in response to external (remote) events and + * enable/disable device wakeup power. + * + * Callers must ensure that @adev is a valid ACPI device node before executing + * this function. + */ +int __acpi_device_run_wake(struct acpi_device *adev, bool enable) +{ + struct acpi_device_wakeup *wakeup = &adev->wakeup; + + if (enable) { + acpi_status res; + int error; + + error = acpi_enable_wakeup_device_power(adev, ACPI_STATE_S0); + if (error) + return error; + + res = acpi_enable_gpe(wakeup->gpe_device, wakeup->gpe_number); + if (ACPI_FAILURE(res)) { + acpi_disable_wakeup_device_power(adev); + return -EIO; + } + } else { + acpi_disable_gpe(wakeup->gpe_device, wakeup->gpe_number); + acpi_disable_wakeup_device_power(adev); + } + return 0; +} + +/** + * acpi_pm_device_run_wake - Enable/disable remote wakeup for given device. + * @dev: Device to enable/disable the platform to wake up. + * @enable: Whether to enable or disable the wakeup functionality. */ int acpi_pm_device_run_wake(struct device *phys_dev, bool enable) { - struct acpi_device *dev; + struct acpi_device *adev; acpi_handle handle; if (!device_run_wake(phys_dev)) return -EINVAL; handle = DEVICE_ACPI_HANDLE(phys_dev); - if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &dev))) { - dev_dbg(phys_dev, "ACPI handle has no context in %s!\n", + if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &adev))) { + dev_dbg(phys_dev, "ACPI handle without context in %s!\n", __func__); return -ENODEV; } - if (enable) { - acpi_enable_wakeup_device_power(dev, ACPI_STATE_S0); - acpi_enable_gpe(dev->wakeup.gpe_device, dev->wakeup.gpe_number); - } else { - acpi_disable_gpe(dev->wakeup.gpe_device, dev->wakeup.gpe_number); - acpi_disable_wakeup_device_power(dev); - } - - return 0; + return __acpi_device_run_wake(adev, enable); } EXPORT_SYMBOL(acpi_pm_device_run_wake); #endif /* CONFIG_PM_RUNTIME */ + + #ifdef CONFIG_PM_SLEEP +/** + * __acpi_device_sleep_wake - Enable or disable device to wake up the system. + * @dev: Device to enable/desible to wake up the system. + * @target_state: System state the device is supposed to wake up from. + * @enable: Whether to enable or disable @dev to wake up the system. + */ +int __acpi_device_sleep_wake(struct acpi_device *adev, u32 target_state, + bool enable) +{ + return enable ? + acpi_enable_wakeup_device_power(adev, target_state) : + acpi_disable_wakeup_device_power(adev); +} +#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) handle = DEVICE_ACPI_HANDLE(dev); if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &adev))) { - dev_dbg(dev, "ACPI handle has no context in %s!\n", __func__); + dev_dbg(dev, "ACPI handle without context in %s!\n", __func__); return -ENODEV; } - error = enable ? - acpi_enable_wakeup_device_power(adev, acpi_target_sleep_state) : - acpi_disable_wakeup_device_power(adev); + error = __acpi_device_sleep_wake(adev, acpi_target_sleep_state, enable); if (!error) - dev_info(dev, "wake-up capability %s by ACPI\n", + dev_info(dev, "System wakeup %s by ACPI\n", enable ? "enabled" : "disabled"); 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) #endif #ifdef CONFIG_PM_RUNTIME +int __acpi_device_run_wake(struct acpi_device *, bool); int acpi_pm_device_run_wake(struct device *, bool); #else +static inline int __acpi_device_run_wake(struct acpi_device *adev, bool en) +{ + return -ENODEV; +} static inline int acpi_pm_device_run_wake(struct device *dev, bool enable) { return -ENODEV; @@ -464,8 +469,14 @@ static inline int acpi_pm_device_run_wake(struct device *dev, bool enable) #endif #ifdef CONFIG_PM_SLEEP +int __acpi_device_sleep_wake(struct acpi_device *, u32, bool); int acpi_pm_device_sleep_wake(struct device *, bool); #else +static inline int __acpi_device_sleep_wake(struct acpi_device *adev, + u32 target_state, bool enable) +{ + return -ENODEV; +} static inline int acpi_pm_device_sleep_wake(struct device *dev, bool enable) { return -ENODEV; |