diff options
| -rw-r--r-- | target/linux/brcm63xx/patches-2.6.25/060-bcm963xx_rewrite_irq_handling_code.patch | 460 | ||||
| -rw-r--r-- | target/linux/brcm63xx/patches-2.6.25/080-bcm963xx_remove_unused_int_handler.patch | 95 | 
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 + | 
