diff options
-rw-r--r-- | openwrt/target/linux/aruba-2.6/patches/002-irq.patch | 76 |
1 files changed, 29 insertions, 47 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 94e68cf..8faffaf 100644 --- a/openwrt/target/linux/aruba-2.6/patches/002-irq.patch +++ b/openwrt/target/linux/aruba-2.6/patches/002-irq.patch @@ -92,7 +92,7 @@ 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,447 @@ +@@ -0,0 +1,429 @@ +/************************************************************************** + * + * BRIEF MODULE DESCRIPTION @@ -183,8 +183,8 @@ diff -Nur linux-2.6.15/arch/mips/aruba/irq.c linux-2.6.15-openwrt/arch/mips/arub +}; + +#define READ_PEND_MERLOT(base) (*((volatile unsigned long *)(0xbc003010))) -+#define READ_MASK_MERLOT(base) (*((volatile unsigned long *)(0xbc003010 + 4))) -+#define WRITE_MASK_MERLOT(base, val) ((*((volatile unsigned long *)((0xbc003010) + 4))) = (val)) ++#define READ_MASK_MERLOT(base) (*((volatile unsigned long *)(0xbc003014))) ++#define WRITE_MASK_MERLOT(base, val) ((*((volatile unsigned long *)(0xbc003014))) = (val), READ_MASK_MERLOT()) + +static const intr_group_t intr_group_muscat[NUM_INTR_GROUPS] = { + {0x0000efff, (u32 *) KSEG1ADDR(IC_GROUP0_PEND + 0 * IC_GROUP_OFFSET)}, @@ -224,21 +224,14 @@ diff -Nur linux-2.6.15/arch/mips/aruba/irq.c linux-2.6.15-openwrt/arch/mips/arub + +static inline void enable_local_irq(unsigned int ip) +{ -+ int ipnum = 0x100 << ip; -+ clear_c0_cause(ipnum); -+ set_c0_status(ipnum); ++ set_c0_status(0x100 << ip); ++ irq_enable_hazard(); +} + +static inline void disable_local_irq(unsigned int ip) +{ -+ int ipnum = 0x100 << ip; -+ clear_c0_status(ipnum); -+} -+ -+static inline void ack_local_irq(unsigned int ip) -+{ -+ int ipnum = 0x100 << ip; -+ clear_c0_cause(ipnum); ++ clear_c0_status(0x100 << ip); ++ irq_disable_hazard(); +} + +static void aruba_enable_irq(unsigned int irq_nr) @@ -270,9 +263,6 @@ diff -Nur linux-2.6.15/arch/mips/aruba/irq.c linux-2.6.15-openwrt/arch/mips/arub + ip -= (group << 5); + intr_bit = 1 << ip; + -+ // first enable the IP mapped to this IRQ -+ enable_local_irq(group_to_ip(group)); -+ + switch (mips_machtype) { + case MACH_ARUBA_AP70: + addr = intr_group_muscat[group].base_addr; @@ -285,8 +275,10 @@ diff -Nur linux-2.6.15/arch/mips/aruba/irq.c linux-2.6.15-openwrt/arch/mips/arub + WRITE_MASK_MERLOT(addr, READ_MASK_MERLOT(addr) | intr_bit); + break; + } ++ enable_local_irq(group_to_ip(group)); + } + ++ back_to_back_c0_hazard(); + local_irq_restore(flags); + +} @@ -341,15 +333,15 @@ diff -Nur linux-2.6.15/arch/mips/aruba/irq.c linux-2.6.15-openwrt/arch/mips/arub + // mask intr within group + mask = READ_MASK_MERLOT(addr); + mask &= ~intr_bit; -+ WRITE_MASK_MERLOT(addr, mask); -+ if (READ_MASK_MERLOT(addr)) ++ if (!mask) + disable_local_irq(group_to_ip(group)); ++ WRITE_MASK_MERLOT(addr, mask); + break; + } + } + ++ back_to_back_c0_hazard(); + local_irq_restore(flags); -+ +} + +static unsigned int startup_irq(unsigned int irq_nr) @@ -361,29 +353,31 @@ diff -Nur linux-2.6.15/arch/mips/aruba/irq.c linux-2.6.15-openwrt/arch/mips/arub +static void shutdown_irq(unsigned int irq_nr) +{ + aruba_disable_irq(irq_nr); -+ return; +} + +static void mask_and_ack_irq(unsigned int irq_nr) +{ + aruba_disable_irq(irq_nr); -+ ack_local_irq(group_to_ip(irq_to_group(irq_nr))); +} + +static void end_irq(unsigned int irq_nr) +{ + -+ unsigned long flags; + int ip = irq_nr - GROUP0_IRQ_BASE; + unsigned int intr_bit, group; + volatile unsigned int *addr; + + -+ local_irq_save(flags); + if (irq_desc[irq_nr].status & (IRQ_DISABLED | IRQ_INPROGRESS)) { + printk("warning: end_irq %d did not enable (%x)\n", + irq_nr, irq_desc[irq_nr].status); -+ } else if (ip<0) { ++ /* fall through; enable the interrupt ++ * -- It'll get stuck otherwise ++ */ ++ ++ } ++ ++ if (ip<0) { + enable_local_irq(irq_nr); + } else { + @@ -409,7 +403,8 @@ diff -Nur linux-2.6.15/arch/mips/aruba/irq.c linux-2.6.15-openwrt/arch/mips/arub + break; + + case MACH_ARUBA_AP65: -+ case MACH_ARUBA_AP60: ++ case MACH_ARUBA_AP60: ++ default: + group = 0; + + // calc interrupt bit within group @@ -424,11 +419,10 @@ diff -Nur linux-2.6.15/arch/mips/aruba/irq.c linux-2.6.15-openwrt/arch/mips/arub + break; + } + } -+ local_irq_restore(flags); +} + +static struct hw_interrupt_type aruba_irq_type = { -+ .typename = "IDT434", ++ .typename = "ARUBA", + .startup = startup_irq, + .shutdown = shutdown_irq, + .enable = aruba_enable_irq, @@ -444,7 +438,6 @@ diff -Nur linux-2.6.15/arch/mips/aruba/irq.c linux-2.6.15-openwrt/arch/mips/arub + memset(irq_desc, 0, sizeof(irq_desc)); + set_except_vector(0, idtIRQ); + -+ + set_c0_status(0xFF00); + + for (i = 0; i < RC32434_NR_IRQS; i++) { @@ -454,17 +447,6 @@ diff -Nur linux-2.6.15/arch/mips/aruba/irq.c linux-2.6.15-openwrt/arch/mips/arub + irq_desc[i].handler = &aruba_irq_type; + spin_lock_init(&irq_desc[i].lock); + } -+ -+ switch (mips_machtype) { -+ case MACH_ARUBA_AP70: -+ break; -+ case MACH_ARUBA_AP65: -+ case MACH_ARUBA_AP60: -+ default: -+ WRITE_MASK_MERLOT(intr_group_merlot[0].base_addr, 0); -+ *((volatile unsigned long *)0xbc003014) = 0x10; -+ break; -+ } +} + +/* Main Interrupt dispatcher */ @@ -475,7 +457,7 @@ diff -Nur linux-2.6.15/arch/mips/aruba/irq.c linux-2.6.15-openwrt/arch/mips/arub + + if(cp0_cause == 0) { + printk("INTERRUPT(S) FIRED WHILE MASKED\n"); -+ ++#ifdef ARUBA_DEBUG + // debuging use -- figure out which interrupt(s) fired + cp0_cause = read_c0_cause() & CAUSEF_IP; + while (cp0_cause) { @@ -486,11 +468,10 @@ diff -Nur linux-2.6.15/arch/mips/aruba/irq.c linux-2.6.15-openwrt/arch/mips/arub + printk(" ---> MASKED IRQ %d\n",irq_nr); + cp0_cause &= ~(1 << intr_bit); + } -+ ++#endif + return; + } + -+ + switch (mips_machtype) { + case MACH_ARUBA_AP70: + if ((ip = (cp0_cause & 0x7c00))) { @@ -514,7 +495,8 @@ diff -Nur linux-2.6.15/arch/mips/aruba/irq.c linux-2.6.15-openwrt/arch/mips/arub + pend = READ_PEND_MERLOT(addr); + pend &= READ_MASK_MERLOT(addr); // only unmasked interrupts + /* handle one misc interrupt at a time */ -+ while (pend) { ++ while (pend) ++ { + unsigned long intr_bit; + unsigned int irq_nr; + @@ -524,9 +506,9 @@ diff -Nur linux-2.6.15/arch/mips/aruba/irq.c linux-2.6.15-openwrt/arch/mips/arub + do_IRQ(irq_nr, regs); + pend &= ~(1 << intr_bit); + } -+ } -+ if (cp0_cause & 0x3c00) { // irq 2-5 -+ while (cp0_cause) { ++ } else if (cp0_cause & 0x3c00) { // irq 2-5 ++ while (cp0_cause) ++ { + unsigned long intr_bit; + unsigned int irq_nr; + |