From 8cefd87ffecd40ef7dd72ca5081d74984ce0d94d Mon Sep 17 00:00:00 2001 From: Robin Gong Date: Fri, 6 Jul 2012 13:07:25 +0800 Subject: [PATCH] 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 --- drivers/cpufreq/cpufreq_interactive.c | 14 +++++++------- 1 file 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, -- 2.39.5