patch-2.2.17 linux/arch/ppc/kernel/pmac_pic.c

Next file: linux/arch/ppc/kernel/pmac_setup.c
Previous file: linux/arch/ppc/kernel/pmac_pci.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.2.16/arch/ppc/kernel/pmac_pic.c linux/arch/ppc/kernel/pmac_pic.c
@@ -4,6 +4,7 @@
 #include <linux/sched.h>
 #include <linux/signal.h>
 #include <linux/pci.h>
+#include <linux/openpic.h>
 #include <asm/pci-bridge.h>
 #include <asm/io.h>
 #include <asm/smp.h>
@@ -27,6 +28,7 @@
 
 static int max_irqs;
 static int max_real_irqs;
+static int has_openpic = 0;
 
 #define MAXCOUNT 10000000
 
@@ -104,6 +106,18 @@
         pmac_set_irq_mask(irq_nr);
 }
 
+static void pmac_openpic_mask_irq(unsigned int irq_nr)
+{
+	openpic_disable_irq(irq_nr);
+}
+
+static void pmac_openpic_unmask_irq(unsigned int irq_nr)
+{
+	openpic_enable_irq(irq_nr);
+}
+
+
+
 struct hw_interrupt_type pmac_pic = {
         " PMAC-PIC ",
         NULL,
@@ -126,6 +140,17 @@
 	0
 };
 
+struct hw_interrupt_type pmac_open_pic = {
+	" OpenPIC  ",
+	NULL,
+	NULL,
+	NULL,
+	pmac_openpic_unmask_irq,
+	pmac_openpic_mask_irq,
+	NULL,/*pmac_openpic_mask_irq,*/
+	0
+};
+
 static void gatwick_action(int cpl, void *dev_id, struct pt_regs *regs)
 {
 	int irq, bits;
@@ -196,6 +221,29 @@
         }
 #endif /* __SMP__ */
 
+	/* Yeah, I know, this could be a separate do_IRQ function */
+	if (has_openpic) {
+	    irq = openpic_irq(0);
+	    if (irq == OPENPIC_VEC_SPURIOUS) {
+                /* Spurious interrupts should never be ack'ed */
+                ppc_spurious_interrupts++;
+            } else {
+            	/* Can this happen ? (comes from CHRP code) */
+		if (irq < 0) {
+		    printk(KERN_DEBUG "Bogus interrupt %d from PC = %lx\n",
+                       irq, regs->nip);
+		    ppc_spurious_interrupts++;
+		} else {
+		    if (!irq_desc[irq].level)
+	                openpic_eoi(0);
+		    ppc_irq_dispatch_handler( regs, irq );
+		    if (irq_desc[irq].level)
+	                openpic_eoi(0);
+		}
+            }
+            return;
+	}
+
         for (irq = max_real_irqs - 1; irq > 0; irq -= 32) {
                 int i = irq >> 5;
                 bits = ld_le32(&pmac_irq_hw[i]->flag)
@@ -350,6 +398,36 @@
         struct device_node *irqctrler;
         volatile struct pmac_irq_hw *addr;
 	int second_irq;
+
+	/* We first try to detect Apple's new Core99 chipset, since mac-io
+	 * is quite different on those machines and contains an IBM MPIC2.
+	 */
+	irqctrler = find_type_devices("open-pic");
+	if (irqctrler != NULL) {
+	    printk("PowerMac using OpenPIC irq controller\n");
+	    if (irqctrler->n_addrs > 0) {
+#ifdef CONFIG_XMON
+		struct device_node* pswitch;
+#endif /* CONFIG_XMON */	
+		OpenPIC = (volatile struct OpenPIC *)
+			ioremap(irqctrler->addrs[0].address,
+			irqctrler->addrs[0].size);
+		for ( i = 0 ; i < NR_IRQS ; i++ ) {
+		    irq_desc[i].ctl = &pmac_open_pic;
+		    irq_desc[i].level = 0;
+		}
+		openpic_init(1);
+		has_openpic = 1;
+#ifdef CONFIG_XMON
+		pswitch = find_devices("programmer-switch");
+		if (pswitch && pswitch->n_intrs)
+			request_irq(pswitch->intrs[0].line, xmon_irq, 0,	
+				"NMI - XMON", 0);
+#endif	/* CONFIG_XMON */
+		return;
+	    }
+	    irqctrler = NULL;
+	}
 
 	/*
 	 * G3 powermacs and 1999 G3 PowerBooks have 64 interrupts,

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)