Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git] / arch / ppc / syslib / mpc52xx_pic.c
index 0f88e63..c4406f9 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * arch/ppc/syslib/mpc52xx_pic.c
- *
  * Programmable Interrupt Controller functions for the Freescale MPC52xx 
  * embedded CPU.
  *
@@ -33,8 +31,8 @@
 #include <asm/mpc52xx.h>
 
 
-static struct mpc52xx_intr *intr;
-static struct mpc52xx_sdma *sdma;
+static struct mpc52xx_intr __iomem *intr;
+static struct mpc52xx_sdma __iomem *sdma;
 
 static void
 mpc52xx_ic_disable(unsigned int irq)
@@ -114,7 +112,7 @@ mpc52xx_ic_ack(unsigned int irq)
        /*
         * Only some irqs are reset here, others in interrupting hardware.
         */
-                       
+
        switch (irq) {
        case MPC52xx_IRQ0:
                val = in_be32(&intr->ctrl);
@@ -166,27 +164,23 @@ mpc52xx_ic_end(unsigned int irq)
 }
 
 static struct hw_interrupt_type mpc52xx_ic = {
-       "MPC52xx",
-       NULL,                           /* startup(irq) */
-       NULL,                           /* shutdown(irq) */
-       mpc52xx_ic_enable,              /* enable(irq) */
-       mpc52xx_ic_disable,             /* disable(irq) */
-       mpc52xx_ic_disable_and_ack,     /* disable_and_ack(irq) */
-       mpc52xx_ic_end,                 /* end(irq) */
-       0                               /* set_affinity(irq, cpumask) SMP. */
+       .typename       = " MPC52xx  ",
+       .enable         = mpc52xx_ic_enable,
+       .disable        = mpc52xx_ic_disable,
+       .ack            = mpc52xx_ic_disable_and_ack,
+       .end            = mpc52xx_ic_end,
 };
 
 void __init
 mpc52xx_init_irq(void)
 {
        int i;
+       u32 intr_ctrl;
 
        /* Remap the necessary zones */
-       intr = (struct mpc52xx_intr *)
-               ioremap(MPC52xx_INTR, sizeof(struct mpc52xx_intr));
-       sdma = (struct mpc52xx_sdma *)
-               ioremap(MPC52xx_SDMA, sizeof(struct mpc52xx_sdma));
-       
+       intr = ioremap(MPC52xx_PA(MPC52xx_INTR_OFFSET), MPC52xx_INTR_SIZE);
+       sdma = ioremap(MPC52xx_PA(MPC52xx_SDMA_OFFSET), MPC52xx_SDMA_SIZE);
+
        if ((intr==NULL) || (sdma==NULL))
                panic("Can't ioremap PIC/SDMA register for init_irq !");
 
@@ -195,12 +189,13 @@ mpc52xx_init_irq(void)
        out_be32(&sdma->IntMask, 0xffffffff);   /* 1 means disabled */
        out_be32(&intr->per_mask, 0x7ffffc00);  /* 1 means disabled */
        out_be32(&intr->main_mask, 0x00010fff); /* 1 means disabled */
-       out_be32(&intr->ctrl,
-                       0x0f000000 |    /* clear IRQ 0-3 */
-                       0x00c00000 |    /* IRQ0: level-sensitive, active low */
+       intr_ctrl = in_be32(&intr->ctrl);
+       intr_ctrl &=    0x00ff0000;     /* Keeps IRQ[0-3] config */
+       intr_ctrl |=    0x0f000000 |    /* clear IRQ 0-3 */
                        0x00001000 |    /* MEE master external enable */
                        0x00000000 |    /* 0 means disable IRQ 0-3 */
-                       0x00000001);    /* CEb route critical normally */
+                       0x00000001;     /* CEb route critical normally */
+       out_be32(&intr->ctrl, intr_ctrl);
 
        /* Zero a bunch of the priority settings.  */
        out_be32(&intr->per_pri1, 0);
@@ -214,6 +209,14 @@ mpc52xx_init_irq(void)
                irq_desc[i].handler = &mpc52xx_ic;
                irq_desc[i].status = IRQ_LEVEL;
        }
+
+       #define IRQn_MODE(intr_ctrl,irq) (((intr_ctrl) >> (22-(i<<1))) & 0x03)
+       for (i=0 ; i<4 ; i++) {
+               int mode;
+               mode = IRQn_MODE(intr_ctrl,i);
+               if ((mode == 0x1) || (mode == 0x2))
+                       irq_desc[i?MPC52xx_IRQ1+i-1:MPC52xx_IRQ0].status = 0;
+       }
 }
 
 int