aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-06-21 16:57:36 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2018-06-21 16:57:36 -0400
commit26c92a38cec99ee7b657901ff64bd01a96a2fb22 (patch)
tree8c5c51b76354a81544c9e1f15d29606f859113eb /drivers
parent1abd8a8f39cd9a2925149000056494523c85643a (diff)
parentb51e001385f1c861445af3efeab766811ee8db29 (diff)
Merge tag 'pm-4.18-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull power management updates from Rafael Wysocki: "These are mostly fixes, including some fixes for changes made during the recent merge window and some "stable" material, plus some minor extensions of the turbostat utility. Specifics: - Fix the PM core to avoid introducing a runtime PM usage counter imbalance when adding device links during driver probe (Rafael Wysocki). - Fix the operating performance points (OPP) framework to ensure that the regulator voltage is always updated as appropriate when updating clock rates (Waldemar Rymarkiewicz). - Fix the intel_pstate driver to use correct max/min limits for cores with differing maximum frequences (Srinivas Pandruvada). - Fix a typo in the intel_pstate driver documentation (Rafael Wysocki). - Fix two issues with the recently added Kryo cpufreq driver (Ilia Lin). - Fix two recent regressions and some other minor issues in the turbostat utility and extend it to provide some more diagnostic information (Len Brown, Nathan Ciobanu)" * tag 'pm-4.18-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: Documentation: intel_pstate: Fix typo tools/power turbostat: version 18.06.20 tools/power turbostat: add the missing command line switches tools/power turbostat: add single character tokens to help tools/power turbostat: alphabetize the help output tools/power turbostat: fix segfault on 'no node' machines tools/power turbostat: add optional APIC X2APIC columns tools/power turbostat: decode cpuid.1.HT tools/power turbostat: fix show/hide issues resulting from mis-merge PM / OPP: Update voltage in case freq == old_freq cpufreq: intel_pstate: Fix scaling max/min limits with Turbo 3.0 cpufreq: kryo: Add module remove and exit cpufreq: kryo: Fix possible error code dereference PM / core: Fix supplier device runtime PM usage counter imbalance
Diffstat (limited to 'drivers')
-rw-r--r--drivers/base/core.c15
-rw-r--r--drivers/cpufreq/intel_pstate.c27
-rw-r--r--drivers/cpufreq/qcom-cpufreq-kryo.c25
-rw-r--r--drivers/opp/core.c2
4 files changed, 56 insertions, 13 deletions
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 36622b52e419..df3e1a44707a 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -236,6 +236,13 @@ struct device_link *device_link_add(struct device *consumer,
236 link->rpm_active = true; 236 link->rpm_active = true;
237 } 237 }
238 pm_runtime_new_link(consumer); 238 pm_runtime_new_link(consumer);
239 /*
240 * If the link is being added by the consumer driver at probe
241 * time, balance the decrementation of the supplier's runtime PM
242 * usage counter after consumer probe in driver_probe_device().
243 */
244 if (consumer->links.status == DL_DEV_PROBING)
245 pm_runtime_get_noresume(supplier);
239 } 246 }
240 get_device(supplier); 247 get_device(supplier);
241 link->supplier = supplier; 248 link->supplier = supplier;
@@ -255,12 +262,12 @@ struct device_link *device_link_add(struct device *consumer,
255 switch (consumer->links.status) { 262 switch (consumer->links.status) {
256 case DL_DEV_PROBING: 263 case DL_DEV_PROBING:
257 /* 264 /*
258 * Balance the decrementation of the supplier's 265 * Some callers expect the link creation during
259 * runtime PM usage counter after consumer probe 266 * consumer driver probe to resume the supplier
260 * in driver_probe_device(). 267 * even without DL_FLAG_RPM_ACTIVE.
261 */ 268 */
262 if (flags & DL_FLAG_PM_RUNTIME) 269 if (flags & DL_FLAG_PM_RUNTIME)
263 pm_runtime_get_sync(supplier); 270 pm_runtime_resume(supplier);
264 271
265 link->status = DL_STATE_CONSUMER_PROBE; 272 link->status = DL_STATE_CONSUMER_PROBE;
266 break; 273 break;
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
index 1de5ec8d5ea3..ece120da3353 100644
--- a/drivers/cpufreq/intel_pstate.c
+++ b/drivers/cpufreq/intel_pstate.c
@@ -294,6 +294,7 @@ struct pstate_funcs {
294static struct pstate_funcs pstate_funcs __read_mostly; 294static struct pstate_funcs pstate_funcs __read_mostly;
295 295
296static int hwp_active __read_mostly; 296static int hwp_active __read_mostly;
297static int hwp_mode_bdw __read_mostly;
297static bool per_cpu_limits __read_mostly; 298static bool per_cpu_limits __read_mostly;
298static bool hwp_boost __read_mostly; 299static bool hwp_boost __read_mostly;
299 300
@@ -1413,7 +1414,15 @@ static void intel_pstate_get_cpu_pstates(struct cpudata *cpu)
1413 cpu->pstate.turbo_pstate = pstate_funcs.get_turbo(); 1414 cpu->pstate.turbo_pstate = pstate_funcs.get_turbo();
1414 cpu->pstate.scaling = pstate_funcs.get_scaling(); 1415 cpu->pstate.scaling = pstate_funcs.get_scaling();
1415 cpu->pstate.max_freq = cpu->pstate.max_pstate * cpu->pstate.scaling; 1416 cpu->pstate.max_freq = cpu->pstate.max_pstate * cpu->pstate.scaling;
1416 cpu->pstate.turbo_freq = cpu->pstate.turbo_pstate * cpu->pstate.scaling; 1417
1418 if (hwp_active && !hwp_mode_bdw) {
1419 unsigned int phy_max, current_max;
1420
1421 intel_pstate_get_hwp_max(cpu->cpu, &phy_max, &current_max);
1422 cpu->pstate.turbo_freq = phy_max * cpu->pstate.scaling;
1423 } else {
1424 cpu->pstate.turbo_freq = cpu->pstate.turbo_pstate * cpu->pstate.scaling;
1425 }
1417 1426
1418 if (pstate_funcs.get_aperf_mperf_shift) 1427 if (pstate_funcs.get_aperf_mperf_shift)
1419 cpu->aperf_mperf_shift = pstate_funcs.get_aperf_mperf_shift(); 1428 cpu->aperf_mperf_shift = pstate_funcs.get_aperf_mperf_shift();
@@ -2467,28 +2476,36 @@ static inline bool intel_pstate_has_acpi_ppc(void) { return false; }
2467static inline void intel_pstate_request_control_from_smm(void) {} 2476static inline void intel_pstate_request_control_from_smm(void) {}
2468#endif /* CONFIG_ACPI */ 2477#endif /* CONFIG_ACPI */
2469 2478
2479#define INTEL_PSTATE_HWP_BROADWELL 0x01
2480
2481#define ICPU_HWP(model, hwp_mode) \
2482 { X86_VENDOR_INTEL, 6, model, X86_FEATURE_HWP, hwp_mode }
2483
2470static const struct x86_cpu_id hwp_support_ids[] __initconst = { 2484static const struct x86_cpu_id hwp_support_ids[] __initconst = {
2471 { X86_VENDOR_INTEL, 6, X86_MODEL_ANY, X86_FEATURE_HWP }, 2485 ICPU_HWP(INTEL_FAM6_BROADWELL_X, INTEL_PSTATE_HWP_BROADWELL),
2486 ICPU_HWP(INTEL_FAM6_BROADWELL_XEON_D, INTEL_PSTATE_HWP_BROADWELL),
2487 ICPU_HWP(X86_MODEL_ANY, 0),
2472 {} 2488 {}
2473}; 2489};
2474 2490
2475static int __init intel_pstate_init(void) 2491static int __init intel_pstate_init(void)
2476{ 2492{
2493 const struct x86_cpu_id *id;
2477 int rc; 2494 int rc;
2478 2495
2479 if (no_load) 2496 if (no_load)
2480 return -ENODEV; 2497 return -ENODEV;
2481 2498
2482 if (x86_match_cpu(hwp_support_ids)) { 2499 id = x86_match_cpu(hwp_support_ids);
2500 if (id) {
2483 copy_cpu_funcs(&core_funcs); 2501 copy_cpu_funcs(&core_funcs);
2484 if (!no_hwp) { 2502 if (!no_hwp) {
2485 hwp_active++; 2503 hwp_active++;
2504 hwp_mode_bdw = id->driver_data;
2486 intel_pstate.attr = hwp_cpufreq_attrs; 2505 intel_pstate.attr = hwp_cpufreq_attrs;
2487 goto hwp_cpu_matched; 2506 goto hwp_cpu_matched;
2488 } 2507 }
2489 } else { 2508 } else {
2490 const struct x86_cpu_id *id;
2491
2492 id = x86_match_cpu(intel_pstate_cpu_ids); 2509 id = x86_match_cpu(intel_pstate_cpu_ids);
2493 if (!id) 2510 if (!id)
2494 return -ENODEV; 2511 return -ENODEV;
diff --git a/drivers/cpufreq/qcom-cpufreq-kryo.c b/drivers/cpufreq/qcom-cpufreq-kryo.c
index d049fe4b80c4..01bddacf5c3b 100644
--- a/drivers/cpufreq/qcom-cpufreq-kryo.c
+++ b/drivers/cpufreq/qcom-cpufreq-kryo.c
@@ -42,6 +42,8 @@ enum _msm8996_version {
42 NUM_OF_MSM8996_VERSIONS, 42 NUM_OF_MSM8996_VERSIONS,
43}; 43};
44 44
45struct platform_device *cpufreq_dt_pdev, *kryo_cpufreq_pdev;
46
45static enum _msm8996_version __init qcom_cpufreq_kryo_get_msm_id(void) 47static enum _msm8996_version __init qcom_cpufreq_kryo_get_msm_id(void)
46{ 48{
47 size_t len; 49 size_t len;
@@ -74,7 +76,6 @@ static enum _msm8996_version __init qcom_cpufreq_kryo_get_msm_id(void)
74static int qcom_cpufreq_kryo_probe(struct platform_device *pdev) 76static int qcom_cpufreq_kryo_probe(struct platform_device *pdev)
75{ 77{
76 struct opp_table *opp_tables[NR_CPUS] = {0}; 78 struct opp_table *opp_tables[NR_CPUS] = {0};
77 struct platform_device *cpufreq_dt_pdev;
78 enum _msm8996_version msm8996_version; 79 enum _msm8996_version msm8996_version;
79 struct nvmem_cell *speedbin_nvmem; 80 struct nvmem_cell *speedbin_nvmem;
80 struct device_node *np; 81 struct device_node *np;
@@ -115,6 +116,8 @@ static int qcom_cpufreq_kryo_probe(struct platform_device *pdev)
115 116
116 speedbin = nvmem_cell_read(speedbin_nvmem, &len); 117 speedbin = nvmem_cell_read(speedbin_nvmem, &len);
117 nvmem_cell_put(speedbin_nvmem); 118 nvmem_cell_put(speedbin_nvmem);
119 if (IS_ERR(speedbin))
120 return PTR_ERR(speedbin);
118 121
119 switch (msm8996_version) { 122 switch (msm8996_version) {
120 case MSM8996_V3: 123 case MSM8996_V3:
@@ -127,6 +130,7 @@ static int qcom_cpufreq_kryo_probe(struct platform_device *pdev)
127 BUG(); 130 BUG();
128 break; 131 break;
129 } 132 }
133 kfree(speedbin);
130 134
131 for_each_possible_cpu(cpu) { 135 for_each_possible_cpu(cpu) {
132 cpu_dev = get_cpu_device(cpu); 136 cpu_dev = get_cpu_device(cpu);
@@ -162,8 +166,15 @@ free_opp:
162 return ret; 166 return ret;
163} 167}
164 168
169static int qcom_cpufreq_kryo_remove(struct platform_device *pdev)
170{
171 platform_device_unregister(cpufreq_dt_pdev);
172 return 0;
173}
174
165static struct platform_driver qcom_cpufreq_kryo_driver = { 175static struct platform_driver qcom_cpufreq_kryo_driver = {
166 .probe = qcom_cpufreq_kryo_probe, 176 .probe = qcom_cpufreq_kryo_probe,
177 .remove = qcom_cpufreq_kryo_remove,
167