aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/acpi/power.c24
-rw-r--r--include/acpi/acpi_bus.h1
2 files changed, 23 insertions, 2 deletions
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c
index 2e959aa1ef0e..4ab21cb1c8c7 100644
--- a/drivers/acpi/power.c
+++ b/drivers/acpi/power.c
@@ -363,11 +363,18 @@ int acpi_device_sleep_wake(struct acpi_device *dev,
363 */ 363 */
364int acpi_enable_wakeup_device_power(struct acpi_device *dev, int sleep_state) 364int acpi_enable_wakeup_device_power(struct acpi_device *dev, int sleep_state)
365{ 365{
366 int i; 366 int i, err;
367 367
368 if (!dev || !dev->wakeup.flags.valid) 368 if (!dev || !dev->wakeup.flags.valid)
369 return -EINVAL; 369 return -EINVAL;
370 370
371 /*
372 * Do not execute the code below twice in a row without calling
373 * acpi_disable_wakeup_device_power() in between for the same device
374 */
375 if (dev->wakeup.flags.prepared)
376 return 0;
377
371 /* Open power resource */ 378 /* Open power resource */
372 for (i = 0; i < dev->wakeup.resources.count; i++) { 379 for (i = 0; i < dev->wakeup.resources.count; i++) {
373 int ret = acpi_power_on(dev->wakeup.resources.handles[i], dev); 380 int ret = acpi_power_on(dev->wakeup.resources.handles[i], dev);
@@ -382,7 +389,11 @@ int acpi_enable_wakeup_device_power(struct acpi_device *dev, int sleep_state)
382 * Passing 3 as the third argument below means the device may be placed 389 * Passing 3 as the third argument below means the device may be placed
383 * in arbitrary power state afterwards. 390 * in arbitrary power state afterwards.
384 */ 391 */
385 return acpi_device_sleep_wake(dev, 1, sleep_state, 3); 392 err = acpi_device_sleep_wake(dev, 1, sleep_state, 3);
393 if (!err)
394 dev->wakeup.flags.prepared = 1;
395
396 return err;
386} 397}
387 398
388/* 399/*
@@ -398,6 +409,15 @@ int acpi_disable_wakeup_device_power(struct acpi_device *dev)
398 if (!dev || !dev->wakeup.flags.valid) 409 if (!dev || !dev->wakeup.flags.valid)
399 return -EINVAL; 410 return -EINVAL;
400 411
412 /*
413 * Do not execute the code below twice in a row without calling
414 * acpi_enable_wakeup_device_power() in between for the same device
415 */
416 if (!dev->wakeup.flags.prepared)
417 return 0;
418
419 dev->wakeup.flags.prepared = 0;
420
401 ret = acpi_device_sleep_wake(dev, 0, 0, 0); 421 ret = acpi_device_sleep_wake(dev, 0, 0, 0);
402 if (ret) 422 if (ret)
403 return ret; 423 return ret;
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index 0c21ea3bb672..071daf8db600 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -259,6 +259,7 @@ struct acpi_device_perf {
259/* Wakeup Management */ 259/* Wakeup Management */
260struct acpi_device_wakeup_flags { 260struct acpi_device_wakeup_flags {
261 u8 valid:1; /* Can successfully enable wakeup? */ 261 u8 valid:1; /* Can successfully enable wakeup? */
262 u8 prepared:1; /* Has the wake-up capability been enabled? */
262 u8 run_wake:1; /* Run-Wake GPE devices */ 263 u8 run_wake:1; /* Run-Wake GPE devices */
263}; 264};
264 265