aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/device_pm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/device_pm.c')
-rw-r--r--drivers/acpi/device_pm.c102
1 files changed, 42 insertions, 60 deletions
diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c
index 993fd31394c8..28938b5a334e 100644
--- a/drivers/acpi/device_pm.c
+++ b/drivers/acpi/device_pm.c
@@ -24,6 +24,7 @@
24#include <linux/pm_qos.h> 24#include <linux/pm_qos.h>
25#include <linux/pm_domain.h> 25#include <linux/pm_domain.h>
26#include <linux/pm_runtime.h> 26#include <linux/pm_runtime.h>
27#include <linux/suspend.h>
27 28
28#include "internal.h" 29#include "internal.h"
29 30
@@ -385,6 +386,12 @@ EXPORT_SYMBOL(acpi_bus_power_manageable);
385#ifdef CONFIG_PM 386#ifdef CONFIG_PM
386static DEFINE_MUTEX(acpi_pm_notifier_lock); 387static DEFINE_MUTEX(acpi_pm_notifier_lock);
387 388
389void acpi_pm_wakeup_event(struct device *dev)
390{
391 pm_wakeup_dev_event(dev, 0, acpi_s2idle_wakeup());
392}
393EXPORT_SYMBOL_GPL(acpi_pm_wakeup_event);
394
388static void acpi_pm_notify_handler(acpi_handle handle, u32 val, void *not_used) 395static void acpi_pm_notify_handler(acpi_handle handle, u32 val, void *not_used)
389{ 396{
390 struct acpi_device *adev; 397 struct acpi_device *adev;
@@ -399,9 +406,9 @@ static void acpi_pm_notify_handler(acpi_handle handle, u32 val, void *not_used)
399 mutex_lock(&acpi_pm_notifier_lock); 406 mutex_lock(&acpi_pm_notifier_lock);
400 407
401 if (adev->wakeup.flags.notifier_present) { 408 if (adev->wakeup.flags.notifier_present) {
402 __pm_wakeup_event(adev->wakeup.ws, 0); 409 pm_wakeup_ws_event(adev->wakeup.ws, 0, acpi_s2idle_wakeup());
403 if (adev->wakeup.context.work.func) 410 if (adev->wakeup.context.func)
404 queue_pm_work(&adev->wakeup.context.work); 411 adev->wakeup.context.func(&adev->wakeup.context);
405 } 412 }
406 413
407 mutex_unlock(&acpi_pm_notifier_lock); 414 mutex_unlock(&acpi_pm_notifier_lock);
@@ -413,7 +420,7 @@ static void acpi_pm_notify_handler(acpi_handle handle, u32 val, void *not_used)
413 * acpi_add_pm_notifier - Register PM notify handler for given ACPI device. 420 * acpi_add_pm_notifier - Register PM notify handler for given ACPI device.
414 * @adev: ACPI device to add the notify handler for. 421 * @adev: ACPI device to add the notify handler for.
415 * @dev: Device to generate a wakeup event for while handling the notification. 422 * @dev: Device to generate a wakeup event for while handling the notification.
416 * @work_func: Work function to execute when handling the notification. 423 * @func: Work function to execute when handling the notification.
417 * 424 *
418 * NOTE: @adev need not be a run-wake or wakeup device to be a valid source of 425 * NOTE: @adev need not be a run-wake or wakeup device to be a valid source of
419 * PM wakeup events. For example, wakeup events may be generated for bridges 426 * PM wakeup events. For example, wakeup events may be generated for bridges
@@ -421,11 +428,11 @@ static void acpi_pm_notify_handler(acpi_handle handle, u32 val, void *not_used)
421 * bridge itself doesn't have a wakeup GPE associated with it. 428 * bridge itself doesn't have a wakeup GPE associated with it.
422 */ 429 */
423acpi_status acpi_add_pm_notifier(struct acpi_device *adev, struct device *dev, 430acpi_status acpi_add_pm_notifier(struct acpi_device *adev, struct device *dev,
424 void (*work_func)(struct work_struct *work)) 431 void (*func)(struct acpi_device_wakeup_context *context))
425{ 432{
426 acpi_status status = AE_ALREADY_EXISTS; 433 acpi_status status = AE_ALREADY_EXISTS;
427 434
428 if (!dev && !work_func) 435 if (!dev && !func)
429 return AE_BAD_PARAMETER; 436 return AE_BAD_PARAMETER;
430 437
431 mutex_lock(&acpi_pm_notifier_lock); 438 mutex_lock(&acpi_pm_notifier_lock);
@@ -435,8 +442,7 @@ acpi_status acpi_add_pm_notifier(struct acpi_device *adev, struct device *dev,
435 442
436 adev->wakeup.ws = wakeup_source_register(dev_name(&adev->dev)); 443 adev->wakeup.ws = wakeup_source_register(dev_name(&adev->dev));
437 adev->wakeup.context.dev = dev; 444 adev->wakeup.context.dev = dev;
438 if (work_func) 445 adev->wakeup.context.func = func;
439 INIT_WORK(&adev->wakeup.context.work, work_func);
440 446
441 status = acpi_install_notify_handler(adev->handle, ACPI_SYSTEM_NOTIFY, 447 status = acpi_install_notify_handler(adev->handle, ACPI_SYSTEM_NOTIFY,
442 acpi_pm_notify_handler, NULL); 448 acpi_pm_notify_handler, NULL);
@@ -469,10 +475,7 @@ acpi_status acpi_remove_pm_notifier(struct acpi_device *adev)
469 if (ACPI_FAILURE(status)) 475 if (ACPI_FAILURE(status))
470 goto out; 476 goto out;
471 477
472 if (adev->wakeup.context.work.func) { 478 adev->wakeup.context.func = NULL;
473 cancel_work_sync(&adev->wakeup.context.work);
474 adev->wakeup.context.work.func = NULL;
475 }
476 adev->wakeup.context.dev = NULL; 479 adev->wakeup.context.dev = NULL;
477 wakeup_source_unregister(adev->wakeup.ws); 480 wakeup_source_unregister(adev->wakeup.ws);
478 481
@@ -493,6 +496,13 @@ bool acpi_bus_can_wakeup(acpi_handle handle)
493} 496}
494EXPORT_SYMBOL(acpi_bus_can_wakeup); 497EXPORT_SYMBOL(acpi_bus_can_wakeup);
495 498
499bool acpi_pm_device_can_wakeup(struct device *dev)
500{
501 struct acpi_device *adev = ACPI_COMPANION(dev);
502
503 return adev ? acpi_device_can_wakeup(adev) : false;
504}
505
496/** 506/**
497 * acpi_dev_pm_get_state - Get preferred power state of ACPI device. 507 * acpi_dev_pm_get_state - Get preferred power state of ACPI device.
498 * @dev: Device whose preferred target power state to return. 508 * @dev: Device whose preferred target power state to return.
@@ -658,16 +668,15 @@ EXPORT_SYMBOL(acpi_pm_device_sleep_state);
658 668
659/** 669/**
660 * acpi_pm_notify_work_func - ACPI devices wakeup notification work function. 670 * acpi_pm_notify_work_func - ACPI devices wakeup notification work function.
661 * @work: Work item to handle. 671 * @context: Device wakeup context.
662 */ 672 */
663static void acpi_pm_notify_work_func(struct work_struct *work) 673static void acpi_pm_notify_work_func(struct acpi_device_wakeup_context *context)
664{ 674{
665 struct device *dev; 675 struct device *dev = context->dev;
666 676
667 dev = container_of(work, struct acpi_device_wakeup_context, work)->dev;
668 if (dev) { 677 if (dev) {
669 pm_wakeup_event(dev, 0); 678 pm_wakeup_event(dev, 0);
670 pm_runtime_resume(dev); 679 pm_request_resume(dev);
671 } 680 }
672} 681}
673 682
@@ -693,80 +702,53 @@ static int acpi_device_wakeup(struct acpi_device *adev, u32 target_state,
693 acpi_status res; 702 acpi_status res;
694 int error; 703 int error;
695 704
705 if (adev->wakeup.flags.enabled)
706 return 0;
707
696 error = acpi_enable_wakeup_device_power(adev, target_state); 708 error = acpi_enable_wakeup_device_power(adev, target_state);
697 if (error) 709 if (error)
698 return error; 710 return error;
699 711
700 if (adev->wakeup.flags.enabled)
701 return 0;
702
703 res = acpi_enable_gpe(wakeup->gpe_device, wakeup->gpe_number); 712 res = acpi_enable_gpe(wakeup->gpe_device, wakeup->gpe_number);
704 if (ACPI_SUCCESS(res)) { 713 if (ACPI_FAILURE(res)) {
705 adev->wakeup.flags.enabled = 1;
706 } else {
707 acpi_disable_wakeup_device_power(adev); 714 acpi_disable_wakeup_device_power(adev);
708 return -EIO; 715 return -EIO;
709 } 716 }
710 } else { 717 adev->wakeup.flags.enabled = 1;
711 if (adev->wakeup.flags.enabled) { 718 } else if (adev->wakeup.flags.enabled) {
712 acpi_disable_gpe(wakeup->gpe_device, wakeup->gpe_number); 719 acpi_disable_gpe(wakeup->gpe_device, wakeup->gpe_number);
713 adev->wakeup.flags.enabled = 0;
714 }
715 acpi_disable_wakeup_device_power(adev); 720 acpi_disable_wakeup_device_power(adev);
721 adev->wakeup.flags.enabled = 0;
716 } 722 }
717 return 0; 723 return 0;
718} 724}
719 725
720/** 726/**
721 * acpi_pm_device_run_wake - Enable/disable remote wakeup for given device. 727 * acpi_pm_set_device_wakeup - Enable/disable remote wakeup for given device.
722 * @dev: Device to enable/disable the platform to wake up. 728 * @dev: Device to enable/disable to generate wakeup events.
723 * @enable: Whether to enable or disable the wakeup functionality. 729 * @enable: Whether to enable or disable the wakeup functionality.
724 */ 730 */
725int acpi_pm_device_run_wake(struct device *phys_dev, bool enable) 731int acpi_pm_set_device_wakeup(struct device *dev, bool enable)
726{
727 struct acpi_device *adev;
728
729 if (!device_run_wake(phys_dev))
730 return -EINVAL;
731
732 adev = ACPI_COMPANION(phys_dev);
733 if (!adev) {
734 dev_dbg(phys_dev, "ACPI companion missing in %s!\n", __func__);
735 return -ENODEV;
736 }
737
738 return acpi_device_wakeup(adev, ACPI_STATE_S0, enable);
739}
740EXPORT_SYMBOL(acpi_pm_device_run_wake);
741
742#ifdef CONFIG_PM_SLEEP
743/**
744 * acpi_pm_device_sleep_wake - Enable or disable device to wake up the system.
745 * @dev: Device to enable/desible to wake up the system from sleep states.
746 * @enable: Whether to enable or disable @dev to wake up the system.
747 */
748int acpi_pm_device_sleep_wake(struct device *dev, bool enable)
749{ 732{
750 struct acpi_device *adev; 733 struct acpi_device *adev;
751 int error; 734 int error;
752 735
753 if (!device_can_wakeup(dev))
754 return -EINVAL;
755
756 adev = ACPI_COMPANION(dev); 736 adev = ACPI_COMPANION(dev);
757 if (!adev) { 737 if (!adev) {
758 dev_dbg(dev, "ACPI companion missing in %s!\n", __func__); 738 dev_dbg(dev, "ACPI companion missing in %s!\n", __func__);
759 return -ENODEV; 739 return -ENODEV;
760 } 740 }
761 741
742 if (!acpi_device_can_wakeup(adev))
743 return -EINVAL;
744
762 error = acpi_device_wakeup(adev, acpi_target_system_state(), enable); 745 error = acpi_device_wakeup(adev, acpi_target_system_state(), enable);
763 if (!error) 746 if (!error)
764 dev_info(dev, "System wakeup %s by ACPI\n", 747 dev_dbg(dev, "Wakeup %s by ACPI\n", enable ? "enabled" : "disabled");
765 enable ? "enabled" : "disabled");
766 748
767 return error; 749 return error;
768} 750}
769#endif /* CONFIG_PM_SLEEP */ 751EXPORT_SYMBOL(acpi_pm_set_device_wakeup);
770 752
771/** 753/**
772 * acpi_dev_pm_low_power - Put ACPI device into a low-power state. 754 * acpi_dev_pm_low_power - Put ACPI device into a low-power state.