aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/device_pm.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-07-04 16:39:41 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2017-07-04 16:39:41 -0400
commit408c9861c6979db974455b9e7a9bcadd60e0934c (patch)
tree9bdb862da2883cd4f74297d01ec8ce3b4619dd66 /drivers/acpi/device_pm.c
parentb39de277b02ffd8e3dccb01e9159bd45cb07b95d (diff)
parent8f8e5c3e2796eaf150d6262115af12707c2616dd (diff)
Merge tag 'pm-4.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull power management updates from Rafael Wysocki: "The big ticket items here are the rework of suspend-to-idle in order to add proper support for power button wakeup from it on recent Dell laptops and the rework of interfaces exporting the current CPU frequency on x86. In addition to that, support for a few new pieces of hardware is added, the PCI/ACPI device wakeup infrastructure is simplified significantly and the wakeup IRQ framework is fixed to unbreak the IRQ bus locking infrastructure. Also, there are some functional improvements for intel_pstate, tools updates and small fixes and cleanups all over. Specifics: - Rework suspend-to-idle to allow it to take wakeup events signaled by the EC into account on ACPI-based platforms in order to properly support power button wakeup from suspend-to-idle on recent Dell laptops (Rafael Wysocki). That includes the core suspend-to-idle code rework, support for the Low Power S0 _DSM interface, and support for the ACPI INT0002 Virtual GPIO device from Hans de Goede (required for USB keyboard wakeup from suspend-to-idle to work on some machines). - Stop trying to export the current CPU frequency via /proc/cpuinfo on x86 as that is inaccurate and confusing (Len Brown). - Rework the way in which the current CPU frequency is exported by the kernel (over the cpufreq sysfs interface) on x86 systems with the APERF and MPERF registers by always using values read from these registers, when available, to compute the current frequency regardless of which cpufreq driver is in use (Len Brown). - Rework the PCI/ACPI device wakeup infrastructure to remove the questionable and artificial distinction between "devices that can wake up the system from sleep states" and "devices that can generate wakeup signals in the working state" from it, which allows the code to be simplified quite a bit (Rafael Wysocki). - Fix the wakeup IRQ framework by making it use SRCU instead of RCU which doesn't allow sleeping in the read-side critical sections, but which in turn is expected to be allowed by the IRQ bus locking infrastructure (Thomas Gleixner). - Modify some computations in the intel_pstate driver to avoid rounding errors resulting from them (Srinivas Pandruvada). - Reduce the overhead of the intel_pstate driver in the HWP (hardware-managed P-states) mode and when the "performance" P-state selection algorithm is in use by making it avoid registering scheduler callbacks in those cases (Len Brown). - Rework the energy_performance_preference sysfs knob in intel_pstate by changing the values that correspond to different symbolic hint names used by it (Len Brown). - Make it possible to use more than one cpuidle driver at the same time on ARM (Daniel Lezcano). - Make it possible to prevent the cpuidle menu governor from using the 0 state by disabling it via sysfs (Nicholas Piggin). - Add support for FFH (Fixed Functional Hardware) MWAIT in ACPI C1 on AMD systems (Yazen Ghannam). - Make the CPPC cpufreq driver take the lowest nonlinear performance information into account (Prashanth Prakash). - Add support for hi3660 to the cpufreq-dt driver, fix the imx6q driver and clean up the sfi, exynos5440 and intel_pstate drivers (Colin Ian King, Krzysztof Kozlowski, Octavian Purdila, Rafael Wysocki, Tao Wang). - Fix a few minor issues in the generic power domains (genpd) framework and clean it up somewhat (Krzysztof Kozlowski, Mikko Perttunen, Viresh Kumar). - Fix a couple of minor issues in the operating performance points (OPP) framework and clean it up somewhat (Viresh Kumar). - Fix a CONFIG dependency in the hibernation core and clean it up slightly (Balbir Singh, Arvind Yadav, BaoJun Luo). - Add rk3228 support to the rockchip-io adaptive voltage scaling (AVS) driver (David Wu). - Fix an incorrect bit shift operation in the RAPL power capping driver (Adam Lessnau). - Add support for the EPP field in the HWP (hardware managed P-states) control register, HWP.EPP, to the x86_energy_perf_policy tool and update msr-index.h with HWP.EPP values (Len Brown). - Fix some minor issues in the turbostat tool (Len Brown). - Add support for AMD family 0x17 CPUs to the cpupower tool and fix a minor issue in it (Sherry Hurwitz). - Assorted cleanups, mostly related to the constification of some data structures (Arvind Yadav, Joe Perches, Kees Cook, Krzysztof Kozlowski)" * tag 'pm-4.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (69 commits) cpufreq: Update scaling_cur_freq documentation cpufreq: intel_pstate: Clean up after performance governor changes PM: hibernate: constify attribute_group structures. cpuidle: menu: allow state 0 to be disabled intel_idle: Use more common logging style PM / Domains: Fix missing default_power_down_ok comment PM / Domains: Fix unsafe iteration over modified list of domains PM / Domains: Fix unsafe iteration over modified list of domain providers PM / Domains: Fix unsafe iteration over modified list of device links PM / Domains: Handle safely genpd_syscore_switch() call on non-genpd device PM / Domains: Call driver's noirq callbacks PM / core: Drop run_wake flag from struct dev_pm_info PCI / PM: Simplify device wakeup settings code PCI / PM: Drop pme_interrupt flag from struct pci_dev ACPI / PM: Consolidate device wakeup settings code ACPI / PM: Drop run_wake from struct acpi_device_wakeup_flags PM / QoS: constify *_attribute_group. PM / AVS: rockchip-io: add io selectors and supplies for rk3228 powercap/RAPL: prevent overridding bits outside of the mask PM / sysfs: Constify attribute groups ...
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.