diff options
author | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2014-04-01 16:10:08 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2014-04-01 16:10:08 -0400 |
commit | 797cb8a6f7f1244ddd1e4bebebe38786d667057f (patch) | |
tree | 6141da5b66b3e33bb18706e8b19e6e246ec27de7 | |
parent | f01a586560ac492373add2550c0f93a002be3e65 (diff) | |
parent | 236a98005274d8011136aee4aef52241588a9712 (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.c | 4 | ||||
-rw-r--r-- | drivers/cpufreq/cpufreq.c | 61 | ||||
-rw-r--r-- | drivers/cpufreq/exynos5440-cpufreq.c | 4 | ||||
-rw-r--r-- | drivers/cpufreq/gx-suspmod.c | 4 | ||||
-rw-r--r-- | drivers/cpufreq/integrator-cpufreq.c | 4 | ||||
-rw-r--r-- | drivers/cpufreq/intel_pstate.c | 2 | ||||
-rw-r--r-- | drivers/cpufreq/longhaul.c | 4 | ||||
-rw-r--r-- | drivers/cpufreq/pcc-cpufreq.c | 4 | ||||
-rw-r--r-- | drivers/cpufreq/powernow-k6.c | 4 | ||||
-rw-r--r-- | drivers/cpufreq/powernow-k7.c | 4 | ||||
-rw-r--r-- | drivers/cpufreq/powernow-k8.c | 4 | ||||
-rw-r--r-- | drivers/cpufreq/s3c24xx-cpufreq.c | 4 | ||||
-rw-r--r-- | drivers/cpufreq/sh-cpufreq.c | 4 | ||||
-rw-r--r-- | drivers/cpufreq/unicore2-cpufreq.c | 4 | ||||
-rw-r--r-- | include/linux/cpufreq.h | 12 |
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 | */ |
334 | void cpufreq_notify_transition(struct cpufreq_policy *policy, | 334 | static 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 | } |
340 | EXPORT_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 */ |
343 | void cpufreq_notify_post_transition(struct cpufreq_policy *policy, | 342 | static 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 | } |
354 | EXPORT_SYMBOL_GPL(cpufreq_notify_post_transition); | 353 | |
354 | void cpufreq_freq_transition_begin(struct cpufreq_policy *policy, | ||
355 | struct cpufreq_freqs *freqs) | ||
356 | { | ||
357 | wait: | ||
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 | } | ||
373 | EXPORT_SYMBOL_GPL(cpufreq_freq_transition_begin); | ||
374 | |||
375 | void 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 | } | ||
387 | EXPORT_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 | ||
1848 | out: | 1881 | out: |
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) {} | |||
333 | int cpufreq_register_notifier(struct notifier_block *nb, unsigned int list); | 339 | int cpufreq_register_notifier(struct notifier_block *nb, unsigned int list); |
334 | int cpufreq_unregister_notifier(struct notifier_block *nb, unsigned int list); | 340 | int cpufreq_unregister_notifier(struct notifier_block *nb, unsigned int list); |
335 | 341 | ||
336 | void cpufreq_notify_transition(struct cpufreq_policy *policy, | 342 | void cpufreq_freq_transition_begin(struct cpufreq_policy *policy, |
337 | struct cpufreq_freqs *freqs, unsigned int state); | 343 | struct cpufreq_freqs *freqs); |
338 | void cpufreq_notify_post_transition(struct cpufreq_policy *policy, | 344 | void 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 */ |