diff options
author | Viresh Kumar <viresh.kumar@linaro.org> | 2013-03-24 02:26:43 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2013-04-02 09:24:00 -0400 |
commit | b43a7ffbf33be7e4d3b10b7714ee663ea2c52fe2 (patch) | |
tree | 7d3ac2733d76a785be12bfba75bfe244a5a31460 /arch/blackfin | |
parent | fd143b4d6fb763183ef6e46d1ab84a42c59079af (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.c | 79 |
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 | ||
130 | static int bfin_target(struct cpufreq_policy *poli, | 130 | static 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; |