aboutsummaryrefslogtreecommitdiff
path: root/arch/mips/sibyte/bcm1480/irq.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2007-10-22 10:38:44 +0100
committerRalf Baechle <ralf@linux-mips.org>2007-10-22 22:09:00 +0100
commitd04533650f64fe3367e180f3e488d92205152cd3 (patch)
tree5f183668d97d9655a8517e61afd46bfa2f80b101 /arch/mips/sibyte/bcm1480/irq.c
parent06d428d719dece96c01532b62df4140f4e69a308 (diff)
[MIPS] time: SMP-proofing of Sibyte clockevent/clocksource code.
The BCM148 has 4 cores but there are also just 4 generic timers available so use the ZBbus cycle counter instead of it. In addition the ZBbus counter also offers a much higher resolution and 64-bit counting so I'm considering a later complete conversion to it once I figure out if all members of the Sibyte SOC family support it - the docs seem to agree but the headers files seem to disagree ... Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/sibyte/bcm1480/irq.c')
-rw-r--r--arch/mips/sibyte/bcm1480/irq.c75
1 files changed, 41 insertions, 34 deletions
diff --git a/arch/mips/sibyte/bcm1480/irq.c b/arch/mips/sibyte/bcm1480/irq.c
index 7aa79bf63c4..10299bafeab 100644
--- a/arch/mips/sibyte/bcm1480/irq.c
+++ b/arch/mips/sibyte/bcm1480/irq.c
@@ -452,6 +452,43 @@ static void bcm1480_kgdb_interrupt(void)
extern void bcm1480_mailbox_interrupt(void);
+static inline void dispatch_ip4(void)
+{
+ 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);
+}
+
+static inline void dispatch_ip2(void)
+{
+ unsigned long long mask_h, mask_l;
+ unsigned int cpu = smp_processor_id();
+ unsigned long base;
+
+ /*
+ * Default...we've hit an IP[2] interrupt, which means we've got to
+ * check the 1480 interrupt registers to figure out what to do. Need
+ * to detect which CPU we're on, now that smp_affinity is supported.
+ */
+ base = A_BCM1480_IMR_MAPPER(cpu);
+ mask_h = __raw_readq(
+ IOADDR(base + R_BCM1480_IMR_INTERRUPT_STATUS_BASE_H));
+ mask_l = __raw_readq(
+ IOADDR(base + R_BCM1480_IMR_INTERRUPT_STATUS_BASE_L));
+
+ if (mask_h) {
+ if (mask_h ^ 1)
+ do_IRQ(fls64(mask_h) - 1);
+ else if (mask_l)
+ do_IRQ(63 + fls64(mask_l));
+ }
+}
+
asmlinkage void plat_irq_dispatch(void)
{
unsigned int pending;
@@ -469,17 +506,8 @@ asmlinkage void plat_irq_dispatch(void)
else
#endif
- 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);
- }
-
+ if (pending & CAUSEF_IP4)
+ dispatch_ip4();
#ifdef CONFIG_SMP
else if (pending & CAUSEF_IP3)
bcm1480_mailbox_interrupt();
@@ -490,27 +518,6 @@ asmlinkage void plat_irq_dispatch(void)
bcm1480_kgdb_interrupt(); /* KGDB (uart 1) */
#endif
- else if (pending & CAUSEF_IP2) {
- unsigned long long mask_h, mask_l;
- unsigned long base;
-
- /*
- * Default...we've hit an IP[2] interrupt, which means we've
- * got to check the 1480 interrupt registers to figure out what
- * to do. Need to detect which CPU we're on, now that
- * smp_affinity is supported.
- */
- base = A_BCM1480_IMR_MAPPER(smp_processor_id());
- mask_h = __raw_readq(
- IOADDR(base + R_BCM1480_IMR_INTERRUPT_STATUS_BASE_H));
- mask_l = __raw_readq(
- IOADDR(base + R_BCM1480_IMR_INTERRUPT_STATUS_BASE_L));
-
- if (mask_h) {
- if (mask_h ^ 1)
- do_IRQ(fls64(mask_h) - 1);
- else
- do_IRQ(63 + fls64(mask_l));
- }
- }
+ else if (pending & CAUSEF_IP2)
+ dispatch_ip2();
}