aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel/smp.c
diff options
context:
space:
mode:
authorThomas Gleinxer <tglx@linutronix.de>2011-10-14 07:44:41 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2011-10-23 16:22:58 -0400
commiteb0474544bc16a9dab53b26abd846e86ba814eb1 (patch)
treed065ba5fce871af8b02a8a8b55625084548ea3a0 /arch/arm/kernel/smp.c
parent6c5482d53f195d3ca61c9ec1be25b0f4a92575fe (diff)
ARM: 7133/1: SMP: fix per cpu timer setup before the cpu is marked online
The problem is related to the early enabling of interrupts and the per cpu timer setup before the cpu is marked online. This doesn't need to be done in order to call calibrate_delay(). calibrate_delay() monitors jiffies, which are updated from the CPU which is waiting for the new CPU to set the online bit. So simply calibrate_delay() can be called on the new CPU just from the interrupt disabled region and move the local timer setup after stored the cpu data and before enabling interrupts. This solves both the cpu_online vs. cpu_active problem and the affinity setting of the per cpu timers. Signed-off-by: Thomas Gleinxer <tglx@linutronix.de> Signed-off-by: Kukjin Kim <kgene.kim@samsung.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/kernel/smp.c')
-rw-r--r--arch/arm/kernel/smp.c23
1 files changed, 13 insertions, 10 deletions
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index d88ff0230e82..697e9a8cbdd8 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -301,17 +301,7 @@ asmlinkage void __cpuinit secondary_start_kernel(void)
301 */ 301 */
302 platform_secondary_init(cpu); 302 platform_secondary_init(cpu);
303 303
304 /*
305 * Enable local interrupts.
306 */
307 notify_cpu_starting(cpu); 304 notify_cpu_starting(cpu);
308 local_irq_enable();
309 local_fiq_enable();
310
311 /*
312 * Setup the percpu timer for this CPU.
313 */
314 percpu_timer_setup();
315 305
316 calibrate_delay(); 306 calibrate_delay();
317 307
@@ -323,10 +313,23 @@ asmlinkage void __cpuinit secondary_start_kernel(void)
323 * before we continue. 313 * before we continue.
324 */ 314 */
325 set_cpu_online(cpu, true); 315 set_cpu_online(cpu, true);
316
317 /*
318 * Setup the percpu timer for this CPU.
319 */
320 percpu_timer_setup();
321
326 while (!cpu_active(cpu)) 322 while (!cpu_active(cpu))
327 cpu_relax(); 323 cpu_relax();
328 324
329 /* 325 /*
326 * cpu_active bit is set, so it's safe to enalbe interrupts
327 * now.
328 */
329 local_irq_enable();
330 local_fiq_enable();
331
332 /*
330 * OK, it's off to the idle thread for us 333 * OK, it's off to the idle thread for us
331 */ 334 */
332 cpu_idle(); 335 cpu_idle();