aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-08-03 15:32:49 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2017-08-03 15:32:49 -0400
commit73784fb73be6fc0a5a204468bc39a2b95f28424b (patch)
tree8c1816283e05bb7fadf2ae2fb4b9857c7613f356
parent19ec50a438c2ea3e370f6d453bf2f2e6e45ef72b (diff)
parent78aa904a773bfd008606c2065709e23173180ace (diff)
Merge tag 'pm-4.13-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull power management fixes from Rafael Wysocki: "These fix two cpufreq issues, one introduced recently and one related to recent changes, fix cpufreq documentation, fix up recently added code in the Thunderbolt driver and update runtime PM framework documentation. Specifics: - Fix the handling of the scaling_cur_freq cpufreq policy attribute on x86 systems with the MPERF/APERF registers present to make it behave more as expected after recent changes (Rafael Wysocki). - Drop a leftover callback from the intel_pstate driver which also prevents the cpuinfo_cur_freq cpufreq policy attribute from being incorrectly exposed when intel_pstate works in the active mode (Rafael Wysocki). - Add a missing piece describing the cpuinfo_cur_freq policy attribute to cpufreq documentation (Rafael Wysocki). - Fix up a recently added part of the Thunderbolt driver to avoid aborting system suspends if its mailbox commands time out (Rafael Wysocki). - Update device runtime PM framework documentation to reflect the current behavior of the code (Johan Hovold)" * tag 'pm-4.13-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: thunderbolt: icm: Ignore mailbox errors in icm_suspend() cpufreq: x86: Make scaling_cur_freq behave more as expected PM / runtime: Document new pm_runtime_set_suspended() constraint cpufreq: docs: Add missing cpuinfo_cur_freq description cpufreq: intel_pstate: Drop ->get from intel_pstate structure
-rw-r--r--Documentation/admin-guide/pm/cpufreq.rst8
-rw-r--r--Documentation/power/runtime_pm.txt3
-rw-r--r--arch/x86/kernel/cpu/aperfmperf.c40
-rw-r--r--drivers/cpufreq/intel_pstate.c8
-rw-r--r--drivers/thunderbolt/icm.c9
5 files changed, 44 insertions, 24 deletions
diff --git a/Documentation/admin-guide/pm/cpufreq.rst b/Documentation/admin-guide/pm/cpufreq.rst
index 463cf7e73db8..7af83a92d2d6 100644
--- a/Documentation/admin-guide/pm/cpufreq.rst
+++ b/Documentation/admin-guide/pm/cpufreq.rst
@@ -237,6 +237,14 @@ are the following:
237 This attribute is not present if the scaling driver in use does not 237 This attribute is not present if the scaling driver in use does not
238 support it. 238 support it.
239 239
240``cpuinfo_cur_freq``
241 Current frequency of the CPUs belonging to this policy as obtained from
242 the hardware (in KHz).
243
244 This is expected to be the frequency the hardware actually runs at.
245 If that frequency cannot be determined, this attribute should not
246 be present.
247
240``cpuinfo_max_freq`` 248``cpuinfo_max_freq``
241 Maximum possible operating frequency the CPUs belonging to this policy 249 Maximum possible operating frequency the CPUs belonging to this policy
242 can run at (in kHz). 250 can run at (in kHz).
diff --git a/Documentation/power/runtime_pm.txt b/Documentation/power/runtime_pm.txt
index 0fde3dcf077a..625549d4c74a 100644
--- a/Documentation/power/runtime_pm.txt
+++ b/Documentation/power/runtime_pm.txt
@@ -435,7 +435,8 @@ drivers/base/power/runtime.c and include/linux/pm_runtime.h:
435 PM status to 'suspended' and update its parent's counter of 'active' 435 PM status to 'suspended' and update its parent's counter of 'active'
436 children as appropriate (it is only valid to use this function if 436 children as appropriate (it is only valid to use this function if
437 'power.runtime_error' is set or 'power.disable_depth' is greater than 437 'power.runtime_error' is set or 'power.disable_depth' is greater than
438 zero) 438 zero); it will fail and return an error code if the device has a child
439 which is active and the 'power.ignore_children' flag is unset
439 440
440 bool pm_runtime_active(struct device *dev); 441 bool pm_runtime_active(struct device *dev);
441 - return true if the device's runtime PM status is 'active' or its 442 - return true if the device's runtime PM status is 'active' or its
diff --git a/arch/x86/kernel/cpu/aperfmperf.c b/arch/x86/kernel/cpu/aperfmperf.c
index d869c8671e36..7cf7c70b6ef2 100644
--- a/arch/x86/kernel/cpu/aperfmperf.c
+++ b/arch/x86/kernel/cpu/aperfmperf.c
@@ -8,20 +8,25 @@
8 * This file is licensed under GPLv2. 8 * This file is licensed under GPLv2.
9 */ 9 */
10 10
11#include <linux/jiffies.h> 11#include <linux/delay.h>
12#include <linux/ktime.h>
12#include <linux/math64.h> 13#include <linux/math64.h>
13#include <linux/percpu.h> 14#include <linux/percpu.h>
14#include <linux/smp.h> 15#include <linux/smp.h>
15 16
16struct aperfmperf_sample { 17struct aperfmperf_sample {
17 unsigned int khz; 18 unsigned int khz;
18 unsigned long jiffies; 19 ktime_t time;
19 u64 aperf; 20 u64 aperf;
20 u64 mperf; 21 u64 mperf;
21}; 22};
22 23
23static DEFINE_PER_CPU(struct aperfmperf_sample, samples); 24static DEFINE_PER_CPU(struct aperfmperf_sample, samples);
24 25
26#define APERFMPERF_CACHE_THRESHOLD_MS 10
27#define APERFMPERF_REFRESH_DELAY_MS 20
28#define APERFMPERF_STALE_THRESHOLD_MS 1000
29
25/* 30/*
26 * aperfmperf_snapshot_khz() 31 * aperfmperf_snapshot_khz()
27 * On the current CPU, snapshot APERF, MPERF, and jiffies 32 * On the current CPU, snapshot APERF, MPERF, and jiffies
@@ -33,9 +38,11 @@ static void aperfmperf_snapshot_khz(void *dummy)
33 u64 aperf, aperf_delta; 38 u64 aperf, aperf_delta;
34 u64 mperf, mperf_delta; 39 u64 mperf, mperf_delta;
35 struct aperfmperf_sample *s = this_cpu_ptr(&samples); 40 struct aperfmperf_sample *s = this_cpu_ptr(&samples);
41 ktime_t now = ktime_get();
42 s64 time_delta = ktime_ms_delta(now, s->time);
36 43
37 /* Don't bother re-computing within 10 ms */ 44 /* Don't bother re-computing within the cache threshold time. */
38 if (time_before(jiffies, s->jiffies + HZ/100)) 45 if (time_delta < APERFMPERF_CACHE_THRESHOLD_MS)
39 return; 46 return;
40 47
41 rdmsrl(MSR_IA32_APERF, aperf); 48 rdmsrl(MSR_IA32_APERF, aperf);
@@ -51,22 +58,21 @@ static void aperfmperf_snapshot_khz(void *dummy)
51 if (mperf_delta == 0) 58 if (mperf_delta == 0)
52 return; 59 return;
53 60
54 /* 61 s->time = now;
55 * if (cpu_khz * aperf_delta) fits into ULLONG_MAX, then
56 * khz = (cpu_khz * aperf_delta) / mperf_delta
57 */
58 if (div64_u64(ULLONG_MAX, cpu_khz) > aperf_delta)
59 s->khz = div64_u64((cpu_khz * aperf_delta), mperf_delta);
60 else /* khz = aperf_delta / (mperf_delta / cpu_khz) */
61 s->khz = div64_u64(aperf_delta,
62 div64_u64(mperf_delta, cpu_khz));
63 s->jiffies = jiffies;
64 s->aperf = aperf; 62 s->aperf = aperf;
65 s->mperf = mperf; 63 s->mperf = mperf;
64
65 /* If the previous iteration was too long ago, discard it. */
66 if (time_delta > APERFMPERF_STALE_THRESHOLD_MS)
67 s->khz = 0;
68 else
69 s->khz = div64_u64((cpu_khz * aperf_delta), mperf_delta);
66} 70}
67 71
68unsigned int arch_freq_get_on_cpu(int cpu) 72unsigned int arch_freq_get_on_cpu(int cpu)
69{ 73{
74 unsigned int khz;
75
70 if (!cpu_khz) 76 if (!cpu_khz)
71 return 0; 77 return 0;
72 78
@@ -74,6 +80,12 @@ unsigned int arch_freq_get_on_cpu(int cpu)
74 return 0; 80 return 0;
75 81
76 smp_call_function_single(cpu, aperfmperf_snapshot_khz, NULL, 1); 82 smp_call_function_single(cpu, aperfmperf_snapshot_khz, NULL, 1);
83 khz = per_cpu(samples.khz, cpu);
84 if (khz)
85 return khz;
86
87 msleep(APERFMPERF_REFRESH_DELAY_MS);
88 smp_call_function_single(cpu, aperfmperf_snapshot_khz, NULL, 1);
77 89
78 return per_cpu(samples.khz, cpu); 90 return per_cpu(samples.khz, cpu);
79} 91}
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
index 6cd503525638..0566455f233e 100644
--- a/drivers/cpufreq/intel_pstate.c
+++ b/drivers/cpufreq/intel_pstate.c
@@ -1922,13 +1922,6 @@ static int intel_pstate_init_cpu(unsigned int cpunum)
1922 return 0; 1922 return 0;
1923} 1923}
1924 1924
1925static unsigned int intel_pstate_get(unsigned int cpu_num)
1926{
1927 struct cpudata *cpu = all_cpu_data[cpu_num];
1928
1929 return cpu ? get_avg_frequency(cpu) : 0;
1930}
1931
1932static void intel_pstate_set_update_util_hook(unsigned int cpu_num) 1925static void intel_pstate_set_update_util_hook(unsigned int cpu_num)
1933{ 1926{
1934 struct cpudata *cpu = all_cpu_data[cpu_num]; 1927 struct cpudata *cpu = all_cpu_data[cpu_num];
@@ -2169,7 +2162,6 @@ static struct cpufreq_driver intel_pstate = {
2169 .setpolicy = intel_pstate_set_policy, 2162 .setpolicy = intel_pstate_set_policy,
2170 .suspend = intel_pstate_hwp_save_state, 2163 .suspend = intel_pstate_hwp_save_state,
2171 .resume = intel_pstate_resume, 2164 .resume = intel_pstate_resume,
2172 .get = intel_pstate_get,
2173 .init = intel_pstate_cpu_init, 2165 .init = intel_pstate_cpu_init,
2174 .exit = intel_pstate_cpu_exit, 2166 .exit = intel_pstate_cpu_exit,
2175 .stop_cpu = intel_pstate_stop_cpu, 2167 .stop_cpu = intel_pstate_stop_cpu,
diff --git a/drivers/thunderbolt/icm.c b/drivers/thunderbolt/icm.c
index 8ee340290219..bdaac1ff00a5 100644
--- a/drivers/thunderbolt/icm.c
+++ b/drivers/thunderbolt/icm.c
@@ -904,7 +904,14 @@ static int icm_driver_ready(struct tb *tb)
904 904
905static int icm_suspend(struct tb *tb) 905static int icm_suspend(struct tb *tb)
906{ 906{
907 return nhi_mailbox_cmd(tb->nhi, NHI_MAILBOX_SAVE_DEVS, 0); 907 int ret;
908
909 ret = nhi_mailbox_cmd(tb->nhi, NHI_MAILBOX_SAVE_DEVS, 0);
910 if (ret)
911 tb_info(tb, "Ignoring mailbox command error (%d) in %s\n",
912 ret, __func__);
913
914 return 0;
908} 915}
909 916
910/* 917/*