aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel
diff options
context:
space:
mode:
authorRussell King <rmk@dyn-67.arm.linux.org.uk>2005-11-08 14:08:05 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2005-11-08 14:08:05 -0500
commit37ee16ae93a3e4ae7dd51beb81d249f5f12a55c2 (patch)
treea6cf9773ddb5eae9f173c6a9c9d6120faa5688a4 /arch/arm/kernel
parent3b6353fae0d7ba772d7eb2651727332c9e9c74ac (diff)
[ARM SMP] Add core ARM support for local timers
Add infrastructure for supporting per-cpu local timers to update the profiling information and update system time accounting. Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/kernel')
-rw-r--r--arch/arm/kernel/entry-armv.S7
-rw-r--r--arch/arm/kernel/irq.c1
-rw-r--r--arch/arm/kernel/smp.c34
3 files changed, 42 insertions, 0 deletions
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index a511ec5b11a3..d9fb819bf7cc 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -47,6 +47,13 @@
47 movne r0, sp 47 movne r0, sp
48 adrne lr, 1b 48 adrne lr, 1b
49 bne do_IPI 49 bne do_IPI
50
51#ifdef CONFIG_LOCAL_TIMERS
52 test_for_ltirq r0, r6, r5, lr
53 movne r0, sp
54 adrne lr, 1b
55 bne do_local_timer
56#endif
50#endif 57#endif
51 58
52 .endm 59 .endm
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
index 6f86d0af7c56..d7099dbbb879 100644
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c
@@ -264,6 +264,7 @@ unlock:
264#endif 264#endif
265#ifdef CONFIG_SMP 265#ifdef CONFIG_SMP
266 show_ipi_list(p); 266 show_ipi_list(p);
267 show_local_irqs(p);
267#endif 268#endif
268 seq_printf(p, "Err: %10lu\n", irq_err_count); 269 seq_printf(p, "Err: %10lu\n", irq_err_count);
269 } 270 }
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index f5fc57e0fe41..77e2e9ca89fa 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -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();
@@ -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 *