summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Gong <B38343@freescale.com>2012-07-06 13:07:25 +0800
committerTerry Lv <r65388@freescale.com>2012-07-25 13:10:34 +0800
commit551dc3c99ea08017970d2197058c1ef0745e6de1 (patch)
treed54c28e33826ad7c4a7b3c4d3b8c13e7b73d2a67
parentec6389c2d0c32e1c0c7eb0735e703ceff1042b4a (diff)
ENGR00215955 cpufreq interactive mx6: set cpufreq lowest point if cpu idling
Consider the below scenario: there is one CPU enter idle state before switch happen, and the CPU frequency is set on high point(1G with userspace cpufreq profile). After cpufreq profile is switched to interactive, all of the cpus's target_freq will be set to the current CPU frequency 1G. Then after one sample window, interactive profile will revalue the current cpu loading in every cpu(except idle cpu), and get the desired frequency and compared with target_freq to decide up or down frequency. Until all of cpus's target_freq is lower than desired frequency , down frequency will happen. But the idle CPU's frequency has been set on 1G , so cpu frequency miss the chance to set lower cpu frequency , although there is no loading in all of cpus.CPU frequency will be down unless the idled CPU exit idle to revalue cpu loading and get the right target_freq, in the worst case, it will never happen. Now we can do this: If we judge cpu idle state and set taget_freq to lowest frequency when switch to interactive, then CPU frequency modify will never be blocked on idled CPU. Signed-off-by: Robin Gong <B38343@freescale.com>
-rw-r--r--drivers/cpufreq/cpufreq_interactive.c14
1 files changed, 7 insertions, 7 deletions
diff --git a/drivers/cpufreq/cpufreq_interactive.c b/drivers/cpufreq/cpufreq_interactive.c
index c3bc7533df07..2db752c1d346 100644
--- a/drivers/cpufreq/cpufreq_interactive.c
+++ b/drivers/cpufreq/cpufreq_interactive.c
@@ -227,7 +227,6 @@ static void cpufreq_interactive_timer(unsigned long data)
}
new_freq = pcpu->freq_table[index].frequency;
-
if (pcpu->target_freq == new_freq)
goto rearm_if_notmax;
@@ -295,11 +294,10 @@ static void cpufreq_interactive_idle_start(void)
&per_cpu(cpuinfo, smp_processor_id());
int pending;
- if (!pcpu->governor_enabled)
- return;
-
pcpu->idling = 1;
smp_wmb();
+ if (!pcpu->governor_enabled)
+ return;
pending = timer_pending(&pcpu->cpu_timer);
if (pcpu->target_freq != pcpu->policy->min) {
@@ -412,11 +410,9 @@ static int cpufreq_interactive_up_task(void *data)
for_each_online_cpu(j) {
struct cpufreq_interactive_cpuinfo *pjcpu =
&per_cpu(cpuinfo, j);
-
if (pjcpu->target_freq > max_freq)
max_freq = pjcpu->target_freq;
}
-
if (max_freq != pcpu->policy->cur)
__cpufreq_driver_target(pcpu->policy,
max_freq,
@@ -640,7 +636,11 @@ static int cpufreq_governor_interactive(struct cpufreq_policy *policy,
for_each_cpu(j, policy->cpus) {
pcpu = &per_cpu(cpuinfo, j);
pcpu->policy = policy;
- pcpu->target_freq = policy->cur;
+ if (pcpu->idling)
+ pcpu->target_freq = policy->min;
+ else
+ pcpu->target_freq = policy->cur;
+
pcpu->freq_table = freq_table;
pcpu->freq_change_time_in_idle =
get_cpu_idle_time_us(j,