From 2285a11b8f3ed2fbec5998e07b5a07dc4770ba84 Mon Sep 17 00:00:00 2001
From: mbm <mbm@3c298f89-4303-0410-b956-a3cf2f4a3e73>
Date: Fri, 17 Feb 2006 23:27:51 +0000
Subject: [PATCH] add interrupt debugging; fix bug with the AP60 interrupt
 handler

git-svn-id: svn://svn.openwrt.org/openwrt/trunk@3250 3c298f89-4303-0410-b956-a3cf2f4a3e73
---
 .../linux/aruba-2.6/patches/002-irq.patch     | 59 +++++++++++++------
 1 file changed, 41 insertions(+), 18 deletions(-)

diff --git a/openwrt/target/linux/aruba-2.6/patches/002-irq.patch b/openwrt/target/linux/aruba-2.6/patches/002-irq.patch
index 308c39903..94e68cfb0 100644
--- a/openwrt/target/linux/aruba-2.6/patches/002-irq.patch
+++ b/openwrt/target/linux/aruba-2.6/patches/002-irq.patch
@@ -92,11 +92,12 @@ diff -Nur linux-2.6.15/arch/mips/aruba/idtIRQ.S linux-2.6.15-openwrt/arch/mips/a
 diff -Nur linux-2.6.15/arch/mips/aruba/irq.c linux-2.6.15-openwrt/arch/mips/aruba/irq.c
 --- linux-2.6.15/arch/mips/aruba/irq.c	1970-01-01 01:00:00.000000000 +0100
 +++ linux-2.6.15-openwrt/arch/mips/aruba/irq.c	2006-01-10 00:32:32.000000000 +0100
-@@ -0,0 +1,424 @@
+@@ -0,0 +1,447 @@
 +/**************************************************************************
 + *
 + *  BRIEF MODULE DESCRIPTION
-+ *     Interrupt routines for IDT EB434 boards
++ *     Interrupt routines for IDT EB434 boards / Atheros boards
++ *     Modified by Aruba Networks
 + *
 + *  Copyright 2004 IDT Inc. (rischelp@idt.com)
 + *         
@@ -275,7 +276,6 @@ diff -Nur linux-2.6.15/arch/mips/aruba/irq.c linux-2.6.15-openwrt/arch/mips/arub
 +		switch (mips_machtype) {
 +			case MACH_ARUBA_AP70:
 +				addr = intr_group_muscat[group].base_addr;
-+				// unmask intr within group
 +				WRITE_MASK_MUSCAT(addr, READ_MASK_MUSCAT(addr) & ~intr_bit);
 +				break;
 +			case MACH_ARUBA_AP65:
@@ -342,7 +342,7 @@ diff -Nur linux-2.6.15/arch/mips/aruba/irq.c linux-2.6.15-openwrt/arch/mips/arub
 +				mask = READ_MASK_MERLOT(addr);
 +				mask &= ~intr_bit;
 +				WRITE_MASK_MERLOT(addr, mask);
-+				if (!mask)
++				if (READ_MASK_MERLOT(addr))
 +					disable_local_irq(group_to_ip(group));
 +				break;
 +		}
@@ -381,11 +381,9 @@ diff -Nur linux-2.6.15/arch/mips/aruba/irq.c linux-2.6.15-openwrt/arch/mips/arub
 +
 +	local_irq_save(flags);
 +	if (irq_desc[irq_nr].status & (IRQ_DISABLED | IRQ_INPROGRESS)) {
-+		printk("warning: end_irq %d did not enable (%x) (ignoring)\n",
++		printk("warning: end_irq %d did not enable (%x)\n",
 +		       irq_nr, irq_desc[irq_nr].status);
-+	}
-+
-+	if (ip<0) {
++	} else if (ip<0) {
 +		enable_local_irq(irq_nr);
 +	} else {
 +
@@ -474,6 +472,25 @@ diff -Nur linux-2.6.15/arch/mips/aruba/irq.c linux-2.6.15-openwrt/arch/mips/arub
 +{
 +	unsigned int pend, group, ip;
 +	volatile unsigned int *addr;
++
++	if(cp0_cause == 0) {
++		printk("INTERRUPT(S) FIRED WHILE MASKED\n");
++
++		// debuging use -- figure out which interrupt(s) fired
++		cp0_cause = read_c0_cause() & CAUSEF_IP;
++		while (cp0_cause) {
++			unsigned long intr_bit;
++			unsigned int irq_nr;
++			intr_bit = (31 - rc32434_clz(cp0_cause));
++			irq_nr = intr_bit - GROUP0_IRQ_BASE;
++			printk(" ---> MASKED IRQ %d\n",irq_nr);
++			cp0_cause &= ~(1 << intr_bit);
++		}
++
++		return;
++	}
++
++	
 +	switch (mips_machtype) {
 +		case MACH_ARUBA_AP70:
 +			if ((ip = (cp0_cause & 0x7c00))) {
@@ -490,7 +507,7 @@ diff -Nur linux-2.6.15/arch/mips/aruba/irq.c linux-2.6.15-openwrt/arch/mips/arub
 +		case MACH_ARUBA_AP65:
 +		case MACH_ARUBA_AP60:
 +		default:
-+			if (cp0_cause & 0x4000) {
++			if (cp0_cause & 0x4000) { // 1 << (8 +6) == irq 6
 +				// Misc Interrupt
 +				group = 0;
 +				addr = intr_group_merlot[group].base_addr;
@@ -498,20 +515,26 @@ diff -Nur linux-2.6.15/arch/mips/aruba/irq.c linux-2.6.15-openwrt/arch/mips/arub
 +				pend &= READ_MASK_MERLOT(addr);	// only unmasked interrupts
 +				/* handle one misc interrupt at a time */
 +				while (pend) {
-+					unsigned int intr_bit, irq_nr;
-+					intr_bit = pend ^ (pend - 1);
-+					irq_nr = ((31 - rc32434_clz(pend)) + GROUP0_IRQ_BASE);
++					unsigned long intr_bit;
++					unsigned int irq_nr;
++
++					intr_bit = (31 - rc32434_clz(pend));
++					irq_nr = intr_bit + GROUP0_IRQ_BASE;
++
 +					do_IRQ(irq_nr, regs);
-+					pend &= ~intr_bit;
++					pend &= ~(1 << intr_bit);
 +				}
 +			}
-+			if (cp0_cause & 0x3c00) {
++			if (cp0_cause & 0x3c00) { // irq 2-5
 +				while (cp0_cause) {
-+					unsigned int intr_bit, irq_nr;
-+					intr_bit = cp0_cause ^ (cp0_cause - 1);
-+					irq_nr = ((31 - rc32434_clz(cp0_cause)) - GROUP0_IRQ_BASE);
++					unsigned long intr_bit;
++					unsigned int irq_nr;
++
++					intr_bit = (31 - rc32434_clz(cp0_cause));
++					irq_nr = intr_bit - GROUP0_IRQ_BASE;
++
 +					do_IRQ(irq_nr, regs);
-+					cp0_cause &= ~intr_bit;
++					cp0_cause &= ~(1 << intr_bit);
 +				}
 +			}
 +			break;
-- 
2.20.1