This commit was manufactured by cvs2svn to create tag
[linux-2.6.git] / arch / ppc / syslib / ppc8xx_pic.c
index d3b01c6..8481a41 100644 (file)
@@ -4,14 +4,11 @@
 #include <linux/init.h>
 #include <linux/sched.h>
 #include <linux/signal.h>
-#include <linux/interrupt.h>
 #include <asm/irq.h>
 #include <asm/8xx_immap.h>
 #include <asm/mpc8xx.h>
 #include "ppc8xx_pic.h"
 
-extern int cpm_get_irq(struct pt_regs *regs);
-
 /* The 8xx internal interrupt controller.  It is usually
  * the only interrupt controller.  Some boards, like the MBX and
  * Sandpoint have the 8259 as a secondary controller.  Depending
@@ -75,13 +72,46 @@ static void m8xx_mask_and_ack(unsigned int irq_nr)
 }
 
 struct hw_interrupt_type ppc8xx_pic = {
-       .typename = " 8xx SIU  ",
-       .enable = m8xx_unmask_irq,
-       .disable = m8xx_mask_irq,
-       .ack = m8xx_mask_and_ack,
-       .end = m8xx_end_irq,
+       " 8xx SIU  ",
+       NULL,
+       NULL,
+       m8xx_unmask_irq,
+       m8xx_mask_irq,
+       m8xx_mask_and_ack,
+       m8xx_end_irq,
+       0
 };
 
+#if 0
+void
+m8xx_do_IRQ(struct pt_regs *regs,
+          int            cpu)
+{
+       int irq;
+        unsigned long bits = 0;
+
+        /* For MPC8xx, read the SIVEC register and shift the bits down
+         * to get the irq number.         */
+        bits = ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_sivec;
+        irq = bits >> 26;
+#if 0
+        irq += ppc8xx_pic.irq_offset;
+#endif
+        bits = 1UL << irq;
+
+       if (irq < 0) {
+               printk(KERN_DEBUG "Bogus interrupt %d from PC = %lx\n",
+                      irq, regs->nip);
+               ppc_spurious_interrupts++;
+       }
+       else {
+                ppc_irq_dispatch_handler( regs, irq );
+       }
+
+}
+#endif
+
+
 /*
  * We either return a valid interrupt or -1 if there is nothing pending
  */
@@ -99,32 +129,73 @@ m8xx_get_irq(struct pt_regs *regs)
         * When we read the sivec without an interrupt to process, we will
         * get back SIU_LEVEL7.  In this case, return -1
         */
-        if (irq == CPM_INTERRUPT)
-               irq = CPM_IRQ_OFFSET + cpm_get_irq(regs);
-#if defined(CONFIG_PCI)
-       else if (irq == ISA_BRIDGE_INT) {
-               int isa_irq;
-
-               if ((isa_irq = i8259_poll(regs)) >= 0)
-                       irq = I8259_IRQ_OFFSET + isa_irq;
-       }
-#endif /* CONFIG_PCI */
-       else if (irq == SIU_LEVEL7)
-               irq = -1;
+       if (irq == SIU_LEVEL7)
+               return -1;
 
        return irq;
 }
 
+/* The MBX is the only 8xx board that uses the 8259.
+*/
 #if defined(CONFIG_MBX) && defined(CONFIG_PCI)
+void mbx_i8259_action(int cpl, void *dev_id, struct pt_regs *regs)
+{
+       int bits, irq;
+
+       /* A bug in the QSpan chip causes it to give us 0xff always
+        * when doing a character read.  So read 32 bits and shift.
+        * This doesn't seem to return useful values anyway, but
+        * read it to make sure things are acked.
+        * -- Cort
+        */
+       irq = (inl(0x508) >> 24)&0xff;
+       if ( irq != 0xff ) printk("iack %d\n", irq);
+
+       outb(0x0C, 0x20);
+       irq = inb(0x20) & 7;
+       if (irq == 2)
+       {
+               outb(0x0C, 0xA0);
+               irq = inb(0xA0);
+               irq = (irq&7) + 8;
+       }
+       bits = 1UL << irq;
+       irq += i8259_pic.irq_offset;
+       ppc_irq_dispatch_handler( regs, irq );
+}
+#endif
+
 /* Only the MBX uses the external 8259.  This allows us to catch standard
  * drivers that may mess up the internal interrupt controllers, and also
  * allow them to run without modification on the MBX.
  */
-void mbx_i8259_action(int irq, void *dev_id, struct pt_regs *regs)
+int request_irq(unsigned int irq,
+       irqreturn_t (*handler)(int, void *, struct pt_regs *),
+       unsigned long irqflags, const char * devname, void *dev_id)
 {
-       /* This interrupt handler never actually gets called.  It is
-        * installed only to unmask the 8259 cascade interrupt in the SIU
-        * and to make the 8259 cascade interrupt visible in /proc/interrupts.
+
+#if defined(CONFIG_MBX) && defined(CONFIG_PCI)
+       irq += i8259_pic.irq_offset;
+       return (request_8xxirq(irq, handler, irqflags, devname, dev_id));
+#else
+       /*
+        * Handle other "well-known" interrupts, but panic on unknown ones.
         */
+       switch (irq) {
+#ifdef IDE0_INTERRUPT
+               case IDE0_INTERRUPT:    /* IDE0 */
+                       return (request_8xxirq(irq, handler, irqflags, devname,
+                                               dev_id));
+#endif
+#ifdef IDE1_INTERRUPT
+               case IDE1_INTERRUPT:    /* IDE1 */
+                       return (request_8xxirq(irq, handler, irqflags, devname,
+                                               dev_id));
+#endif
+       default:                        /* unknown IRQ -> panic */
+               panic("request_irq");
+       }
+#endif
 }
-#endif /* CONFIG_PCI */
+
+EXPORT_SYMBOL(request_irq);