aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/power/main.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/base/power/main.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/base/power/main.c')
-rw-r--r--drivers/base/power/main.c40
1 files changed, 21 insertions, 19 deletions
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index 9faee1c893e5..c99f8730de82 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -62,7 +62,7 @@ static pm_message_t pm_transition;
62 62
63static int async_error; 63static int async_error;
64 64
65static char *pm_verb(int event) 65static const char *pm_verb(int event)
66{ 66{
67 switch (event) { 67 switch (event) {
68 case PM_EVENT_SUSPEND: 68 case PM_EVENT_SUSPEND:
@@ -208,7 +208,8 @@ static ktime_t initcall_debug_start(struct device *dev)
208} 208}
209 209
210static void initcall_debug_report(struct device *dev, ktime_t calltime, 210static void initcall_debug_report(struct device *dev, ktime_t calltime,
211 int error, pm_message_t state, char *info) 211 int error, pm_message_t state,
212 const char *info)
212{ 213{
213 ktime_t rettime; 214 ktime_t rettime;
214 s64 nsecs; 215 s64 nsecs;
@@ -403,21 +404,23 @@ static pm_callback_t pm_noirq_op(const struct dev_pm_ops *ops, pm_message_t stat
403 return NULL; 404 return NULL;
404} 405}
405 406
406static void pm_dev_dbg(struct device *dev, pm_message_t state, char *info) 407static void pm_dev_dbg(struct device *dev, pm_message_t state, const char *info)
407{ 408{
408 dev_dbg(dev, "%s%s%s\n", info, pm_verb(state.event), 409 dev_dbg(dev, "%s%s%s\n", info, pm_verb(state.event),
409 ((state.event & PM_EVENT_SLEEP) && device_may_wakeup(dev)) ? 410 ((state.event & PM_EVENT_SLEEP) && device_may_wakeup(dev)) ?
410 ", may wakeup" : ""); 411 ", may wakeup" : "");
411} 412}
412 413
413static void pm_dev_err(struct device *dev, pm_message_t state, char *info, 414static void pm_dev_err(struct device *dev, pm_message_t state, const char *info,
414 int error) 415 int error)
415{ 416{
416 printk(KERN_ERR "PM: Device %s failed to %s%s: error %d\n", 417 printk(KERN_ERR "PM: Device %s failed to %s%s: error %d\n",
417 dev_name(dev), pm_verb(state.event), info, error); 418 dev_name(dev), pm_verb(state.event), info, error);
418} 419}
419 420
420static void dpm_show_time(ktime_t starttime, pm_message_t state, char *info) 421#ifdef CONFIG_PM_DEBUG
422static void dpm_show_time(ktime_t starttime, pm_message_t state,
423 const char *info)
421{ 424{
422 ktime_t calltime; 425 ktime_t calltime;
423 u64 usecs64; 426 u64 usecs64;
@@ -433,9 +436,13 @@ static void dpm_show_time(ktime_t starttime, pm_message_t state, char *info)
433 info ?: "", info ? " " : "", pm_verb(state.event), 436 info ?: "", info ? " " : "", pm_verb(state.event),
434 usecs / USEC_PER_MSEC, usecs % USEC_PER_MSEC); 437 usecs / USEC_PER_MSEC, usecs % USEC_PER_MSEC);
435} 438}
439#else
440static inline void dpm_show_time(ktime_t starttime, pm_message_t state,
441 const char *info) {}
442#endif /* CONFIG_PM_DEBUG */
436 443
437static int dpm_run_callback(pm_callback_t cb, struct device *dev, 444static int dpm_run_callback(pm_callback_t cb, struct device *dev,
438 pm_message_t state, char *info) 445 pm_message_t state, const char *info)
439{ 446{
440 ktime_t calltime; 447 ktime_t calltime;
441 int error; 448 int error;
@@ -535,7 +542,7 @@ static void dpm_watchdog_clear(struct dpm_watchdog *wd)
535static int device_resume_noirq(struct device *dev, pm_message_t state, bool async) 542static int device_resume_noirq(struct device *dev, pm_message_t state, bool async)
536{ 543{
537 pm_callback_t callback = NULL; 544 pm_callback_t callback = NULL;
538 char *info = NULL; 545 const char *info = NULL;
539 int error = 0; 546 int error = 0;
540 547
541 TRACE_DEVICE(dev); 548 TRACE_DEVICE(dev);
@@ -665,7 +672,7 @@ void dpm_resume_noirq(pm_message_t state)
665static int device_resume_early(struct device *dev, pm_message_t state, bool async) 672static int device_resume_early(struct device *dev, pm_message_t state, bool async)
666{ 673{
667 pm_callback_t callback = NULL; 674 pm_callback_t callback = NULL;
668 char *info = NULL; 675 const char *info = NULL;
669 int error = 0; 676 int error = 0;
670 677
671 TRACE_DEVICE(dev); 678 TRACE_DEVICE(dev);
@@ -793,7 +800,7 @@ EXPORT_SYMBOL_GPL(dpm_resume_start);
793static int device_resume(struct device *dev, pm_message_t state, bool async) 800static int device_resume(struct device *dev, pm_message_t state, bool async)
794{ 801{
795 pm_callback_t callback = NULL; 802 pm_callback_t callback = NULL;
796 char *info = NULL; 803 const char *info = NULL;
797 int error = 0; 804 int error = 0;
798 DECLARE_DPM_WATCHDOG_ON_STACK(wd); 805 DECLARE_DPM_WATCHDOG_ON_STACK(wd);
799 806
@@ -955,7 +962,7 @@ void dpm_resume(pm_message_t state)
955static void device_complete(struct device *dev, pm_message_t state) 962static void device_complete(struct device *dev, pm_message_t state)
956{ 963{
957 void (*callback)(struct device *) = NULL; 964 void (*callback)(struct device *) = NULL;
958 char *info = NULL; 965 const char *info = NULL;
959 966
960 if (dev->power.syscore) 967 if (dev->power.syscore)
961 return; 968 return;
@@ -1080,7 +1087,7 @@ static pm_message_t resume_event(pm_message_t sleep_state)
1080static int __device_suspend_noirq(struct device *dev, pm_message_t state, bool async) 1087static int __device_suspend_noirq(struct device *dev, pm_message_t state, bool async)
1081{ 1088{
1082 pm_callback_t callback = NULL; 1089 pm_callback_t callback = NULL;
1083 char *info = NULL; 1090 const char *info = NULL;
1084 int error = 0; 1091 int error = 0;
1085 1092
1086 TRACE_DEVICE(dev); 1093 TRACE_DEVICE(dev);
@@ -1091,11 +1098,6 @@ static int __device_suspend_noirq(struct device *dev, pm_message_t state, bool a
1091 if (async_error) 1098 if (async_error)
1092 goto Complete; 1099 goto Complete;
1093 1100
1094 if (pm_wakeup_pending()) {
1095 async_error = -EBUSY;
1096 goto Complete;
1097 }
1098
1099 if (dev->power.syscore || dev->power.direct_complete) 1101 if (dev->power.syscore || dev->power.direct_complete)
1100 goto Complete; 1102 goto Complete;
1101 1103
@@ -1225,7 +1227,7 @@ int dpm_suspend_noirq(pm_message_t state)
1225static int __device_suspend_late(struct device *dev, pm_message_t state, bool async) 1227static int __device_suspend_late(struct device *dev, pm_message_t state, bool async)
1226{ 1228{
1227 pm_callback_t callback = NULL; 1229 pm_callback_t callback = NULL;
1228 char *info = NULL; 1230 const char *info = NULL;
1229 int error = 0; 1231 int error = 0;
1230 1232
1231 TRACE_DEVICE(dev); 1233 TRACE_DEVICE(dev);
@@ -1384,7 +1386,7 @@ EXPORT_SYMBOL_GPL(dpm_suspend_end);
1384 */ 1386 */
1385static int legacy_suspend(struct device *dev, pm_message_t state, 1387static int legacy_suspend(struct device *dev, pm_message_t state,
1386 int (*cb)(struct device *dev, pm_message_t state), 1388 int (*cb)(struct device *dev, pm_message_t state),
1387 char *info) 1389 const char *info)
1388{ 1390{
1389 int error; 1391 int error;
1390 ktime_t calltime; 1392 ktime_t calltime;
@@ -1426,7 +1428,7 @@ static void dpm_clear_suppliers_direct_complete(struct device *dev)
1426static int __device_suspend(struct device *dev, pm_message_t state, bool async) 1428static int __device_suspend(struct device *dev, pm_message_t state, bool async)
1427{ 1429{
1428 pm_callback_t callback = NULL; 1430 pm_callback_t callback = NULL;
1429 char *info = NULL; 1431 const char *info = NULL;
1430 int error = 0; 1432 int error = 0;
1431 DECLARE_DPM_WATCHDOG_ON_STACK(wd); 1433 DECLARE_DPM_WATCHDOG_ON_STACK(wd);
1432 1434