diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-06-21 16:57:36 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-06-21 16:57:36 -0400 |
| commit | 26c92a38cec99ee7b657901ff64bd01a96a2fb22 (patch) | |
| tree | 8c5c51b76354a81544c9e1f15d29606f859113eb /drivers | |
| parent | 1abd8a8f39cd9a2925149000056494523c85643a (diff) | |
| parent | b51e001385f1c861445af3efeab766811ee8db29 (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.c | 15 | ||||
| -rw-r--r-- | drivers/cpufreq/intel_pstate.c | 27 | ||||
| -rw-r--r-- | drivers/cpufreq/qcom-cpufreq-kryo.c | 25 | ||||
| -rw-r--r-- | drivers/opp/core.c | 2 |
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 { | |||
| 294 | static struct pstate_funcs pstate_funcs __read_mostly; | 294 | static struct pstate_funcs pstate_funcs __read_mostly; |
| 295 | 295 | ||
| 296 | static int hwp_active __read_mostly; | 296 | static int hwp_active __read_mostly; |
| 297 | static int hwp_mode_bdw __read_mostly; | ||
| 297 | static bool per_cpu_limits __read_mostly; | 298 | static bool per_cpu_limits __read_mostly; |
| 298 | static bool hwp_boost __read_mostly; | 299 | static 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, ¤t_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; } | |||
| 2467 | static inline void intel_pstate_request_control_from_smm(void) {} | 2476 | static 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 | |||
| 2470 | static const struct x86_cpu_id hwp_support_ids[] __initconst = { | 2484 | static 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 | ||
| 2475 | static int __init intel_pstate_init(void) | 2491 | static 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 | ||
| 45 | struct platform_device *cpufreq_dt_pdev, *kryo_cpufreq_pdev; | ||
| 46 | |||
| 45 | static enum _msm8996_version __init qcom_cpufreq_kryo_get_msm_id(void) | 47 | static 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) | |||
| 74 | static int qcom_cpufreq_kryo_probe(struct platform_device *pdev) | 76 | static 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 | ||
| 169 | static int qcom_cpufreq_kryo_remove(struct platform_device *pdev) | ||
| 170 | { | ||
| 171 | platform_device_unregister(cpufreq_dt_pdev); | ||
| 172 | return 0; | ||
| 173 | } | ||
| 174 | |||
| 165 | static struct platform_driver qcom_cpufreq_kryo_driver = { | 175 | static 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 | |||
