aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/acpi/device_pm.c74
-rw-r--r--drivers/acpi/sleep.c8
-rw-r--r--include/acpi/acpi_bus.h11
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;