diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2007-10-11 18:46:09 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2007-10-11 18:46:09 -0400 |
commit | 7bcf7717b6a047c272410d0cd00213185fe6b99d (patch) | |
tree | 81c5d6bbc2130815713e22bb5408ea80b6e1c499 /arch/mips/sibyte/sb1250 | |
parent | 91a2fcc88634663e9e13dcdfad0e4a860e64aeee (diff) |
[MIPS] Implement clockevents for R4000-style cp0 count/compare interrupt
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/sibyte/sb1250')
-rw-r--r-- | arch/mips/sibyte/sb1250/irq.c | 50 | ||||
-rw-r--r-- | arch/mips/sibyte/sb1250/time.c | 12 |
2 files changed, 37 insertions, 25 deletions
diff --git a/arch/mips/sibyte/sb1250/irq.c b/arch/mips/sibyte/sb1250/irq.c index ad593a6c20be..6a4cc84194a9 100644 --- a/arch/mips/sibyte/sb1250/irq.c +++ b/arch/mips/sibyte/sb1250/irq.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <asm/errno.h> | 28 | #include <asm/errno.h> |
29 | #include <asm/signal.h> | 29 | #include <asm/signal.h> |
30 | #include <asm/system.h> | 30 | #include <asm/system.h> |
31 | #include <asm/time.h> | ||
31 | #include <asm/io.h> | 32 | #include <asm/io.h> |
32 | 33 | ||
33 | #include <asm/sibyte/sb1250_regs.h> | 34 | #include <asm/sibyte/sb1250_regs.h> |
@@ -399,18 +400,45 @@ static void sb1250_kgdb_interrupt(void) | |||
399 | 400 | ||
400 | #endif /* CONFIG_KGDB */ | 401 | #endif /* CONFIG_KGDB */ |
401 | 402 | ||
402 | extern void sb1250_timer_interrupt(void); | 403 | static inline void sb1250_timer_interrupt(void) |
404 | { | ||
405 | int cpu = smp_processor_id(); | ||
406 | int irq = K_INT_TIMER_0 + cpu; | ||
407 | |||
408 | irq_enter(); | ||
409 | kstat_this_cpu.irqs[irq]++; | ||
410 | |||
411 | write_seqlock(&xtime_lock); | ||
412 | |||
413 | /* ACK interrupt */ | ||
414 | ____raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS, | ||
415 | IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG))); | ||
416 | |||
417 | /* | ||
418 | * call the generic timer interrupt handling | ||
419 | */ | ||
420 | do_timer(1); | ||
421 | |||
422 | write_sequnlock(&xtime_lock); | ||
423 | |||
424 | /* | ||
425 | * In UP mode, we call local_timer_interrupt() to do profiling | ||
426 | * and process accouting. | ||
427 | * | ||
428 | * In SMP mode, local_timer_interrupt() is invoked by appropriate | ||
429 | * low-level local timer interrupt handler. | ||
430 | */ | ||
431 | local_timer_interrupt(irq); | ||
432 | |||
433 | irq_exit(); | ||
434 | } | ||
435 | |||
403 | extern void sb1250_mailbox_interrupt(void); | 436 | extern void sb1250_mailbox_interrupt(void); |
404 | 437 | ||
405 | asmlinkage void plat_irq_dispatch(void) | 438 | asmlinkage void plat_irq_dispatch(void) |
406 | { | 439 | { |
407 | unsigned int pending; | 440 | unsigned int pending; |
408 | 441 | ||
409 | #ifdef CONFIG_SIBYTE_SB1250_PROF | ||
410 | /* Set compare to count to silence count/compare timer interrupts */ | ||
411 | write_c0_compare(read_c0_count()); | ||
412 | #endif | ||
413 | |||
414 | /* | 442 | /* |
415 | * What a pain. We have to be really careful saving the upper 32 bits | 443 | * What a pain. We have to be really careful saving the upper 32 bits |
416 | * of any * register across function calls if we don't want them | 444 | * of any * register across function calls if we don't want them |
@@ -423,13 +451,9 @@ asmlinkage void plat_irq_dispatch(void) | |||
423 | 451 | ||
424 | pending = read_c0_cause() & read_c0_status() & ST0_IM; | 452 | pending = read_c0_cause() & read_c0_status() & ST0_IM; |
425 | 453 | ||
426 | #ifdef CONFIG_SIBYTE_SB1250_PROF | 454 | if (pending & CAUSEF_IP7) /* CPU performance counter interrupt */ |
427 | if (pending & CAUSEF_IP7) /* Cpu performance counter interrupt */ | 455 | do_IRQ(MIPS_CPU_IRQ_BASE + 7); |
428 | sbprof_cpu_intr(); | 456 | else if (pending & CAUSEF_IP4) |
429 | else | ||
430 | #endif | ||
431 | |||
432 | if (pending & CAUSEF_IP4) | ||
433 | sb1250_timer_interrupt(); | 457 | sb1250_timer_interrupt(); |
434 | 458 | ||
435 | #ifdef CONFIG_SMP | 459 | #ifdef CONFIG_SMP |
diff --git a/arch/mips/sibyte/sb1250/time.c b/arch/mips/sibyte/sb1250/time.c index 5bb83cd4c113..eb177075e9c0 100644 --- a/arch/mips/sibyte/sb1250/time.c +++ b/arch/mips/sibyte/sb1250/time.c | |||
@@ -116,18 +116,6 @@ void sb1250_time_init(void) | |||
116 | */ | 116 | */ |
117 | } | 117 | } |
118 | 118 | ||
119 | void sb1250_timer_interrupt(void) | ||
120 | { | ||
121 | int cpu = smp_processor_id(); | ||
122 | int irq = K_INT_TIMER_0 + cpu; | ||
123 | |||
124 | /* ACK interrupt */ | ||
125 | ____raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS, | ||
126 | IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG))); | ||
127 | |||
128 | ll_timer_interrupt(irq); | ||
129 | } | ||
130 | |||
131 | /* | 119 | /* |
132 | * The HPT is free running from SB1250_HPT_VALUE down to 0 then starts over | 120 | * The HPT is free running from SB1250_HPT_VALUE down to 0 then starts over |
133 | * again. | 121 | * again. |