]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/powerpc/platforms/pasemi/setup.c
Merge branch 'linus' into x86/irq
[linux-2.6-omap-h63xx.git] / arch / powerpc / platforms / pasemi / setup.c
index 2b638659d1eace8bb2e4f50eb80049a356dd90f1..c64fb5bfb37e3598ea6b44a64332210bc0bf5c8a 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/delay.h>
 #include <linux/console.h>
 #include <linux/pci.h>
+#include <linux/of_platform.h>
 
 #include <asm/prom.h>
 #include <asm/system.h>
@@ -35,7 +36,7 @@
 #include <asm/mpic.h>
 #include <asm/smp.h>
 #include <asm/time.h>
-#include <asm/of_platform.h>
+#include <asm/mmu.h>
 
 #include <pcmcia/ss.h>
 #include <pcmcia/cistpl.h>
@@ -60,6 +61,7 @@ struct mce_regs {
 
 static struct mce_regs mce_regs[MAX_MCE_REGS];
 static int num_mce_regs;
+static int nmi_virq = NO_IRQ;
 
 
 static void pas_restart(char *cmd)
@@ -133,9 +135,6 @@ static int __init pas_setup_mce_regs(void)
        struct pci_dev *dev;
        int reg;
 
-       if (!machine_is(pasemi))
-               return -ENODEV;
-
        /* Remap various SoC status registers for use by the MCE handler */
 
        reg = 0;
@@ -179,7 +178,7 @@ static int __init pas_setup_mce_regs(void)
 
        return 0;
 }
-device_initcall(pas_setup_mce_regs);
+machine_device_initcall(pasemi, pas_setup_mce_regs);
 
 static __init void pas_init_IRQ(void)
 {
@@ -188,6 +187,8 @@ static __init void pas_init_IRQ(void)
        unsigned long openpic_addr;
        const unsigned int *opprop;
        int naddr, opplen;
+       int mpic_flags;
+       const unsigned int *nmiprop;
        struct mpic *mpic;
 
        mpic_node = NULL;
@@ -220,13 +221,26 @@ static __init void pas_init_IRQ(void)
        openpic_addr = of_read_number(opprop, naddr);
        printk(KERN_DEBUG "OpenPIC addr: %lx\n", openpic_addr);
 
+       mpic_flags = MPIC_PRIMARY | MPIC_LARGE_VECTORS | MPIC_NO_BIAS;
+
+       nmiprop = of_get_property(mpic_node, "nmi-source", NULL);
+       if (nmiprop)
+               mpic_flags |= MPIC_ENABLE_MCK;
+
        mpic = mpic_alloc(mpic_node, openpic_addr,
-                         MPIC_PRIMARY|MPIC_LARGE_VECTORS,
-                         0, 0, " PAS-OPIC  ");
+                         mpic_flags, 0, 0, "PASEMI-OPIC");
        BUG_ON(!mpic);
 
        mpic_assign_isu(mpic, 0, openpic_addr + 0x10000);
        mpic_init(mpic);
+       /* The NMI/MCK source needs to be prio 15 */
+       if (nmiprop) {
+               nmi_virq = irq_create_mapping(NULL, *nmiprop);
+               mpic_irq_set_priority(nmi_virq, 15);
+               set_irq_type(nmi_virq, IRQ_TYPE_EDGE_RISING);
+               mpic_unmask_irq(nmi_virq);
+       }
+
        of_node_put(mpic_node);
        of_node_put(root);
 }
@@ -246,6 +260,14 @@ static int pas_machine_check_handler(struct pt_regs *regs)
 
        srr0 = regs->nip;
        srr1 = regs->msr;
+
+       if (nmi_virq != NO_IRQ && mpic_get_mcirq() == nmi_virq) {
+               printk(KERN_ERR "NMI delivered\n");
+               debugger(regs);
+               mpic_end_irq(nmi_virq);
+               goto out;
+       }
+
        dsisr = mfspr(SPRN_DSISR);
        printk(KERN_ERR "Machine Check on CPU %d\n", cpu);
        printk(KERN_ERR "SRR0  0x%016lx SRR1 0x%016lx\n", srr0, srr1);
@@ -302,14 +324,14 @@ static int pas_machine_check_handler(struct pt_regs *regs)
                int i;
 
                printk(KERN_ERR "slb contents:\n");
-               for (i = 0; i < SLB_NUM_ENTRIES; i++) {
+               for (i = 0; i < mmu_slb_size; i++) {
                        asm volatile("slbmfee  %0,%1" : "=r" (e) : "r" (i));
                        asm volatile("slbmfev  %0,%1" : "=r" (v) : "r" (i));
                        printk(KERN_ERR "%02d %016lx %016lx\n", i, e, v);
                }
        }
 
-
+out:
        /* SRR1[62] is from MSR[62] if recoverable, so pass that back */
        return !!(srr1 & 0x2);
 }
@@ -380,9 +402,6 @@ static struct of_device_id pasemi_bus_ids[] = {
 
 static int __init pasemi_publish_devices(void)
 {
-       if (!machine_is(pasemi))
-               return 0;
-
        pasemi_pcmcia_init();
 
        /* Publish OF platform devices for SDC and other non-PCI devices */
@@ -390,7 +409,7 @@ static int __init pasemi_publish_devices(void)
 
        return 0;
 }
-device_initcall(pasemi_publish_devices);
+machine_device_initcall(pasemi, pasemi_publish_devices);
 
 
 /*