summaryrefslogtreecommitdiffstats
path: root/drivers/cpufreq/cpufreq.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-05-06 22:40:31 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2019-05-06 22:40:31 -0400
commit8f5e823f9131a430b12f73e9436d7486e20c16f5 (patch)
treeec3f03c236182d113dd71b1b7b59be73e54ebab1 /drivers/cpufreq/cpufreq.c
parent59df1c2bdecb0d1aaadfb8533df4bea528ee4952 (diff)
parente07095c9bbcd296401bec8b6852d258d7c926969 (diff)
Merge tag 'pm-5.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull power management updates from Rafael Wysocki: "These fix the (Intel-specific) Performance and Energy Bias Hint (EPB) handling and expose it to user space via sysfs, fix and clean up several cpufreq drivers, add support for two new chips to the qoriq cpufreq driver, fix, simplify and clean up the cpufreq core and the schedutil governor, add support for "CPU" domains to the generic power domains (genpd) framework and provide low-level PSCI firmware support for that feature, fix the exynos cpuidle driver and fix a couple of issues in the devfreq subsystem and clean it up. Specifics: - Fix the handling of Performance and Energy Bias Hint (EPB) on Intel processors and expose it to user space via sysfs to avoid having to access it through the generic MSR I/F (Rafael Wysocki). - Improve the handling of global turbo changes made by the platform firmware in the intel_pstate driver (Rafael Wysocki). - Convert some slow-path static_cpu_has() callers to boot_cpu_has() in cpufreq (Borislav Petkov). - Fix the frequency calculation loop in the armada-37xx cpufreq driver (Gregory CLEMENT). - Fix possible object reference leaks in multuple cpufreq drivers (Wen Yang). - Fix kerneldoc comment in the centrino cpufreq driver (dongjian). - Clean up the ACPI and maple cpufreq drivers (Viresh Kumar, Mohan Kumar). - Add support for lx2160a and ls1028a to the qoriq cpufreq driver (Vabhav Sharma, Yuantian Tang). - Fix kobject memory leak in the cpufreq core (Viresh Kumar). - Simplify the IOwait boosting in the schedutil cpufreq governor and rework the TSC cpufreq notifier on x86 (Rafael Wysocki). - Clean up the cpufreq core and statistics code (Yue Hu, Kyle Lin). - Improve the cpufreq documentation, add SPDX license tags to some PM documentation files and unify copyright notices in them (Rafael Wysocki). - Add support for "CPU" domains to the generic power domains (genpd) framework and provide low-level PSCI firmware support for that feature (Ulf Hansson). - Rearrange the PSCI firmware support code and add support for SYSTEM_RESET2 to it (Ulf Hansson, Sudeep Holla). - Improve genpd support for devices in multiple power domains (Ulf Hansson). - Unify target residency for the AFTR and coupled AFTR states in the exynos cpuidle driver (Marek Szyprowski). - Introduce new helper routine in the operating performance points (OPP) framework (Andrew-sh.Cheng). - Add support for passing on-die termination (ODT) and auto power down parameters from the kernel to Trusted Firmware-A (TF-A) to the rk3399_dmc devfreq driver (Enric Balletbo i Serra). - Add tracing to devfreq (Lukasz Luba). - Make the exynos-bus devfreq driver suspend all devices on system shutdown (Marek Szyprowski). - Fix a few minor issues in the devfreq subsystem and clean it up somewhat (Enric Balletbo i Serra, MyungJoo Ham, Rob Herring, Saravana Kannan, Yangtao Li). - Improve system wakeup diagnostics (Stephen Boyd). - Rework filesystem sync messages emitted during system suspend and hibernation (Harry Pan)" * tag 'pm-5.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (72 commits) cpufreq: Fix kobject memleak cpufreq: armada-37xx: fix frequency calculation for opp cpufreq: centrino: Fix centrino_setpolicy() kerneldoc comment cpufreq: qoriq: add support for lx2160a x86: tsc: Rework time_cpufreq_notifier() PM / Domains: Allow to attach a CPU via genpd_dev_pm_attach_by_id|name() PM / Domains: Search for the CPU device outside the genpd lock PM / Domains: Drop unused in-parameter to some genpd functions PM / Domains: Use the base device for driver_deferred_probe_check_state() cpufreq: qoriq: Add ls1028a chip support PM / Domains: Enable genpd_dev_pm_attach_by_id|name() for single PM domain PM / Domains: Allow OF lookup for multi PM domain case from ->attach_dev() PM / Domains: Don't kfree() the virtual device in the error path cpufreq: Move ->get callback check outside of __cpufreq_get() PM / Domains: remove unnecessary unlikely() cpufreq: Remove needless bios_limit check in show_bios_limit() drivers/cpufreq/acpi-cpufreq.c: This fixes the following checkpatch warning firmware/psci: add support for SYSTEM_RESET2 PM / devfreq: add tracing for scheduling work trace: events: add devfreq trace event file ...
Diffstat (limited to 'drivers/cpufreq/cpufreq.c')
-rw-r--r--drivers/cpufreq/cpufreq.c100
1 files changed, 73 insertions, 27 deletions
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index e10922709d13..7ea217c88c2e 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -34,11 +34,6 @@
34 34
35static LIST_HEAD(cpufreq_policy_list); 35static LIST_HEAD(cpufreq_policy_list);
36 36
37static inline bool policy_is_inactive(struct cpufreq_policy *policy)
38{
39 return cpumask_empty(policy->cpus);
40}
41
42/* Macros to iterate over CPU policies */ 37/* Macros to iterate over CPU policies */
43#define for_each_suitable_policy(__policy, __active) \ 38#define for_each_suitable_policy(__policy, __active) \
44 list_for_each_entry(__policy, &cpufreq_policy_list, policy_list) \ 39 list_for_each_entry(__policy, &cpufreq_policy_list, policy_list) \
@@ -250,6 +245,51 @@ void cpufreq_cpu_put(struct cpufreq_policy *policy)
250} 245}
251EXPORT_SYMBOL_GPL(cpufreq_cpu_put); 246EXPORT_SYMBOL_GPL(cpufreq_cpu_put);
252 247
248/**
249 * cpufreq_cpu_release - Unlock a policy and decrement its usage counter.
250 * @policy: cpufreq policy returned by cpufreq_cpu_acquire().
251 */
252void cpufreq_cpu_release(struct cpufreq_policy *policy)
253{
254 if (WARN_ON(!policy))
255 return;
256
257 lockdep_assert_held(&policy->rwsem);
258
259 up_write(&policy->rwsem);
260
261 cpufreq_cpu_put(policy);
262}
263
264/**
265 * cpufreq_cpu_acquire - Find policy for a CPU, mark it as busy and lock it.
266 * @cpu: CPU to find the policy for.
267 *
268 * Call cpufreq_cpu_get() to get a reference on the cpufreq policy for @cpu and
269 * if the policy returned by it is not NULL, acquire its rwsem for writing.
270 * Return the policy if it is active or release it and return NULL otherwise.
271 *
272 * The policy returned by this function has to be released with the help of
273 * cpufreq_cpu_release() in order to release its rwsem and balance its usage
274 * counter properly.
275 */
276struct cpufreq_policy *cpufreq_cpu_acquire(unsigned int cpu)
277{
278 struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
279
280 if (!policy)
281 return NULL;
282
283 down_write(&policy->rwsem);
284
285 if (policy_is_inactive(policy)) {
286 cpufreq_cpu_release(policy);
287 return NULL;
288 }
289
290 return policy;
291}
292
253/********************************************************************* 293/*********************************************************************
254 * EXTERNALLY AFFECTING FREQUENCY CHANGES * 294 * EXTERNALLY AFFECTING FREQUENCY CHANGES *
255 *********************************************************************/ 295 *********************************************************************/
@@ -669,9 +709,6 @@ static ssize_t show_scaling_cur_freq(struct cpufreq_policy *policy, char *buf)
669 return ret; 709 return ret;
670} 710}
671 711
672static int cpufreq_set_policy(struct cpufreq_policy *policy,
673 struct cpufreq_policy *new_policy);
674
675/** 712/**
676 * cpufreq_per_cpu_attr_write() / store_##file_name() - sysfs write access 713 * cpufreq_per_cpu_attr_write() / store_##file_name() - sysfs write access
677 */ 714 */
@@ -857,11 +894,9 @@ static ssize_t show_bios_limit(struct cpufreq_policy *policy, char *buf)
857{ 894{
858 unsigned int limit; 895 unsigned int limit;
859 int ret; 896 int ret;
860 if (cpufreq_driver->bios_limit) { 897 ret = cpufreq_driver->bios_limit(policy->cpu, &limit);
861 ret = cpufreq_driver->bios_limit(policy->cpu, &limit); 898 if (!ret)
862 if (!ret) 899 return sprintf(buf, "%u\n", limit);
863 return sprintf(buf, "%u\n", limit);
864 }
865 return sprintf(buf, "%u\n", policy->cpuinfo.max_freq); 900 return sprintf(buf, "%u\n", policy->cpuinfo.max_freq);
866} 901}
867 902
@@ -1098,6 +1133,7 @@ static struct cpufreq_policy *cpufreq_policy_alloc(unsigned int cpu)
1098 cpufreq_global_kobject, "policy%u", cpu); 1133 cpufreq_global_kobject, "policy%u", cpu);
1099 if (ret) { 1134 if (ret) {
1100 pr_err("%s: failed to init policy->kobj: %d\n", __func__, ret); 1135 pr_err("%s: failed to init policy->kobj: %d\n", __func__, ret);
1136 kobject_put(&policy->kobj);
1101 goto err_free_real_cpus; 1137 goto err_free_real_cpus;
1102 } 1138 }
1103 1139
@@ -1550,7 +1586,7 @@ static unsigned int __cpufreq_get(struct cpufreq_policy *policy)
1550{ 1586{
1551 unsigned int ret_freq = 0; 1587 unsigned int ret_freq = 0;
1552 1588
1553 if (unlikely(policy_is_inactive(policy)) || !cpufreq_driver->get) 1589 if (unlikely(policy_is_inactive(policy)))
1554 return ret_freq; 1590 return ret_freq;
1555 1591
1556 ret_freq = cpufreq_driver->get(policy->cpu); 1592 ret_freq = cpufreq_driver->get(policy->cpu);
@@ -1588,7 +1624,8 @@ unsigned int cpufreq_get(unsigned int cpu)
1588 1624
1589 if (policy) { 1625 if (policy) {
1590 down_read(&policy->rwsem); 1626 down_read(&policy->rwsem);
1591 ret_freq = __cpufreq_get(policy); 1627 if (cpufreq_driver->get)
1628 ret_freq = __cpufreq_get(policy);
1592 up_read(&policy->rwsem); 1629 up_read(&policy->rwsem);
1593 1630
1594 cpufreq_cpu_put(policy); 1631 cpufreq_cpu_put(policy);
@@ -2229,8 +2266,8 @@ EXPORT_SYMBOL(cpufreq_get_policy);
2229 * 2266 *
2230 * The cpuinfo part of @policy is not updated by this function. 2267 * The cpuinfo part of @policy is not updated by this function.
2231 */ 2268 */
2232static int cpufreq_set_policy(struct cpufreq_policy *policy, 2269int cpufreq_set_policy(struct cpufreq_policy *policy,
2233 struct cpufreq_policy *new_policy) 2270 struct cpufreq_policy *new_policy)
2234{ 2271{
2235 struct cpufreq_governor *old_gov; 2272 struct cpufreq_governor *old_gov;
2236 int ret; 2273 int ret;
@@ -2337,17 +2374,12 @@ static int cpufreq_set_policy(struct cpufreq_policy *policy,
2337 */ 2374 */
2338void cpufreq_update_policy(unsigned int cpu) 2375void cpufreq_update_policy(unsigned int cpu)
2339{ 2376{
2340 struct cpufreq_policy *policy = cpufreq_cpu_get(cpu); 2377 struct cpufreq_policy *policy = cpufreq_cpu_acquire(cpu);
2341 struct cpufreq_policy new_policy; 2378 struct cpufreq_policy new_policy;
2342 2379
2343 if (!policy) 2380 if (!policy)
2344 return; 2381 return;
2345 2382
2346 down_write(&policy->rwsem);
2347
2348 if (policy_is_inactive(policy))
2349 goto unlock;
2350
2351 /* 2383 /*
2352 * BIOS might change freq behind our back 2384 * BIOS might change freq behind our back
2353 * -> ask driver for current freq and notify governors about a change 2385 * -> ask driver for current freq and notify governors about a change
@@ -2364,12 +2396,26 @@ void cpufreq_update_policy(unsigned int cpu)
2364 cpufreq_set_policy(policy, &new_policy); 2396 cpufreq_set_policy(policy, &new_policy);
2365 2397
2366unlock: 2398unlock:
2367 up_write(&policy->rwsem); 2399 cpufreq_cpu_release(policy);
2368
2369 cpufreq_cpu_put(policy);
2370} 2400}
2371EXPORT_SYMBOL(cpufreq_update_policy); 2401EXPORT_SYMBOL(cpufreq_update_policy);
2372 2402
2403/**
2404 * cpufreq_update_limits - Update policy limits for a given CPU.
2405 * @cpu: CPU to update the policy limits for.
2406 *
2407 * Invoke the driver's ->update_limits callback if present or call
2408 * cpufreq_update_policy() for @cpu.
2409 */
2410void cpufreq_update_limits(unsigned int cpu)
2411{
2412 if (cpufreq_driver->update_limits)
2413 cpufreq_driver->update_limits(cpu);
2414 else
2415 cpufreq_update_policy(cpu);
2416}
2417EXPORT_SYMBOL_GPL(cpufreq_update_limits);
2418
2373/********************************************************************* 2419/*********************************************************************
2374 * BOOST * 2420 * BOOST *
2375 *********************************************************************/ 2421 *********************************************************************/
@@ -2426,7 +2472,7 @@ int cpufreq_boost_trigger_state(int state)
2426 2472
2427static bool cpufreq_boost_supported(void) 2473static bool cpufreq_boost_supported(void)
2428{ 2474{
2429 return likely(cpufreq_driver) && cpufreq_driver->set_boost; 2475 return cpufreq_driver->set_boost;
2430} 2476}
2431 2477
2432static int create_boost_sysfs_file(void) 2478static int create_boost_sysfs_file(void)