aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-04-01 16:10:08 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-04-01 16:10:08 -0400
commit797cb8a6f7f1244ddd1e4bebebe38786d667057f (patch)
tree6141da5b66b3e33bb18706e8b19e6e246ec27de7
parentf01a586560ac492373add2550c0f93a002be3e65 (diff)
parent236a98005274d8011136aee4aef52241588a9712 (diff)
Merge branch 'pm-cpufreq'
* pm-cpufreq: cpufreq: Make cpufreq_notify_transition & cpufreq_notify_post_transition static cpufreq: Convert existing drivers to use cpufreq_freq_transition_{begin|end} cpufreq: Make sure frequency transitions are serialized intel_pstate: Use del_timer_sync in intel_pstate_cpu_stop cpufreq: resume drivers before enabling governors
-rw-r--r--drivers/cpufreq/cpufreq-nforce2.c4
-rw-r--r--drivers/cpufreq/cpufreq.c61
-rw-r--r--drivers/cpufreq/exynos5440-cpufreq.c4
-rw-r--r--drivers/cpufreq/gx-suspmod.c4
-rw-r--r--drivers/cpufreq/integrator-cpufreq.c4
-rw-r--r--drivers/cpufreq/intel_pstate.c2
-rw-r--r--drivers/cpufreq/longhaul.c4
-rw-r--r--drivers/cpufreq/pcc-cpufreq.c4
-rw-r--r--drivers/cpufreq/powernow-k6.c4
-rw-r--r--drivers/cpufreq/powernow-k7.c4
-rw-r--r--drivers/cpufreq/powernow-k8.c4
-rw-r--r--drivers/cpufreq/s3c24xx-cpufreq.c4
-rw-r--r--drivers/cpufreq/sh-cpufreq.c4
-rw-r--r--drivers/cpufreq/unicore2-cpufreq.c4
-rw-r--r--include/linux/cpufreq.h12
15 files changed, 81 insertions, 42 deletions
diff --git a/drivers/cpufreq/cpufreq-nforce2.c b/drivers/cpufreq/cpufreq-nforce2.c
index a05b876f375e..bc447b9003c3 100644
--- a/drivers/cpufreq/cpufreq-nforce2.c
+++ b/drivers/cpufreq/cpufreq-nforce2.c
@@ -270,7 +270,7 @@ static int nforce2_target(struct cpufreq_policy *policy,
270 pr_debug("Old CPU frequency %d kHz, new %d kHz\n", 270 pr_debug("Old CPU frequency %d kHz, new %d kHz\n",
271 freqs.old, freqs.new); 271 freqs.old, freqs.new);
272 272
273 cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); 273 cpufreq_freq_transition_begin(policy, &freqs);
274 274
275 /* Disable IRQs */ 275 /* Disable IRQs */
276 /* local_irq_save(flags); */ 276 /* local_irq_save(flags); */
@@ -285,7 +285,7 @@ static int nforce2_target(struct cpufreq_policy *policy,
285 /* Enable IRQs */ 285 /* Enable IRQs */
286 /* local_irq_restore(flags); */ 286 /* local_irq_restore(flags); */
287 287
288 cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); 288 cpufreq_freq_transition_end(policy, &freqs, 0);
289 289
290 return 0; 290 return 0;
291} 291}
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 3aa7a7a226b3..abda6609d3e7 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -331,16 +331,15 @@ static void __cpufreq_notify_transition(struct cpufreq_policy *policy,
331 * function. It is called twice on all CPU frequency changes that have 331 * function. It is called twice on all CPU frequency changes that have
332 * external effects. 332 * external effects.
333 */ 333 */
334void cpufreq_notify_transition(struct cpufreq_policy *policy, 334static void cpufreq_notify_transition(struct cpufreq_policy *policy,
335 struct cpufreq_freqs *freqs, unsigned int state) 335 struct cpufreq_freqs *freqs, unsigned int state)
336{ 336{
337 for_each_cpu(freqs->cpu, policy->cpus) 337 for_each_cpu(freqs->cpu, policy->cpus)
338 __cpufreq_notify_transition(policy, freqs, state); 338 __cpufreq_notify_transition(policy, freqs, state);
339} 339}
340EXPORT_SYMBOL_GPL(cpufreq_notify_transition);
341 340
342/* Do post notifications when there are chances that transition has failed */ 341/* Do post notifications when there are chances that transition has failed */
343void cpufreq_notify_post_transition(struct cpufreq_policy *policy, 342static void cpufreq_notify_post_transition(struct cpufreq_policy *policy,
344 struct cpufreq_freqs *freqs, int transition_failed) 343 struct cpufreq_freqs *freqs, int transition_failed)
345{ 344{
346 cpufreq_notify_transition(policy, freqs, CPUFREQ_POSTCHANGE); 345 cpufreq_notify_transition(policy, freqs, CPUFREQ_POSTCHANGE);
@@ -351,7 +350,41 @@ void cpufreq_notify_post_transition(struct cpufreq_policy *policy,
351 cpufreq_notify_transition(policy, freqs, CPUFREQ_PRECHANGE); 350 cpufreq_notify_transition(policy, freqs, CPUFREQ_PRECHANGE);
352 cpufreq_notify_transition(policy, freqs, CPUFREQ_POSTCHANGE); 351 cpufreq_notify_transition(policy, freqs, CPUFREQ_POSTCHANGE);
353} 352}
354EXPORT_SYMBOL_GPL(cpufreq_notify_post_transition); 353
354void cpufreq_freq_transition_begin(struct cpufreq_policy *policy,
355 struct cpufreq_freqs *freqs)
356{
357wait:
358 wait_event(policy->transition_wait, !policy->transition_ongoing);
359
360 spin_lock(&policy->transition_lock);
361
362 if (unlikely(policy->transition_ongoing)) {
363 spin_unlock(&policy->transition_lock);
364 goto wait;
365 }
366
367 policy->transition_ongoing = true;
368
369 spin_unlock(&policy->transition_lock);
370
371 cpufreq_notify_transition(policy, freqs, CPUFREQ_PRECHANGE);
372}
373EXPORT_SYMBOL_GPL(cpufreq_freq_transition_begin);
374
375void cpufreq_freq_transition_end(struct cpufreq_policy *policy,
376 struct cpufreq_freqs *freqs, int transition_failed)
377{
378 if (unlikely(WARN_ON(!policy->transition_ongoing)))
379 return;
380
381 cpufreq_notify_post_transition(policy, freqs, transition_failed);
382
383 policy->transition_ongoing = false;
384
385 wake_up(&policy->transition_wait);
386}
387EXPORT_SYMBOL_GPL(cpufreq_freq_transition_end);
355 388
356 389
357/********************************************************************* 390/*********************************************************************
@@ -985,6 +1018,8 @@ static struct cpufreq_policy *cpufreq_policy_alloc(void)
985 1018
986 INIT_LIST_HEAD(&policy->policy_list); 1019 INIT_LIST_HEAD(&policy->policy_list);
987 init_rwsem(&policy->rwsem); 1020 init_rwsem(&policy->rwsem);
1021 spin_lock_init(&policy->transition_lock);
1022 init_waitqueue_head(&policy->transition_wait);
988 1023
989 return policy; 1024 return policy;
990 1025
@@ -1470,8 +1505,8 @@ static void cpufreq_out_of_sync(unsigned int cpu, unsigned int old_freq,
1470 policy = per_cpu(cpufreq_cpu_data, cpu); 1505 policy = per_cpu(cpufreq_cpu_data, cpu);
1471 read_unlock_irqrestore(&cpufreq_driver_lock, flags); 1506 read_unlock_irqrestore(&cpufreq_driver_lock, flags);
1472 1507
1473 cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); 1508 cpufreq_freq_transition_begin(policy, &freqs);
1474 cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); 1509 cpufreq_freq_transition_end(policy, &freqs, 0);
1475} 1510}
1476 1511
1477/** 1512/**
@@ -1652,14 +1687,13 @@ void cpufreq_resume(void)
1652 cpufreq_suspended = false; 1687 cpufreq_suspended = false;
1653 1688
1654 list_for_each_entry(policy, &cpufreq_policy_list, policy_list) { 1689 list_for_each_entry(policy, &cpufreq_policy_list, policy_list) {
1655 if (__cpufreq_governor(policy, CPUFREQ_GOV_START) 1690 if (cpufreq_driver->resume && cpufreq_driver->resume(policy))
1691 pr_err("%s: Failed to resume driver: %p\n", __func__,
1692 policy);
1693 else if (__cpufreq_governor(policy, CPUFREQ_GOV_START)
1656 || __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS)) 1694 || __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS))
1657 pr_err("%s: Failed to start governor for policy: %p\n", 1695 pr_err("%s: Failed to start governor for policy: %p\n",
1658 __func__, policy); 1696 __func__, policy);
1659 else if (cpufreq_driver->resume
1660 && cpufreq_driver->resume(policy))
1661 pr_err("%s: Failed to resume driver: %p\n", __func__,
1662 policy);
1663 1697
1664 /* 1698 /*
1665 * schedule call cpufreq_update_policy() for boot CPU, i.e. last 1699 * schedule call cpufreq_update_policy() for boot CPU, i.e. last
@@ -1832,8 +1866,7 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy,
1832 pr_debug("%s: cpu: %d, oldfreq: %u, new freq: %u\n", 1866 pr_debug("%s: cpu: %d, oldfreq: %u, new freq: %u\n",
1833 __func__, policy->cpu, freqs.old, freqs.new); 1867 __func__, policy->cpu, freqs.old, freqs.new);
1834 1868
1835 cpufreq_notify_transition(policy, &freqs, 1869 cpufreq_freq_transition_begin(policy, &freqs);
1836 CPUFREQ_PRECHANGE);
1837 } 1870 }
1838 1871
1839 retval = cpufreq_driver->target_index(policy, index); 1872 retval = cpufreq_driver->target_index(policy, index);
@@ -1842,7 +1875,7 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy,
1842 __func__, retval); 1875 __func__, retval);
1843 1876
1844 if (notify) 1877 if (notify)
1845 cpufreq_notify_post_transition(policy, &freqs, retval); 1878 cpufreq_freq_transition_end(policy, &freqs, retval);
1846 } 1879 }
1847 1880
1848out: 1881out:
diff --git a/drivers/cpufreq/exynos5440-cpufreq.c b/drivers/cpufreq/exynos5440-cpufreq.c
index 7f776aa91e2f..a6b8214d7b77 100644
--- a/drivers/cpufreq/exynos5440-cpufreq.c
+++ b/drivers/cpufreq/exynos5440-cpufreq.c
@@ -219,7 +219,7 @@ static int exynos_target(struct cpufreq_policy *policy, unsigned int index)
219 freqs.old = policy->cur; 219 freqs.old = policy->cur;
220 freqs.new = freq_table[index].frequency; 220 freqs.new = freq_table[index].frequency;
221 221
222 cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); 222 cpufreq_freq_transition_begin(policy, &freqs);
223 223
224 /* Set the target frequency in all C0_3_PSTATE register */ 224 /* Set the target frequency in all C0_3_PSTATE register */
225 for_each_cpu(i, policy->cpus) { 225 for_each_cpu(i, policy->cpus) {
@@ -258,7 +258,7 @@ static void exynos_cpufreq_work(struct work_struct *work)
258 dev_crit(dvfs_info->dev, "New frequency out of range\n"); 258 dev_crit(dvfs_info->dev, "New frequency out of range\n");
259 freqs.new = freqs.old; 259 freqs.new = freqs.old;
260 } 260 }
261 cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); 261 cpufreq_freq_transition_end(policy, &freqs, 0);
262 262
263 cpufreq_cpu_put(policy); 263 cpufreq_cpu_put(policy);
264 mutex_unlock(&cpufreq_lock); 264 mutex_unlock(&cpufreq_lock);
diff --git a/drivers/cpufreq/gx-suspmod.c b/drivers/cpufreq/gx-suspmod.c
index d83e8266a58e..1d723dc8880c 100644
--- a/drivers/cpufreq/gx-suspmod.c
+++ b/drivers/cpufreq/gx-suspmod.c
@@ -265,7 +265,7 @@ static void gx_set_cpuspeed(struct cpufreq_policy *policy, unsigned int khz)
265 265
266 freqs.new = new_khz; 266 freqs.new = new_khz;
267 267
268 cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); 268 cpufreq_freq_transition_begin(policy, &freqs);
269 local_irq_save(flags); 269 local_irq_save(flags);
270 270
271 if (new_khz != stock_freq) { 271 if (new_khz != stock_freq) {
@@ -314,7 +314,7 @@ static void gx_set_cpuspeed(struct cpufreq_policy *policy, unsigned int khz)
314 314
315 gx_params->pci_suscfg = suscfg; 315 gx_params->pci_suscfg = suscfg;
316 316
317 cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); 317 cpufreq_freq_transition_end(policy, &freqs, 0);
318 318
319 pr_debug("suspend modulation w/ duration of ON:%d us, OFF:%d us\n", 319 pr_debug("suspend modulation w/ duration of ON:%d us, OFF:%d us\n",
320 gx_params->on_duration * 32, gx_params->off_duration * 32); 320 gx_params->on_duration * 32, gx_params->off_duration * 32);
diff --git a/drivers/cpufreq/integrator-cpufreq.c b/drivers/cpufreq/integrator-cpufreq.c
index 0e27844e8c2d..e5122f1bfe78 100644
--- a/drivers/cpufreq/integrator-cpufreq.c
+++ b/drivers/cpufreq/integrator-cpufreq.c
@@ -122,7 +122,7 @@ static int integrator_set_target(struct cpufreq_policy *policy,
122 return 0; 122 return 0;
123 } 123 }
124 124
125 cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); 125 cpufreq_freq_transition_begin(policy, &freqs);
126 126
127 cm_osc = __raw_readl(cm_base + INTEGRATOR_HDR_OSC_OFFSET); 127 cm_osc = __raw_readl(cm_base + INTEGRATOR_HDR_OSC_OFFSET);
128 128
@@ -143,7 +143,7 @@ static int integrator_set_target(struct cpufreq_policy *policy,
143 */ 143 */
144 set_cpus_allowed(current, cpus_allowed); 144 set_cpus_allowed(current, cpus_allowed);
145 145
146 cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); 146 cpufreq_freq_transition_end(policy, &freqs, 0);
147 147
148 return 0; 148 return 0;
149} 149}
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
index bcb9a6d0ae11..099967302bf2 100644
--- a/drivers/cpufreq/intel_pstate.c
+++ b/drivers/cpufreq/intel_pstate.c
@@ -778,7 +778,7 @@ static void intel_pstate_stop_cpu(struct cpufreq_policy *policy)
778 778
779 pr_info("intel_pstate CPU %d exiting\n", cpu_num); 779 pr_info("intel_pstate CPU %d exiting\n", cpu_num);
780 780
781 del_timer(&all_cpu_data[cpu_num]->timer); 781 del_timer_sync(&all_cpu_data[cpu_num]->timer);
782 intel_pstate_set_pstate(cpu, cpu->pstate.min_pstate); 782 intel_pstate_set_pstate(cpu, cpu->pstate.min_pstate);
783 kfree(all_cpu_data[cpu_num]); 783 kfree(all_cpu_data[cpu_num]);
784 all_cpu_data[cpu_num] = NULL; 784 all_cpu_data[cpu_num] = NULL;
diff --git a/drivers/cpufreq/longhaul.c b/drivers/cpufreq/longhaul.c
index 7b94da3d2d10..5c440f87ba8a 100644
--- a/drivers/cpufreq/longhaul.c
+++ b/drivers/cpufreq/longhaul.c
@@ -269,7 +269,7 @@ static void longhaul_setstate(struct cpufreq_policy *policy,
269 freqs.old = calc_speed(longhaul_get_cpu_mult()); 269 freqs.old = calc_speed(longhaul_get_cpu_mult());
270 freqs.new = speed; 270 freqs.new = speed;
271 271
272 cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); 272 cpufreq_freq_transition_begin(policy, &freqs);
273 273
274 pr_debug("Setting to FSB:%dMHz Mult:%d.%dx (%s)\n", 274 pr_debug("Setting to FSB:%dMHz Mult:%d.%dx (%s)\n",
275 fsb, mult/10, mult%10, print_speed(speed/1000)); 275 fsb, mult/10, mult%10, print_speed(speed/1000));
@@ -386,7 +386,7 @@ retry_loop:
386 } 386 }
387 } 387 }
388 /* Report true CPU frequency */ 388 /* Report true CPU frequency */
389 cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); 389 cpufreq_freq_transition_end(policy, &freqs, 0);
390 390
391 if (!bm_timeout) 391 if (!bm_timeout)
392 printk(KERN_INFO PFX "Warning: Timeout while waiting for " 392 printk(KERN_INFO PFX "Warning: Timeout while waiting for "
diff --git a/drivers/cpufreq/pcc-cpufreq.c b/drivers/cpufreq/pcc-cpufreq.c
index 1c0f1067af73..728a2d879499 100644
--- a/drivers/cpufreq/pcc-cpufreq.c
+++ b/drivers/cpufreq/pcc-cpufreq.c
@@ -215,7 +215,7 @@ static int pcc_cpufreq_target(struct cpufreq_policy *policy,
215 215
216 freqs.old = policy->cur; 216 freqs.old = policy->cur;
217 freqs.new = target_freq; 217 freqs.new = target_freq;
218 cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); 218 cpufreq_freq_transition_begin(policy, &freqs);
219 219
220 input_buffer = 0x1 | (((target_freq * 100) 220 input_buffer = 0x1 | (((target_freq * 100)
221 / (ioread32(&pcch_hdr->nominal) * 1000)) << 8); 221 / (ioread32(&pcch_hdr->nominal) * 1000)) << 8);
@@ -231,7 +231,7 @@ static int pcc_cpufreq_target(struct cpufreq_policy *policy,
231 status = ioread16(&pcch_hdr->status); 231 status = ioread16(&pcch_hdr->status);
232 iowrite16(0, &pcch_hdr->status); 232 iowrite16(0, &pcch_hdr->status);
233 233
234 cpufreq_notify_post_transition(policy, &freqs, status != CMD_COMPLETE); 234 cpufreq_freq_transition_end(policy, &freqs, status != CMD_COMPLETE);
235 spin_unlock(&pcc_lock); 235 spin_unlock(&pcc_lock);
236 236
237 if (status != CMD_COMPLETE) { 237 if (status != CMD_COMPLETE) {
diff --git a/drivers/cpufreq/powernow-k6.c b/drivers/cpufreq/powernow-k6.c
index ce27e6c26c94..62c6f2e5afce 100644
--- a/drivers/cpufreq/powernow-k6.c
+++ b/drivers/cpufreq/powernow-k6.c
@@ -148,11 +148,11 @@ static int powernow_k6_target(struct cpufreq_policy *policy,
148 freqs.old = busfreq * powernow_k6_get_cpu_multiplier(); 148 freqs.old = busfreq * powernow_k6_get_cpu_multiplier();
149 freqs.new = busfreq * clock_ratio[best_i].driver_data; 149 freqs.new = busfreq * clock_ratio[best_i].driver_data;
150 150
151 cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); 151 cpufreq_freq_transition_begin(policy, &freqs);
152 152
153 powernow_k6_set_cpu_multiplier(best_i); 153 powernow_k6_set_cpu_multiplier(best_i);
154 154
155 cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); 155 cpufreq_freq_transition_end(policy, &freqs, 0);
156 156
157 return 0; 157 return 0;
158} 158}
diff --git a/drivers/cpufreq/powernow-k7.c b/drivers/cpufreq/powernow-k7.c
index 0e68e0275621..f911645c3f6d 100644
--- a/drivers/cpufreq/powernow-k7.c
+++ b/drivers/cpufreq/powernow-k7.c
@@ -269,7 +269,7 @@ static int powernow_target(struct cpufreq_policy *policy, unsigned int index)
269 269
270 freqs.new = powernow_table[index].frequency; 270 freqs.new = powernow_table[index].frequency;
271 271
272 cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); 272 cpufreq_freq_transition_begin(policy, &freqs);
273 273
274 /* Now do the magic poking into the MSRs. */ 274 /* Now do the magic poking into the MSRs. */
275 275
@@ -290,7 +290,7 @@ static int powernow_target(struct cpufreq_policy *policy, unsigned int index)
290 if (have_a0 == 1) 290 if (have_a0 == 1)
291 local_irq_enable(); 291 local_irq_enable();
292 292
293 cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); 293 cpufreq_freq_transition_end(policy, &freqs, 0);
294 294
295 return 0; 295 return 0;
296} 296}
diff --git a/drivers/cpufreq/powernow-k8.c b/drivers/cpufreq/powernow-k8.c
index 27eb2be44de5..770a9e1b3468 100644
--- a/drivers/cpufreq/powernow-k8.c
+++ b/drivers/cpufreq/powernow-k8.c
@@ -963,9 +963,9 @@ static int transition_frequency_fidvid(struct powernow_k8_data *data,
963 policy = cpufreq_cpu_get(smp_processor_id()); 963 policy = cpufreq_cpu_get(smp_processor_id());
964 cpufreq_cpu_put(policy); 964 cpufreq_cpu_put(policy);
965 965
966 cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); 966 cpufreq_freq_transition_begin(policy, &freqs);
967 res = transition_fid_vid(data, fid, vid); 967 res = transition_fid_vid(data, fid, vid);
968 cpufreq_notify_post_transition(policy, &freqs, res); 968 cpufreq_freq_transition_end(policy, &freqs, res);
969 969
970 return res; 970 return res;
971} 971}
diff --git a/drivers/cpufreq/s3c24xx-cpufreq.c b/drivers/cpufreq/s3c24xx-cpufreq.c
index 25069741b507..a3dc192d21f9 100644
--- a/drivers/cpufreq/s3c24xx-cpufreq.c
+++ b/drivers/cpufreq/s3c24xx-cpufreq.c
@@ -217,7 +217,7 @@ static int s3c_cpufreq_settarget(struct cpufreq_policy *policy,
217 s3c_cpufreq_updateclk(clk_pclk, cpu_new.freq.pclk); 217 s3c_cpufreq_updateclk(clk_pclk, cpu_new.freq.pclk);
218 218
219 /* start the frequency change */ 219 /* start the frequency change */
220 cpufreq_notify_transition(policy, &freqs.freqs, CPUFREQ_PRECHANGE); 220 cpufreq_freq_transition_begin(policy, &freqs.freqs);
221 221
222 /* If hclk is staying the same, then we do not need to 222 /* If hclk is staying the same, then we do not need to
223 * re-write the IO or the refresh timings whilst we are changing 223 * re-write the IO or the refresh timings whilst we are changing
@@ -261,7 +261,7 @@ static int s3c_cpufreq_settarget(struct cpufreq_policy *policy,
261 local_irq_restore(flags); 261 local_irq_restore(flags);
262 262
263 /* notify everyone we've done this */ 263 /* notify everyone we've done this */
264 cpufreq_notify_transition(policy, &freqs.freqs, CPUFREQ_POSTCHANGE); 264 cpufreq_freq_transition_end(policy, &freqs.freqs, 0);
265 265
266 s3c_freq_dbg("%s: finished\n", __func__); 266 s3c_freq_dbg("%s: finished\n", __func__);
267 return 0; 267 return 0;
diff --git a/drivers/cpufreq/sh-cpufreq.c b/drivers/cpufreq/sh-cpufreq.c
index 696170ebd3a3..86628e22b2a3 100644
--- a/drivers/cpufreq/sh-cpufreq.c
+++ b/drivers/cpufreq/sh-cpufreq.c
@@ -68,10 +68,10 @@ static int sh_cpufreq_target(struct cpufreq_policy *policy,
68 freqs.new = (freq + 500) / 1000; 68 freqs.new = (freq + 500) / 1000;
69 freqs.flags = 0; 69 freqs.flags = 0;
70 70
71 cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); 71 cpufreq_freq_transition_begin(policy, &freqs);
72 set_cpus_allowed_ptr(current, &cpus_allowed); 72 set_cpus_allowed_ptr(current, &cpus_allowed);
73 clk_set_rate(cpuclk, freq); 73 clk_set_rate(cpuclk, freq);
74 cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); 74 cpufreq_freq_transition_end(policy, &freqs, 0);
75 75
76 dev_dbg(dev, "set frequency %lu Hz\n", freq); 76 dev_dbg(dev, "set frequency %lu Hz\n", freq);
77 77
diff --git a/drivers/cpufreq/unicore2-cpufreq.c b/drivers/cpufreq/unicore2-cpufreq.c
index 36cc330b8747..13be802b6170 100644
--- a/drivers/cpufreq/unicore2-cpufreq.c
+++ b/drivers/cpufreq/unicore2-cpufreq.c
@@ -44,9 +44,9 @@ static int ucv2_target(struct cpufreq_policy *policy,
44 freqs.old = policy->cur; 44 freqs.old = policy->cur;
45 freqs.new = target_freq; 45 freqs.new = target_freq;
46 46
47 cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); 47 cpufreq_freq_transition_begin(policy, &freqs);
48 ret = clk_set_rate(policy->mclk, target_freq * 1000); 48 ret = clk_set_rate(policy->mclk, target_freq * 1000);
49 cpufreq_notify_post_transition(policy, &freqs, ret); 49 cpufreq_freq_transition_end(policy, &freqs, ret);
50 50
51 return ret; 51 return ret;
52} 52}
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
index 2d2e62c8666a..c48e595f623e 100644
--- a/include/linux/cpufreq.h
+++ b/include/linux/cpufreq.h
@@ -16,6 +16,7 @@
16#include <linux/completion.h> 16#include <linux/completion.h>
17#include <linux/kobject.h> 17#include <linux/kobject.h>
18#include <linux/notifier.h> 18#include <linux/notifier.h>
19#include <linux/spinlock.h>
19#include <linux/sysfs.h> 20#include <linux/sysfs.h>
20 21
21/********************************************************************* 22/*********************************************************************
@@ -104,6 +105,11 @@ struct cpufreq_policy {
104 * __cpufreq_governor(data, CPUFREQ_GOV_POLICY_EXIT); 105 * __cpufreq_governor(data, CPUFREQ_GOV_POLICY_EXIT);
105 */ 106 */
106 struct rw_semaphore rwsem; 107 struct rw_semaphore rwsem;
108
109 /* Synchronization for frequency transitions */
110 bool transition_ongoing; /* Tracks transition status */
111 spinlock_t transition_lock;
112 wait_queue_head_t transition_wait;
107}; 113};
108 114
109/* Only for ACPI */ 115/* Only for ACPI */
@@ -333,9 +339,9 @@ static inline void cpufreq_resume(void) {}
333int cpufreq_register_notifier(struct notifier_block *nb, unsigned int list); 339int cpufreq_register_notifier(struct notifier_block *nb, unsigned int list);
334int cpufreq_unregister_notifier(struct notifier_block *nb, unsigned int list); 340int cpufreq_unregister_notifier(struct notifier_block *nb, unsigned int list);
335 341
336void cpufreq_notify_transition(struct cpufreq_policy *policy, 342void cpufreq_freq_transition_begin(struct cpufreq_policy *policy,
337 struct cpufreq_freqs *freqs, unsigned int state); 343 struct cpufreq_freqs *freqs);
338void cpufreq_notify_post_transition(struct cpufreq_policy *policy, 344void cpufreq_freq_transition_end(struct cpufreq_policy *policy,
339 struct cpufreq_freqs *freqs, int transition_failed); 345 struct cpufreq_freqs *freqs, int transition_failed);
340 346
341#else /* CONFIG_CPU_FREQ */ 347#else /* CONFIG_CPU_FREQ */