summaryrefslogtreecommitdiffstats
path: root/arch/mips/sibyte
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2007-10-11 23:46:09 +0100
committerRalf Baechle <ralf@linux-mips.org>2007-10-11 23:46:09 +0100
commit7bcf7717b6a047c272410d0cd00213185fe6b99d (patch)
tree81c5d6bbc2130815713e22bb5408ea80b6e1c499 /arch/mips/sibyte
parent91a2fcc88634663e9e13dcdfad0e4a860e64aeee (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')
-rw-r--r--arch/mips/sibyte/Kconfig12
-rw-r--r--arch/mips/sibyte/bcm1480/irq.c13
-rw-r--r--arch/mips/sibyte/sb1250/irq.c50
-rw-r--r--arch/mips/sibyte/sb1250/time.c12
4 files changed, 55 insertions, 32 deletions
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 <asm/errno.h>
#include <asm/signal.h>
#include <asm/system.h>
+#include <asm/time.h>
#include <asm/io.h>
#include <asm/sibyte/sb1250_regs.h>
@@ -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.