aboutsummaryrefslogtreecommitdiffstats
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);
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 */
214int __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 */
211int acpi_pm_device_run_wake(struct device *phys_dev, bool enable) 243int 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}
236EXPORT_SYMBOL(acpi_pm_device_run_wake); 260EXPORT_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 */
270int __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
458int __acpi_device_run_wake(struct acpi_device *, bool);
458int acpi_pm_device_run_wake(struct device *, bool); 459int acpi_pm_device_run_wake(struct device *, bool);
459#else 460#else
461static inline int __acpi_device_run_wake(struct acpi_device *adev, bool en)
462{
463 return -ENODEV;
464}
460static inline int acpi_pm_device_run_wake(struct device *dev, bool enable) 465static 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
472int __acpi_device_sleep_wake(struct acpi_device *, u32, bool);
467int acpi_pm_device_sleep_wake(struct device *, bool); 473int acpi_pm_device_sleep_wake(struct device *, bool);
468#else 474#else
475static inline int __acpi_device_sleep_wake(struct acpi_device *adev,
476 u32 target_state, bool enable)
477{
478 return -ENODEV;
479}
469static inline int acpi_pm_device_sleep_wake(struct device *dev, bool enable) 480static inline int acpi_pm_device_sleep_wake(struct device *dev, bool enable)
470{ 481{
471 return -ENODEV; 482 return -ENODEV;