|
|
|
@ -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;
|
|
|
|
|
+
|
|
|
|
|