summaryrefslogtreecommitdiffstats
path: root/target
diff options
context:
space:
mode:
Diffstat (limited to 'target')
-rw-r--r--target/linux/brcm63xx/patches-2.6.25/060-bcm963xx_rewrite_irq_handling_code.patch460
-rw-r--r--target/linux/brcm63xx/patches-2.6.25/080-bcm963xx_remove_unused_int_handler.patch95
2 files changed, 555 insertions, 0 deletions
diff --git a/target/linux/brcm63xx/patches-2.6.25/060-bcm963xx_rewrite_irq_handling_code.patch b/target/linux/brcm63xx/patches-2.6.25/060-bcm963xx_rewrite_irq_handling_code.patch
new file mode 100644
index 000000000..4f1e360a1
--- /dev/null
+++ b/target/linux/brcm63xx/patches-2.6.25/060-bcm963xx_rewrite_irq_handling_code.patch
@@ -0,0 +1,460 @@
+From 9a70f2dcb24a5aab29386373c86ba035acba4891 Mon Sep 17 00:00:00 2001
+From: Axel Gembe <ago@bastart.eu.org>
+Date: Sun, 18 May 2008 12:07:21 +0200
+Subject: [PATCH] bcm963xx: rewrite irq handling code
+
+This patch adds interrupt handling as on AR7. The old code was very messy and
+didn't work too well.
+
+Signed-off-by: Axel Gembe <ago@bastart.eu.org>
+---
+ arch/mips/bcm963xx/irq.c | 308 ++++++++++-------------------
+ drivers/serial/bcm63xx_cons.c | 13 +-
+ include/asm-mips/mach-bcm963xx/bcm_intr.h | 18 +--
+ 3 files changed, 119 insertions(+), 220 deletions(-)
+
+diff --git a/arch/mips/bcm963xx/irq.c b/arch/mips/bcm963xx/irq.c
+index 62a848b..11583c9 100644
+--- a/arch/mips/bcm963xx/irq.c
++++ b/arch/mips/bcm963xx/irq.c
+@@ -1,259 +1,159 @@
+ /*
+-<:copyright-gpl
+- Copyright 2002 Broadcom Corp. All Rights Reserved.
+-
+- This program is free software; you can distribute it and/or modify it
+- under the terms of the GNU General Public License (Version 2) as
+- published by the Free Software Foundation.
+-
+- This program is distributed in the hope it will be useful, but WITHOUT
+- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+- for more details.
+-
+- You should have received a copy of the GNU General Public License along
+- with this program; if not, write to the Free Software Foundation, Inc.,
+- 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+-:>
+-*/
+-/*
+- * Interrupt control functions for Broadcom 963xx MIPS boards
++ * Copyright (C) 2006,2007 Felix Fietkau <nbd@openwrt.org>
++ * Copyright (C) 2006,2007 Eugene Konev <ejka@openwrt.org>
++ * Copyright (C) 2008 Axel Gembe <ago@bastart.eu.org>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+-#include <asm/atomic.h>
+-
+-#include <linux/delay.h>
+-#include <linux/init.h>
+-#include <linux/ioport.h>
+-#include <linux/irq.h>
+ #include <linux/interrupt.h>
+-#include <linux/kernel.h>
+-#include <linux/slab.h>
+-#include <linux/module.h>
++#include <linux/io.h>
+
+-#include <asm/irq.h>
++#include <asm/irq_cpu.h>
+ #include <asm/mipsregs.h>
+-#include <asm/addrspace.h>
+-#include <asm/signal.h>
++
+ #include <6348_map_part.h>
+ #include <6348_intr.h>
+ #include <bcm_map_part.h>
+ #include <bcm_intr.h>
+
+-static void irq_dispatch_int(void)
+-{
+- unsigned int pendingIrqs;
+- static unsigned int irqBit;
+- static unsigned int isrNumber = 31;
+-
+- pendingIrqs = PERF->IrqStatus & PERF->IrqMask;
+- if (!pendingIrqs) {
+- return;
+- }
++static int bcm963xx_irq_base;
+
+- while (1) {
+- irqBit <<= 1;
+- isrNumber++;
+- if (isrNumber == 32) {
+- isrNumber = 0;
+- irqBit = 0x1;
+- }
+- if (pendingIrqs & irqBit) {
+- PERF->IrqMask &= ~irqBit; // mask
+- do_IRQ(isrNumber + INTERNAL_ISR_TABLE_OFFSET);
+- break;
+- }
+- }
++void bcm963xx_unmask_irq(unsigned int irq)
++{
++ PERF->IrqMask |= (1 << (irq - bcm963xx_irq_base));
+ }
+
+-static void irq_dispatch_ext(uint32 irq)
++void bcm963xx_mask_irq(unsigned int irq)
+ {
+- if (!(PERF->ExtIrqCfg & (1 << (irq - INTERRUPT_ID_EXTERNAL_0 + EI_MASK_SHFT)))) {
+- printk("**** Ext IRQ mask. Should not dispatch ****\n");
+- }
+- /* disable and clear interrupt in the controller */
+- PERF->ExtIrqCfg |= (1 << (irq - INTERRUPT_ID_EXTERNAL_0 + EI_CLEAR_SHFT));
+- PERF->ExtIrqCfg &= ~(1 << (irq - INTERRUPT_ID_EXTERNAL_0 + EI_MASK_SHFT));
+- do_IRQ(irq);
++ PERF->IrqMask &= ~(1 << (irq - bcm963xx_irq_base));
+ }
+
+-
+-//extern void brcm_timer_interrupt(struct pt_regs *regs);
+-
+-asmlinkage void plat_irq_dispatch(void)
++void bcm963xx_ack_irq(unsigned int irq)
+ {
+- unsigned long cause;
+-
+- cause = read_c0_status() & read_c0_cause() & ST0_IM;
+- if (cause & CAUSEF_IP7)
+- do_IRQ(7);
+- else if (cause & CAUSEF_IP2)
+- irq_dispatch_int();
+- else if (cause & CAUSEF_IP3)
+- irq_dispatch_ext(INTERRUPT_ID_EXTERNAL_0);
+- else if (cause & CAUSEF_IP4)
+- irq_dispatch_ext(INTERRUPT_ID_EXTERNAL_1);
+- else if (cause & CAUSEF_IP5)
+- irq_dispatch_ext(INTERRUPT_ID_EXTERNAL_2);
+- else if (cause & CAUSEF_IP6) {
+- irq_dispatch_ext(INTERRUPT_ID_EXTERNAL_3);
+- local_irq_disable();
+- }
++ PERF->IrqStatus &= ~(1 << (irq - bcm963xx_irq_base));
+ }
+
+-
+-void enable_brcm_irq(unsigned int irq)
++void bcm963xx_unmask_ext_irq(unsigned int irq)
+ {
+- unsigned long flags;
+-
+- local_irq_save(flags);
+- if( irq >= INTERNAL_ISR_TABLE_OFFSET ) {
+- PERF->IrqMask |= (1 << (irq - INTERNAL_ISR_TABLE_OFFSET));
+- }
+- else if (irq >= INTERRUPT_ID_EXTERNAL_0 && irq <= INTERRUPT_ID_EXTERNAL_3) {
+- /* enable and clear interrupt in the controller */
+- PERF->ExtIrqCfg |= (1 << (irq - INTERRUPT_ID_EXTERNAL_0 + EI_CLEAR_SHFT));
+ PERF->ExtIrqCfg |= (1 << (irq - INTERRUPT_ID_EXTERNAL_0 + EI_MASK_SHFT));
+- }
+- local_irq_restore(flags);
+ }
+
+-void disable_brcm_irq(unsigned int irq)
++void bcm963xx_mask_ext_irq(unsigned int irq)
+ {
+- unsigned long flags;
+-
+- local_irq_save(flags);
+- if( irq >= INTERNAL_ISR_TABLE_OFFSET ) {
+- PERF->IrqMask &= ~(1 << (irq - INTERNAL_ISR_TABLE_OFFSET));
+- }
+- else if (irq >= INTERRUPT_ID_EXTERNAL_0 && irq <= INTERRUPT_ID_EXTERNAL_3) {
+- /* disable interrupt in the controller */
+ PERF->ExtIrqCfg &= ~(1 << (irq - INTERRUPT_ID_EXTERNAL_0 + EI_MASK_SHFT));
+- }
+- local_irq_restore(flags);
+ }
+
+-void ack_brcm_irq(unsigned int irq)
++void bcm963xx_ack_ext_irq(unsigned int irq)
+ {
+- /* Already done in brcm_irq_dispatch */
++ PERF->ExtIrqCfg |= (1 << (irq - INTERRUPT_ID_EXTERNAL_0 + EI_CLEAR_SHFT));
+ }
+
+-unsigned int startup_brcm_irq(unsigned int irq)
++static void bcm963xx_dispatch_ext_irq(unsigned int irq)
+ {
+- enable_brcm_irq(irq);
+-
+- return 0; /* never anything pending */
++ bcm963xx_ack_ext_irq(irq);
++ bcm963xx_mask_ext_irq(irq);
++ do_IRQ(irq);
+ }
+
+-unsigned int startup_brcm_none(unsigned int irq)
++static void bcm963xx_cascade(void)
+ {
+- return 0;
+-}
++ uint32_t pending, bit, irq;
+
+-void end_brcm_irq(unsigned int irq)
+-{
+- if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+- enable_brcm_irq(irq);
+-}
++ if (!(pending = PERF->IrqStatus & PERF->IrqMask))
++ return;
+
+-void end_brcm_none(unsigned int irq)
+-{
++ for (irq = 0, bit = 1; irq < 32; irq++, bit <<= 1) {
++ if (pending & bit) {
++ bcm963xx_ack_irq(irq + bcm963xx_irq_base);
++ bcm963xx_mask_irq(irq + bcm963xx_irq_base);
++ do_IRQ(irq + bcm963xx_irq_base);
++ return;
++ }
++ }
++
++ spurious_interrupt();
+ }
+
+-static struct hw_interrupt_type brcm_irq_type = {
+- .typename = "MIPS",
+- .startup = startup_brcm_irq,
+- .shutdown = disable_brcm_irq,
+- .enable = enable_brcm_irq,
+- .disable = disable_brcm_irq,
+- .ack = ack_brcm_irq,
+- .end = end_brcm_irq,
+- .set_affinity = NULL
++static struct irq_chip bcm963xx_irq_type = {
++ .name = "bcm963xx",
++ .unmask = bcm963xx_unmask_irq,
++ .mask = bcm963xx_mask_irq,
++ .ack = bcm963xx_ack_irq
+ };
+
+-static struct hw_interrupt_type brcm_irq_no_end_type = {
+- .typename = "MIPS",
+- .startup = startup_brcm_none,
+- .shutdown = disable_brcm_irq,
+- .enable = enable_brcm_irq,
+- .disable = disable_brcm_irq,
+- .ack = ack_brcm_irq,
+- .end = end_brcm_none,
+- .set_affinity = NULL
++static struct irq_chip bcm963xx_ext_irq_type = {
++ .name = "bcm963xx_ext",
++ .unmask = bcm963xx_unmask_ext_irq,
++ .mask = bcm963xx_mask_ext_irq,
++ .ack = bcm963xx_ack_ext_irq,
+ };
+
+-void __init arch_init_irq(void)
++static struct irqaction bcm963xx_cascade_action = {
++ .handler = no_action,
++ .name = "BCM963xx cascade interrupt"
++};
++
++static void __init bcm963xx_irq_init(int base)
+ {
+ int i;
+
+- clear_c0_status(ST0_BEV);
+- change_c0_status(ST0_IM, (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4));
+-
+- for (i = 0; i < NR_IRQS; i++) {
+- irq_desc[i].status = IRQ_DISABLED;
+- irq_desc[i].action = 0;
+- irq_desc[i].depth = 1;
+- irq_desc[i].chip = &brcm_irq_type;
++ bcm963xx_irq_base = base;
++
++ /* External IRQs */
++ set_irq_chip_and_handler(INTERRUPT_ID_EXTERNAL_0, &bcm963xx_ext_irq_type,
++ handle_level_irq);
++ set_irq_chip_and_handler(INTERRUPT_ID_EXTERNAL_1, &bcm963xx_ext_irq_type,
++ handle_level_irq);
++ set_irq_chip_and_handler(INTERRUPT_ID_EXTERNAL_2, &bcm963xx_ext_irq_type,
++ handle_level_irq);
++ set_irq_chip_and_handler(INTERRUPT_ID_EXTERNAL_3, &bcm963xx_ext_irq_type,
++ handle_level_irq);
++
++ for (i = 0; i < 32; i++) {
++ set_irq_chip_and_handler(base + i, &bcm963xx_irq_type,
++ handle_level_irq);
+ }
++
++ setup_irq(2, &bcm963xx_cascade_action);
++ setup_irq(bcm963xx_irq_base, &bcm963xx_cascade_action);
++ set_c0_status(IE_IRQ0);
+ }
+
+-int request_external_irq(unsigned int irq,
+- FN_HANDLER handler,
+- unsigned long irqflags,
+- const char * devname,
+- void *dev_id)
++asmlinkage void plat_irq_dispatch(void)
+ {
+- unsigned long flags;
++ unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM;
+
+- local_irq_save(flags);
+-
+- PERF->ExtIrqCfg |= (1 << (irq - INTERRUPT_ID_EXTERNAL_0 + EI_CLEAR_SHFT)); // Clear
+- PERF->ExtIrqCfg &= ~(1 << (irq - INTERRUPT_ID_EXTERNAL_0 + EI_MASK_SHFT)); // Mask
+- PERF->ExtIrqCfg &= ~(1 << (irq - INTERRUPT_ID_EXTERNAL_0 + EI_INSENS_SHFT)); // Edge insesnsitive
+- PERF->ExtIrqCfg |= (1 << (irq - INTERRUPT_ID_EXTERNAL_0 + EI_LEVEL_SHFT)); // Level triggered
+- PERF->ExtIrqCfg &= ~(1 << (irq - INTERRUPT_ID_EXTERNAL_0 + EI_SENSE_SHFT)); // Low level
+-
+- local_irq_restore(flags);
+-
+- return( request_irq(irq, handler, irqflags, devname, dev_id) );
++ if (pending & STATUSF_IP7) /* cpu timer */
++ do_IRQ(7);
++ else if (pending & STATUSF_IP2) /* internal interrupt cascade */
++ bcm963xx_cascade();
++ else if (pending & STATUSF_IP3)
++ bcm963xx_dispatch_ext_irq(INTERRUPT_ID_EXTERNAL_0);
++ else if (pending & STATUSF_IP4)
++ bcm963xx_dispatch_ext_irq(INTERRUPT_ID_EXTERNAL_1);
++ else if (pending & STATUSF_IP5)
++ bcm963xx_dispatch_ext_irq(INTERRUPT_ID_EXTERNAL_2);
++ else if (pending & STATUSF_IP6)
++ bcm963xx_dispatch_ext_irq(INTERRUPT_ID_EXTERNAL_3);
++ else
++ spurious_interrupt();
+ }
+
+-/* VxWorks compatibility function(s). */
+-
+-unsigned int BcmHalMapInterrupt(FN_HANDLER pfunc, unsigned int param,
+- unsigned int interruptId)
++void __init arch_init_irq(void)
+ {
+- int nRet = -1;
+- char *devname;
+-
+- devname = kmalloc(16, GFP_KERNEL);
+- if (devname)
+- sprintf( devname, "brcm_%d", interruptId );
+-
+- /* Set the IRQ description to not automatically enable the interrupt at
+- * the end of an ISR. The driver that handles the interrupt must
+- * explicitly call BcmHalInterruptEnable or enable_brcm_irq. This behavior
+- * is consistent with interrupt handling on VxWorks.
+- */
+- irq_desc[interruptId].chip = &brcm_irq_no_end_type;
+-
+- if( interruptId >= INTERNAL_ISR_TABLE_OFFSET )
+- {
+- printk("BcmHalMapInterrupt : internal IRQ\n");
+- nRet = request_irq( interruptId, pfunc, IRQF_DISABLED, devname, (void *) param );
+- }
+- else if (interruptId >= INTERRUPT_ID_EXTERNAL_0 && interruptId <= INTERRUPT_ID_EXTERNAL_3)
+- {
+- printk("BcmHalMapInterrupt : external IRQ\n");
+- nRet = request_external_irq( interruptId, pfunc, IRQF_DISABLED, devname, (void *) param );
+- }
+-
+- return( nRet );
++ mips_cpu_irq_init();
++ bcm963xx_irq_init(INTERNAL_ISR_TABLE_OFFSET);
+ }
+-
+-
+-EXPORT_SYMBOL(enable_brcm_irq);
+-EXPORT_SYMBOL(disable_brcm_irq);
+-EXPORT_SYMBOL(request_external_irq);
+-EXPORT_SYMBOL(BcmHalMapInterrupt);
+-
+diff --git a/drivers/serial/bcm63xx_cons.c b/drivers/serial/bcm63xx_cons.c
+index 8fff16d..2302ea6 100644
+--- a/drivers/serial/bcm63xx_cons.c
++++ b/drivers/serial/bcm63xx_cons.c
+@@ -267,7 +267,7 @@ static void bcm_interrupt(int irq, void *dev, struct pt_regs *regs)
+ }
+
+ // Clear the interrupt
+- enable_brcm_irq(INTERRUPT_ID_UART);
++// bcm963xx_unmask_irq(INTERRUPT_ID_UART);
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+ return IRQ_HANDLED;
+ #endif
+@@ -880,7 +880,7 @@ static int bcm63xx_cons_open(struct tty_struct *tty, struct file *filp)
+ info->count++;
+ tty->driver_data = info;
+ info->tty = tty;
+- enable_brcm_irq(INTERRUPT_ID_UART);
++ bcm963xx_unmask_irq(INTERRUPT_ID_UART);
+
+ // Start up serial port
+ retval = startup(info);
+@@ -927,7 +927,7 @@ static struct tty_operations rs_ops = {
+ -------------------------------------------------------------------------- */
+ static int __init bcm63xx_serialinit(void)
+ {
+- int i, flags;
++ int i, flags, res;
+ struct bcm_serial *info;
+
+ // Print the driver version information
+@@ -981,7 +981,12 @@ static int __init bcm63xx_serialinit(void)
+ */
+ if (!info->port)
+ return 0;
+- BcmHalMapInterrupt(bcm_interrupt, 0, INTERRUPT_ID_UART);
++
++ res = request_irq(INTERRUPT_ID_UART, bcm_interrupt, 0, "bcm-uart", NULL);
++ if (res) {
++ spin_unlock_irqrestore(&bcm963xx_serial_lock, flags);
++ return res;
++ }
+ }
+
+ /* order matters here... the trick is that flags
+diff --git a/include/asm-mips/mach-bcm963xx/bcm_intr.h b/include/asm-mips/mach-bcm963xx/bcm_intr.h
+index 8c56840..920f783 100644
+--- a/include/asm-mips/mach-bcm963xx/bcm_intr.h
++++ b/include/asm-mips/mach-bcm963xx/bcm_intr.h
+@@ -39,18 +39,12 @@ struct pt_regs;
+ typedef int (*FN_HANDLER) (int, void *);
+
+ /* prototypes */
+-extern void enable_brcm_irq(unsigned int irq);
+-extern void disable_brcm_irq(unsigned int irq);
+-extern int request_external_irq(unsigned int irq,
+- FN_HANDLER handler, unsigned long irqflags,
+- const char * devname, void *dev_id);
+-extern unsigned int BcmHalMapInterrupt(FN_HANDLER isr, unsigned int param,
+- unsigned int interruptId);
+-extern void dump_intr_regs(void);
+-
+-/* compatibility definitions */
+-#define BcmHalInterruptEnable(irq) enable_brcm_irq( irq )
+-#define BcmHalInterruptDisable(irq) disable_brcm_irq( irq )
++extern void bcm963xx_unmask_irq(unsigned int irq);
++extern void bcm963xx_mask_irq(unsigned int irq);
++extern void bcm963xx_ack_irq(unsigned int irq);
++extern void bcm963xx_unmask_ext_irq(unsigned int irq);
++extern void bcm963xx_mask_ext_irq(unsigned int irq);
++extern void bcm963xx_ack_ext_irq(unsigned int irq);
+
+ #ifdef __cplusplus
+ }
+--
+1.5.5.1
+
diff --git a/target/linux/brcm63xx/patches-2.6.25/080-bcm963xx_remove_unused_int_handler.patch b/target/linux/brcm63xx/patches-2.6.25/080-bcm963xx_remove_unused_int_handler.patch
new file mode 100644
index 000000000..ad4484e31
--- /dev/null
+++ b/target/linux/brcm63xx/patches-2.6.25/080-bcm963xx_remove_unused_int_handler.patch
@@ -0,0 +1,95 @@
+From e3abd028e7631ee952fe73d8f9ee97bc615526a8 Mon Sep 17 00:00:00 2001
+From: Axel Gembe <ago@bastart.eu.org>
+Date: Sat, 17 May 2008 16:07:46 +0200
+Subject: [PATCH] bcm963xx: remove unused int-handler.S
+
+The code is not used anymore.
+
+Signed-off-by: Axel Gembe <ago@bastart.eu.org>
+---
+ arch/mips/bcm963xx/Makefile | 2 +-
+ arch/mips/bcm963xx/int-handler.S | 59 --------------------------------------
+ 2 files changed, 1 insertions(+), 60 deletions(-)
+ delete mode 100644 arch/mips/bcm963xx/int-handler.S
+
+diff --git a/arch/mips/bcm963xx/Makefile b/arch/mips/bcm963xx/Makefile
+index a9d1e55..77fbd84 100644
+--- a/arch/mips/bcm963xx/Makefile
++++ b/arch/mips/bcm963xx/Makefile
+@@ -3,7 +3,7 @@
+ #
+ # Copyright (C) 2004 Broadcom Corporation
+ #
+-obj-y := irq.o prom.o setup.o time.o ser_init.o int-handler.o info.o wdt.o
++obj-y := irq.o prom.o setup.o time.o ser_init.o info.o wdt.o
+
+ SRCBASE := $(TOPDIR)
+ EXTRA_CFLAGS += -I$(SRCBASE)/include
+diff --git a/arch/mips/bcm963xx/int-handler.S b/arch/mips/bcm963xx/int-handler.S
+deleted file mode 100644
+index a7a9c9d..0000000
+--- a/arch/mips/bcm963xx/int-handler.S
++++ /dev/null
+@@ -1,59 +0,0 @@
+-/*
+-<:copyright-gpl
+- Copyright 2002 Broadcom Corp. All Rights Reserved.
+-
+- This program is free software; you can distribute it and/or modify it
+- under the terms of the GNU General Public License (Version 2) as
+- published by the Free Software Foundation.
+-
+- This program is distributed in the hope it will be useful, but WITHOUT
+- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+- for more details.
+-
+- You should have received a copy of the GNU General Public License along
+- with this program; if not, write to the Free Software Foundation, Inc.,
+- 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+-:>
+-*/
+-/*
+- * Generic interrupt handler for Broadcom MIPS boards
+- */
+-
+-#include <linux/autoconf.h>
+-
+-#include <asm/asm.h>
+-#include <asm/mipsregs.h>
+-#include <asm/regdef.h>
+-#include <asm/stackframe.h>
+-
+-/*
+- * MIPS IRQ Source
+- * -------- ------
+- * 0 Software (ignored)
+- * 1 Software (ignored)
+- * 2 Combined hardware interrupt (hw0)
+- * 3 Hardware
+- * 4 Hardware
+- * 5 Hardware
+- * 6 Hardware
+- * 7 R4k timer
+- */
+-
+- .text
+- .set noreorder
+- .set noat
+- .align 5
+- NESTED(brcmIRQ, PT_SIZE, sp)
+- SAVE_ALL
+- CLI
+- .set noreorder
+- .set at
+-
+- jal plat_irq_dispatch
+- move a0, sp
+-
+- j ret_from_irq
+- nop
+-
+- END(brcmIRQ)
+--
+1.5.5.1
+