aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel/smp.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/kernel/smp.c')
-rw-r--r--arch/arm/kernel/smp.c42
1 files changed, 38 insertions, 4 deletions
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index edb5a406922f..77e2e9ca89fa 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -142,7 +142,7 @@ int __cpuinit __cpu_up(unsigned int cpu)
142 ret = -EIO; 142 ret = -EIO;
143 } 143 }
144 144
145 secondary_data.stack = 0; 145 secondary_data.stack = NULL;
146 secondary_data.pgdir = 0; 146 secondary_data.pgdir = 0;
147 147
148 *pmd_offset(pgd, PHYS_OFFSET) = __pmd(0); 148 *pmd_offset(pgd, PHYS_OFFSET) = __pmd(0);
@@ -185,6 +185,11 @@ int __cpuexit __cpu_disable(void)
185 migrate_irqs(); 185 migrate_irqs();
186 186
187 /* 187 /*
188 * Stop the local timer for this CPU.
189 */
190 local_timer_stop(cpu);
191
192 /*
188 * Flush user cache and TLB mappings, and then remove this CPU 193 * Flush user cache and TLB mappings, and then remove this CPU
189 * from the vm mask set of all processes. 194 * from the vm mask set of all processes.
190 */ 195 */
@@ -290,6 +295,11 @@ asmlinkage void __cpuinit secondary_start_kernel(void)
290 cpu_set(cpu, cpu_online_map); 295 cpu_set(cpu, cpu_online_map);
291 296
292 /* 297 /*
298 * Setup local timer for this CPU.
299 */
300 local_timer_setup(cpu);
301
302 /*
293 * OK, it's off to the idle thread for us 303 * OK, it's off to the idle thread for us
294 */ 304 */
295 cpu_idle(); 305 cpu_idle();
@@ -359,8 +369,8 @@ static void send_ipi_message(cpumask_t callmap, enum ipi_msg_type msg)
359 * You must not call this function with disabled interrupts, from a 369 * You must not call this function with disabled interrupts, from a
360 * hardware interrupt handler, nor from a bottom half handler. 370 * hardware interrupt handler, nor from a bottom half handler.
361 */ 371 */
362int smp_call_function_on_cpu(void (*func)(void *info), void *info, int retry, 372static int smp_call_function_on_cpu(void (*func)(void *info), void *info,
363 int wait, cpumask_t callmap) 373 int retry, int wait, cpumask_t callmap)
364{ 374{
365 struct smp_call_struct data; 375 struct smp_call_struct data;
366 unsigned long timeout; 376 unsigned long timeout;
@@ -454,6 +464,18 @@ void show_ipi_list(struct seq_file *p)
454 seq_putc(p, '\n'); 464 seq_putc(p, '\n');
455} 465}
456 466
467void show_local_irqs(struct seq_file *p)
468{
469 unsigned int cpu;
470
471 seq_printf(p, "LOC: ");
472
473 for_each_present_cpu(cpu)
474 seq_printf(p, "%10u ", irq_stat[cpu].local_timer_irqs);
475
476 seq_putc(p, '\n');
477}
478
457static void ipi_timer(struct pt_regs *regs) 479static void ipi_timer(struct pt_regs *regs)
458{ 480{
459 int user = user_mode(regs); 481 int user = user_mode(regs);
@@ -464,6 +486,18 @@ static void ipi_timer(struct pt_regs *regs)
464 irq_exit(); 486 irq_exit();
465} 487}
466 488
489#ifdef CONFIG_LOCAL_TIMERS
490asmlinkage void do_local_timer(struct pt_regs *regs)
491{
492 int cpu = smp_processor_id();
493
494 if (local_timer_ack()) {
495 irq_stat[cpu].local_timer_irqs++;
496 ipi_timer(regs);
497 }
498}
499#endif
500
467/* 501/*
468 * ipi_call_function - handle IPI from smp_call_function() 502 * ipi_call_function - handle IPI from smp_call_function()
469 * 503 *
@@ -515,7 +549,7 @@ static void ipi_cpu_stop(unsigned int cpu)
515 * 549 *
516 * Bit 0 - Inter-processor function call 550 * Bit 0 - Inter-processor function call
517 */ 551 */
518void do_IPI(struct pt_regs *regs) 552asmlinkage void do_IPI(struct pt_regs *regs)
519{ 553{
520 unsigned int cpu = smp_processor_id(); 554 unsigned int cpu = smp_processor_id();
521 struct ipi_data *ipi = &per_cpu(ipi_data, cpu); 555 struct ipi_data *ipi = &per_cpu(ipi_data, cpu);