summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/cpufreq/cpufreq.c31
-rw-r--r--include/linux/cpufreq.h3
2 files changed, 25 insertions, 9 deletions
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index d41067cd1f1b..4e78f4caab3a 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -2368,9 +2368,13 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy,
* exactly same freq is called again and so we can save on few function
* calls.
*/
- if (target_freq == policy->cur &&
- !(cpufreq_driver->flags & CPUFREQ_NEED_UPDATE_LIMITS))
- return 0;
+ if (target_freq == policy->cur) {
+ if (!(cpufreq_driver->flags & CPUFREQ_NEED_UPDATE_LIMITS) ||
+ !policy->update_limits)
+ return 0;
+
+ policy->update_limits = false;
+ }
if (cpufreq_driver->target) {
/*
@@ -2622,6 +2626,7 @@ static int cpufreq_set_policy(struct cpufreq_policy *policy,
{
struct cpufreq_policy_data new_data;
struct cpufreq_governor *old_gov;
+ unsigned int freq;
int ret;
memcpy(&new_data.cpuinfo, &policy->cpuinfo, sizeof(policy->cpuinfo));
@@ -2654,12 +2659,20 @@ static int cpufreq_set_policy(struct cpufreq_policy *policy,
* compiler optimizations around them because they may be accessed
* concurrently by cpufreq_driver_resolve_freq() during the update.
*/
- WRITE_ONCE(policy->max, __resolve_freq(policy, new_data.max,
- new_data.min, new_data.max,
- CPUFREQ_RELATION_H));
- new_data.min = __resolve_freq(policy, new_data.min, new_data.min,
- new_data.max, CPUFREQ_RELATION_L);
- WRITE_ONCE(policy->min, new_data.min > policy->max ? policy->max : new_data.min);
+ freq = __resolve_freq(policy, new_data.max, new_data.min, new_data.max,
+ CPUFREQ_RELATION_H);
+ if (freq != policy->max) {
+ WRITE_ONCE(policy->max, freq);
+ policy->update_limits = true;
+ }
+
+ freq = __resolve_freq(policy, new_data.min, new_data.min, new_data.max,
+ CPUFREQ_RELATION_L);
+ freq = min(freq, policy->max);
+ if (freq != policy->min) {
+ WRITE_ONCE(policy->min, freq);
+ policy->update_limits = true;
+ }
trace_cpu_frequency_limits(policy);
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
index 4d4b4ed24b30..ae9d1ce4f49c 100644
--- a/include/linux/cpufreq.h
+++ b/include/linux/cpufreq.h
@@ -146,6 +146,9 @@ struct cpufreq_policy {
/* Per policy boost supported flag. */
bool boost_supported;
+ /* Pending policy->min/max update for the driver */
+ bool update_limits;
+
/* Cached frequency lookup from cpufreq_driver_resolve_freq. */
unsigned int cached_target_freq;
unsigned int cached_resolved_idx;