diff options
Diffstat (limited to 'arch/arm/kernel/smp.c')
-rw-r--r-- | arch/arm/kernel/smp.c | 42 |
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 | */ |
362 | int smp_call_function_on_cpu(void (*func)(void *info), void *info, int retry, | 372 | static 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 | ||
467 | void 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 | |||
457 | static void ipi_timer(struct pt_regs *regs) | 479 | static 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 | ||
490 | asmlinkage 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 | */ |
518 | void do_IPI(struct pt_regs *regs) | 552 | asmlinkage 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); |