diff options
Diffstat (limited to 'arch/arm/kernel/smp.c')
-rw-r--r-- | arch/arm/kernel/smp.c | 67 |
1 files changed, 17 insertions, 50 deletions
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index 35417d0fb8ab..ef5640b9e218 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -319,17 +319,7 @@ asmlinkage void __cpuinit secondary_start_kernel(void) */ platform_secondary_init(cpu); - /* - * Enable local interrupts. - */ notify_cpu_starting(cpu); - local_irq_enable(); - local_fiq_enable(); - - /* - * Setup the percpu timer for this CPU. - */ - percpu_timer_setup(); calibrate_delay(); @@ -341,10 +331,23 @@ asmlinkage void __cpuinit secondary_start_kernel(void) * before we continue. */ set_cpu_online(cpu, true); + + /* + * Setup the percpu timer for this CPU. + */ + percpu_timer_setup(); + while (!cpu_active(cpu)) cpu_relax(); /* + * cpu_active bit is set, so it's safe to enalbe interrupts + * now. + */ + local_irq_enable(); + local_fiq_enable(); + + /* * OK, it's off to the idle thread for us */ cpu_idle(); @@ -457,10 +460,6 @@ u64 smp_irq_stat_cpu(unsigned int cpu) for (i = 0; i < NR_IPI; i++) sum += __get_irq_stat(cpu, ipi_irqs[i]); -#ifdef CONFIG_LOCAL_TIMERS - sum += __get_irq_stat(cpu, local_timer_irqs); -#endif - return sum; } @@ -477,38 +476,6 @@ static void ipi_timer(void) irq_exit(); } -#ifdef CONFIG_LOCAL_TIMERS -asmlinkage void __exception_irq_entry do_local_timer(struct pt_regs *regs) -{ - handle_local_timer(regs); -} - -void handle_local_timer(struct pt_regs *regs) -{ - struct pt_regs *old_regs = set_irq_regs(regs); - int cpu = smp_processor_id(); - - if (local_timer_ack()) { - __inc_irq_stat(cpu, local_timer_irqs); - ipi_timer(); - } - - set_irq_regs(old_regs); -} - -void show_local_irqs(struct seq_file *p, int prec) -{ - unsigned int cpu; - - seq_printf(p, "%*s: ", prec, "LOC"); - - for_each_present_cpu(cpu) - seq_printf(p, "%10u ", __get_irq_stat(cpu, local_timer_irqs)); - - seq_printf(p, " Local timer interrupts\n"); -} -#endif - #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST static void smp_timer_broadcast(const struct cpumask *mask) { @@ -559,11 +526,11 @@ static void percpu_timer_stop(void) unsigned int cpu = smp_processor_id(); struct clock_event_device *evt = &per_cpu(percpu_clockevent, cpu); - evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt); + local_timer_stop(evt); } #endif -static DEFINE_SPINLOCK(stop_lock); +static DEFINE_RAW_SPINLOCK(stop_lock); /* * ipi_cpu_stop - handle IPI from smp_send_stop() @@ -572,10 +539,10 @@ static void ipi_cpu_stop(unsigned int cpu) { if (system_state == SYSTEM_BOOTING || system_state == SYSTEM_RUNNING) { - spin_lock(&stop_lock); + raw_spin_lock(&stop_lock); printk(KERN_CRIT "CPU%u: stopping\n", cpu); dump_stack(); - spin_unlock(&stop_lock); + raw_spin_unlock(&stop_lock); } set_cpu_online(cpu, false); |