aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/power.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/power.c')
-rw-r--r--drivers/acpi/power.c59
1 files changed, 36 insertions, 23 deletions
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c
index d74365d4a6e7..22b297916519 100644
--- a/drivers/acpi/power.c
+++ b/drivers/acpi/power.c
@@ -43,6 +43,9 @@
43#include <linux/seq_file.h> 43#include <linux/seq_file.h>
44#include <acpi/acpi_bus.h> 44#include <acpi/acpi_bus.h>
45#include <acpi/acpi_drivers.h> 45#include <acpi/acpi_drivers.h>
46#include "sleep.h"
47
48#define PREFIX "ACPI: "
46 49
47#define _COMPONENT ACPI_POWER_COMPONENT 50#define _COMPONENT ACPI_POWER_COMPONENT
48ACPI_MODULE_NAME("power"); 51ACPI_MODULE_NAME("power");
@@ -361,17 +364,15 @@ int acpi_device_sleep_wake(struct acpi_device *dev,
361 */ 364 */
362int acpi_enable_wakeup_device_power(struct acpi_device *dev, int sleep_state) 365int acpi_enable_wakeup_device_power(struct acpi_device *dev, int sleep_state)
363{ 366{
364 int i, err; 367 int i, err = 0;
365 368
366 if (!dev || !dev->wakeup.flags.valid) 369 if (!dev || !dev->wakeup.flags.valid)
367 return -EINVAL; 370 return -EINVAL;
368 371
369 /* 372 mutex_lock(&acpi_device_lock);
370 * Do not execute the code below twice in a row without calling 373
371 * acpi_disable_wakeup_device_power() in between for the same device 374 if (dev->wakeup.prepare_count++)
372 */ 375 goto out;
373 if (dev->wakeup.flags.prepared)
374 return 0;
375 376
376 /* Open power resource */ 377 /* Open power resource */
377 for (i = 0; i < dev->wakeup.resources.count; i++) { 378 for (i = 0; i < dev->wakeup.resources.count; i++) {
@@ -379,7 +380,8 @@ int acpi_enable_wakeup_device_power(struct acpi_device *dev, int sleep_state)
379 if (ret) { 380 if (ret) {
380 printk(KERN_ERR PREFIX "Transition power state\n"); 381 printk(KERN_ERR PREFIX "Transition power state\n");
381 dev->wakeup.flags.valid = 0; 382 dev->wakeup.flags.valid = 0;
382 return -ENODEV; 383 err = -ENODEV;
384 goto err_out;
383 } 385 }
384 } 386 }
385 387
@@ -388,9 +390,13 @@ int acpi_enable_wakeup_device_power(struct acpi_device *dev, int sleep_state)
388 * in arbitrary power state afterwards. 390 * in arbitrary power state afterwards.
389 */ 391 */
390 err = acpi_device_sleep_wake(dev, 1, sleep_state, 3); 392 err = acpi_device_sleep_wake(dev, 1, sleep_state, 3);
391 if (!err)
392 dev->wakeup.flags.prepared = 1;
393 393
394 err_out:
395 if (err)
396 dev->wakeup.prepare_count = 0;
397
398 out:
399 mutex_unlock(&acpi_device_lock);
394 return err; 400 return err;
395} 401}
396 402
@@ -402,35 +408,42 @@ int acpi_enable_wakeup_device_power(struct acpi_device *dev, int sleep_state)
402 */ 408 */
403int acpi_disable_wakeup_device_power(struct acpi_device *dev) 409int acpi_disable_wakeup_device_power(struct acpi_device *dev)
404{ 410{
405 int i, ret; 411 int i, err = 0;
406 412
407 if (!dev || !dev->wakeup.flags.valid) 413 if (!dev || !dev->wakeup.flags.valid)
408 return -EINVAL; 414 return -EINVAL;
409 415
416 mutex_lock(&acpi_device_lock);
417
418 if (--dev->wakeup.prepare_count > 0)
419 goto out;
420
410 /* 421 /*
411 * Do not execute the code below twice in a row without calling 422 * Executing the code below even if prepare_count is already zero when
412 * acpi_enable_wakeup_device_power() in between for the same device 423 * the function is called may be useful, for example for initialisation.
413 */ 424 */
414 if (!dev->wakeup.flags.prepared) 425 if (dev->wakeup.prepare_count < 0)
415 return 0; 426 dev->wakeup.prepare_count = 0;
416 427
417 dev->wakeup.flags.prepared = 0; 428 err = acpi_device_sleep_wake(dev, 0, 0, 0);
418 429 if (err)
419 ret = acpi_device_sleep_wake(dev, 0, 0, 0); 430 goto out;
420 if (ret)
421 return ret;
422 431
423 /* Close power resource */ 432 /* Close power resource */
424 for (i = 0; i < dev->wakeup.resources.count; i++) { 433 for (i = 0; i < dev->wakeup.resources.count; i++) {
425 ret = acpi_power_off_device(dev->wakeup.resources.handles[i], dev); 434 int ret = acpi_power_off_device(
435 dev->wakeup.resources.handles[i], dev);
426 if (ret) { 436 if (ret) {
427 printk(KERN_ERR PREFIX "Transition power state\n"); 437 printk(KERN_ERR PREFIX "Transition power state\n");
428 dev->wakeup.flags.valid = 0; 438 dev->wakeup.flags.valid = 0;
429 return -ENODEV; 439 err = -ENODEV;
440 goto out;
430 } 441 }
431 } 442 }
432 443
433 return ret; 444 out:
445 mutex_unlock(&acpi_device_lock);
446 return err;
434} 447}
435 448
436/* -------------------------------------------------------------------------- 449/* --------------------------------------------------------------------------