From 7bcf7717b6a047c272410d0cd00213185fe6b99d Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Thu, 11 Oct 2007 23:46:09 +0100 Subject: [MIPS] Implement clockevents for R4000-style cp0 count/compare interrupt Signed-off-by: Ralf Baechle --- arch/mips/sibyte/Kconfig | 12 ++++++---- arch/mips/sibyte/bcm1480/irq.c | 13 ++++++++--- arch/mips/sibyte/sb1250/irq.c | 50 +++++++++++++++++++++++++++++++----------- arch/mips/sibyte/sb1250/time.c | 12 ---------- 4 files changed, 55 insertions(+), 32 deletions(-) (limited to 'arch/mips/sibyte') diff --git a/arch/mips/sibyte/Kconfig b/arch/mips/sibyte/Kconfig index 841b301c99f..e8fb880272b 100644 --- a/arch/mips/sibyte/Kconfig +++ b/arch/mips/sibyte/Kconfig @@ -1,6 +1,7 @@ config SIBYTE_SB1250 bool select HW_HAS_PCI + select IRQ_CPU select SIBYTE_ENABLE_LDT_IF_PCI select SIBYTE_HAS_ZBUS_PROFILING select SIBYTE_SB1xxx_SOC @@ -8,6 +9,7 @@ config SIBYTE_SB1250 config SIBYTE_BCM1120 bool + select IRQ_CPU select SIBYTE_BCM112X select SIBYTE_HAS_ZBUS_PROFILING select SIBYTE_SB1xxx_SOC @@ -15,6 +17,7 @@ config SIBYTE_BCM1120 config SIBYTE_BCM1125 bool select HW_HAS_PCI + select IRQ_CPU select SIBYTE_BCM112X select SIBYTE_HAS_ZBUS_PROFILING select SIBYTE_SB1xxx_SOC @@ -22,6 +25,7 @@ config SIBYTE_BCM1125 config SIBYTE_BCM1125H bool select HW_HAS_PCI + select IRQ_CPU select SIBYTE_BCM112X select SIBYTE_ENABLE_LDT_IF_PCI select SIBYTE_HAS_ZBUS_PROFILING @@ -29,12 +33,14 @@ config SIBYTE_BCM1125H config SIBYTE_BCM112X bool + select IRQ_CPU select SIBYTE_SB1xxx_SOC select SIBYTE_HAS_ZBUS_PROFILING config SIBYTE_BCM1x80 bool select HW_HAS_PCI + select IRQ_CPU select SIBYTE_HAS_ZBUS_PROFILING select SIBYTE_SB1xxx_SOC select SYS_SUPPORTS_SMP @@ -42,6 +48,7 @@ config SIBYTE_BCM1x80 config SIBYTE_BCM1x55 bool select HW_HAS_PCI + select IRQ_CPU select SIBYTE_SB1xxx_SOC select SIBYTE_HAS_ZBUS_PROFILING select SYS_SUPPORTS_SMP @@ -49,6 +56,7 @@ config SIBYTE_BCM1x55 config SIBYTE_SB1xxx_SOC bool select DMA_COHERENT + select IRQ_CPU select SIBYTE_CFE select SWAP_IO_SPACE select SYS_SUPPORTS_32BIT_KERNEL @@ -166,10 +174,6 @@ config SIBYTE_BW_TRACE buffer activity. Raw buffer data is dumped to console, and must be processed off-line. -config SIBYTE_SB1250_PROF - bool "Support for SB1/SOC profiling - SB1/SCD perf counters" - depends on SIBYTE_SB1xxx_SOC - config SIBYTE_TBPROF tristate "Support for ZBbus profiling" depends on SIBYTE_HAS_ZBUS_PROFILING diff --git a/arch/mips/sibyte/bcm1480/irq.c b/arch/mips/sibyte/bcm1480/irq.c index e729b5f3026..cf979dbb282 100644 --- a/arch/mips/sibyte/bcm1480/irq.c +++ b/arch/mips/sibyte/bcm1480/irq.c @@ -450,7 +450,6 @@ static void bcm1480_kgdb_interrupt(void) #endif /* CONFIG_KGDB */ -extern void bcm1480_timer_interrupt(void); extern void bcm1480_mailbox_interrupt(void); asmlinkage void plat_irq_dispatch(void) @@ -470,8 +469,16 @@ asmlinkage void plat_irq_dispatch(void) else #endif - if (pending & CAUSEF_IP4) - bcm1480_timer_interrupt(); + if (pending & CAUSEF_IP4) { + int cpu = smp_processor_id(); + int irq = K_BCM1480_INT_TIMER_0 + cpu; + + /* Reset the timer */ + __raw_writeq(M_SCD_TIMER_ENABLE|M_SCD_TIMER_MODE_CONTINUOUS, + IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG))); + + do_IRQ(irq); + } #ifdef CONFIG_SMP else if (pending & CAUSEF_IP3) diff --git a/arch/mips/sibyte/sb1250/irq.c b/arch/mips/sibyte/sb1250/irq.c index ad593a6c20b..6a4cc84194a 100644 --- a/arch/mips/sibyte/sb1250/irq.c +++ b/arch/mips/sibyte/sb1250/irq.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -399,18 +400,45 @@ static void sb1250_kgdb_interrupt(void) #endif /* CONFIG_KGDB */ -extern void sb1250_timer_interrupt(void); +static inline void sb1250_timer_interrupt(void) +{ + int cpu = smp_processor_id(); + int irq = K_INT_TIMER_0 + cpu; + + irq_enter(); + kstat_this_cpu.irqs[irq]++; + + write_seqlock(&xtime_lock); + + /* ACK interrupt */ + ____raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS, + IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG))); + + /* + * call the generic timer interrupt handling + */ + do_timer(1); + + write_sequnlock(&xtime_lock); + + /* + * In UP mode, we call local_timer_interrupt() to do profiling + * and process accouting. + * + * In SMP mode, local_timer_interrupt() is invoked by appropriate + * low-level local timer interrupt handler. + */ + local_timer_interrupt(irq); + + irq_exit(); +} + extern void sb1250_mailbox_interrupt(void); asmlinkage void plat_irq_dispatch(void) { unsigned int pending; -#ifdef CONFIG_SIBYTE_SB1250_PROF - /* Set compare to count to silence count/compare timer interrupts */ - write_c0_compare(read_c0_count()); -#endif - /* * What a pain. We have to be really careful saving the upper 32 bits * of any * register across function calls if we don't want them @@ -423,13 +451,9 @@ asmlinkage void plat_irq_dispatch(void) pending = read_c0_cause() & read_c0_status() & ST0_IM; -#ifdef CONFIG_SIBYTE_SB1250_PROF - if (pending & CAUSEF_IP7) /* Cpu performance counter interrupt */ - sbprof_cpu_intr(); - else -#endif - - if (pending & CAUSEF_IP4) + if (pending & CAUSEF_IP7) /* CPU performance counter interrupt */ + do_IRQ(MIPS_CPU_IRQ_BASE + 7); + else if (pending & CAUSEF_IP4) sb1250_timer_interrupt(); #ifdef CONFIG_SMP diff --git a/arch/mips/sibyte/sb1250/time.c b/arch/mips/sibyte/sb1250/time.c index 5bb83cd4c11..eb177075e9c 100644 --- a/arch/mips/sibyte/sb1250/time.c +++ b/arch/mips/sibyte/sb1250/time.c @@ -116,18 +116,6 @@ void sb1250_time_init(void) */ } -void sb1250_timer_interrupt(void) -{ - int cpu = smp_processor_id(); - int irq = K_INT_TIMER_0 + cpu; - - /* ACK interrupt */ - ____raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS, - IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG))); - - ll_timer_interrupt(irq); -} - /* * The HPT is free running from SB1250_HPT_VALUE down to 0 then starts over * again. -- cgit v1.2.3