aboutsummaryrefslogtreecommitdiffstats
path: root/arch/blackfin
diff options
context:
space:
mode:
authorViresh Kumar <viresh.kumar@linaro.org>2013-03-24 02:26:43 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-04-02 09:24:00 -0400
commitb43a7ffbf33be7e4d3b10b7714ee663ea2c52fe2 (patch)
tree7d3ac2733d76a785be12bfba75bfe244a5a31460 /arch/blackfin
parentfd143b4d6fb763183ef6e46d1ab84a42c59079af (diff)
cpufreq: Notify all policy->cpus in cpufreq_notify_transition()
policy->cpus contains all online cpus that have single shared clock line. And their frequencies are always updated together. Many SMP system's cpufreq drivers take care of this in individual drivers but the best place for this code is in cpufreq core. This patch modifies cpufreq_notify_transition() to notify frequency change for all cpus in policy->cpus and hence updates all users of this API. Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org> Acked-by: Stephen Warren <swarren@nvidia.com> Tested-by: Stephen Warren <swarren@nvidia.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'arch/blackfin')
-rw-r--r--arch/blackfin/mach-common/cpufreq.c79
1 files changed, 34 insertions, 45 deletions
diff --git a/arch/blackfin/mach-common/cpufreq.c b/arch/blackfin/mach-common/cpufreq.c
index d88bd31319e6..995511e80bef 100644
--- a/arch/blackfin/mach-common/cpufreq.c
+++ b/arch/blackfin/mach-common/cpufreq.c
@@ -127,13 +127,13 @@ unsigned long cpu_set_cclk(int cpu, unsigned long new)
127} 127}
128#endif 128#endif
129 129
130static int bfin_target(struct cpufreq_policy *poli, 130static int bfin_target(struct cpufreq_policy *policy,
131 unsigned int target_freq, unsigned int relation) 131 unsigned int target_freq, unsigned int relation)
132{ 132{
133#ifndef CONFIG_BF60x 133#ifndef CONFIG_BF60x
134 unsigned int plldiv; 134 unsigned int plldiv;
135#endif 135#endif
136 unsigned int index, cpu; 136 unsigned int index;
137 unsigned long cclk_hz; 137 unsigned long cclk_hz;
138 struct cpufreq_freqs freqs; 138 struct cpufreq_freqs freqs;
139 static unsigned long lpj_ref; 139 static unsigned long lpj_ref;
@@ -144,59 +144,48 @@ static int bfin_target(struct cpufreq_policy *poli,
144 cycles_t cycles; 144 cycles_t cycles;
145#endif 145#endif
146 146
147 for_each_online_cpu(cpu) { 147 if (cpufreq_frequency_table_target(policy, bfin_freq_table, target_freq,
148 struct cpufreq_policy *policy = cpufreq_cpu_get(cpu); 148 relation, &index))
149 return -EINVAL;
149 150
150 if (!policy) 151 cclk_hz = bfin_freq_table[index].frequency;
151 continue;
152 152
153 if (cpufreq_frequency_table_target(policy, bfin_freq_table, 153 freqs.old = bfin_getfreq_khz(0);
154 target_freq, relation, &index)) 154 freqs.new = cclk_hz;
155 return -EINVAL;
156 155
157 cclk_hz = bfin_freq_table[index].frequency; 156 pr_debug("cpufreq: changing cclk to %lu; target = %u, oldfreq = %u\n",
157 cclk_hz, target_freq, freqs.old);
158 158
159 freqs.old = bfin_getfreq_khz(0); 159 cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
160 freqs.new = cclk_hz;
161 freqs.cpu = cpu;
162
163 pr_debug("cpufreq: changing cclk to %lu; target = %u, oldfreq = %u\n",
164 cclk_hz, target_freq, freqs.old);
165
166 cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
167 if (cpu == CPUFREQ_CPU) {
168#ifndef CONFIG_BF60x 160#ifndef CONFIG_BF60x
169 plldiv = (bfin_read_PLL_DIV() & SSEL) | 161 plldiv = (bfin_read_PLL_DIV() & SSEL) | dpm_state_table[index].csel;
170 dpm_state_table[index].csel; 162 bfin_write_PLL_DIV(plldiv);
171 bfin_write_PLL_DIV(plldiv);
172#else 163#else
173 ret = cpu_set_cclk(cpu, freqs.new * 1000); 164 ret = cpu_set_cclk(policy->cpu, freqs.new * 1000);
174 if (ret != 0) { 165 if (ret != 0) {
175 WARN_ONCE(ret, "cpufreq set freq failed %d\n", ret); 166 WARN_ONCE(ret, "cpufreq set freq failed %d\n", ret);
176 break; 167 return ret;
177 } 168 }
178#endif 169#endif
179 on_each_cpu(bfin_adjust_core_timer, &index, 1); 170 on_each_cpu(bfin_adjust_core_timer, &index, 1);
180#if defined(CONFIG_CYCLES_CLOCKSOURCE) 171#if defined(CONFIG_CYCLES_CLOCKSOURCE)
181 cycles = get_cycles(); 172 cycles = get_cycles();
182 SSYNC(); 173 SSYNC();
183 cycles += 10; /* ~10 cycles we lose after get_cycles() */ 174 cycles += 10; /* ~10 cycles we lose after get_cycles() */
184 __bfin_cycles_off += 175 __bfin_cycles_off += (cycles << __bfin_cycles_mod) - (cycles << index);
185 (cycles << __bfin_cycles_mod) - (cycles << index); 176 __bfin_cycles_mod = index;
186 __bfin_cycles_mod = index;
187#endif 177#endif
188 if (!lpj_ref_freq) { 178 if (!lpj_ref_freq) {
189 lpj_ref = loops_per_jiffy; 179 lpj_ref = loops_per_jiffy;
190 lpj_ref_freq = freqs.old; 180 lpj_ref_freq = freqs.old;
191 }
192 if (freqs.new != freqs.old) {
193 loops_per_jiffy = cpufreq_scale(lpj_ref,
194 lpj_ref_freq, freqs.new);
195 }
196 }
197 /* TODO: just test case for cycles clock source, remove later */
198 cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
199 } 181 }
182 if (freqs.new != freqs.old) {
183 loops_per_jiffy = cpufreq_scale(lpj_ref,
184 lpj_ref_freq, freqs.new);
185 }
186
187 /* TODO: just test case for cycles clock source, remove later */
188 cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
200 189
201 pr_debug("cpufreq: done\n"); 190 pr_debug("cpufreq: done\n");
202 return ret; 191 return ret;