fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / arch / mips / philips / pnx8550 / common / int.c
index 5461449..2c36c10 100644 (file)
@@ -23,7 +23,7 @@
  *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  *
  */
-#include <linux/config.h>
+#include <linux/compiler.h>
 #include <linux/init.h>
 #include <linux/irq.h>
 #include <linux/sched.h>
 #include <int.h>
 #include <uart.h>
 
-extern asmlinkage void cp0_irqdispatch(void);
-
-static DEFINE_SPINLOCK(irq_lock);
-
 /* default prio for interrupts */
 /* first one is a no-no so therefore always prio 0 (disabled) */
 static char gic_prio[PNX8550_INT_GIC_TOTINT] = {
@@ -55,7 +51,7 @@ static char gic_prio[PNX8550_INT_GIC_TOTINT] = {
        1                       //  70
 };
 
-void hw0_irqdispatch(int irq, struct pt_regs *regs)
+static void hw0_irqdispatch(int irq)
 {
        /* find out which interrupt */
        irq = PNX8550_GIC_VECTOR_0 >> 3;
@@ -64,28 +60,39 @@ void hw0_irqdispatch(int irq, struct pt_regs *regs)
                printk("hw0_irqdispatch: irq 0, spurious interrupt?\n");
                return;
        }
-       do_IRQ(PNX8550_INT_GIC_MIN + irq, regs);
+       do_IRQ(PNX8550_INT_GIC_MIN + irq);
 }
 
 
-void timer_irqdispatch(int irq, struct pt_regs *regs)
+static void timer_irqdispatch(int irq)
 {
        irq = (0x01c0 & read_c0_config7()) >> 6;
 
-       if (irq == 0) {
+       if (unlikely(irq == 0)) {
                printk("timer_irqdispatch: irq 0, spurious interrupt?\n");
                return;
        }
 
-       if (irq & 0x1) {
-               do_IRQ(PNX8550_INT_TIMER1, regs);
-       }
-       if (irq & 0x2) {
-               do_IRQ(PNX8550_INT_TIMER2, regs);
-       }
-       if (irq & 0x4) {
-               do_IRQ(PNX8550_INT_TIMER3, regs);
+       if (irq & 0x1)
+               do_IRQ(PNX8550_INT_TIMER1);
+       if (irq & 0x2)
+               do_IRQ(PNX8550_INT_TIMER2);
+       if (irq & 0x4)
+               do_IRQ(PNX8550_INT_TIMER3);
+}
+
+asmlinkage void plat_irq_dispatch(void)
+{
+       unsigned int pending = read_c0_status() & read_c0_cause();
+
+       if (pending & STATUSF_IP2)
+               hw0_irqdispatch(2);
+       else if (pending & STATUSF_IP7) {
+               if (read_c0_config7() & 0x01c0)
+                       timer_irqdispatch(7);
        }
+
+       spurious_interrupt();
 }
 
 static inline void modify_cp0_intmask(unsigned clr_mask, unsigned set_mask)
@@ -140,38 +147,6 @@ static inline void unmask_irq(unsigned int irq_nr)
        }
 }
 
-#define pnx8550_disable pnx8550_ack
-static void pnx8550_ack(unsigned int irq)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&irq_lock, flags);
-       mask_irq(irq);
-       spin_unlock_irqrestore(&irq_lock, flags);
-}
-
-#define pnx8550_enable pnx8550_unmask
-static void pnx8550_unmask(unsigned int irq)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&irq_lock, flags);
-       unmask_irq(irq);
-       spin_unlock_irqrestore(&irq_lock, flags);
-}
-
-static unsigned int startup_irq(unsigned int irq_nr)
-{
-       pnx8550_unmask(irq_nr);
-       return 0;
-}
-
-static void shutdown_irq(unsigned int irq_nr)
-{
-       pnx8550_ack(irq_nr);
-       return;
-}
-
 int pnx8550_set_gic_priority(int irq, int priority)
 {
        int gic_irq = irq-PNX8550_INT_GIC_MIN;
@@ -183,38 +158,23 @@ int pnx8550_set_gic_priority(int irq, int priority)
        return prev_priority;
 }
 
-static inline void mask_and_ack_level_irq(unsigned int irq)
-{
-       pnx8550_disable(irq);
-       return;
-}
-
-static void end_irq(unsigned int irq)
-{
-       if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) {
-               pnx8550_enable(irq);
-       }
-}
-
-static struct hw_interrupt_type level_irq_type = {
+static struct irq_chip level_irq_type = {
        .typename =     "PNX Level IRQ",
-       .startup =      startup_irq,
-       .shutdown =     shutdown_irq,
-       .enable =       pnx8550_enable,
-       .disable =      pnx8550_disable,
-       .ack =          mask_and_ack_level_irq,
-       .end =          end_irq,
+       .ack =          mask_irq,
+       .mask =         mask_irq,
+       .mask_ack =     mask_irq,
+       .unmask =       unmask_irq,
 };
 
 static struct irqaction gic_action = {
        .handler =      no_action,
-       .flags =        SA_INTERRUPT,
+       .flags =        IRQF_DISABLED,
        .name =         "GIC",
 };
 
 static struct irqaction timer_action = {
        .handler =      no_action,
-       .flags =        SA_INTERRUPT,
+       .flags =        IRQF_DISABLED,
        .name =         "Timer",
 };
 
@@ -223,12 +183,9 @@ void __init arch_init_irq(void)
        int i;
        int configPR;
 
-       /* init of cp0 interrupts */
-       set_except_vector(0, cp0_irqdispatch);
-
        for (i = 0; i < PNX8550_INT_CP0_TOTINT; i++) {
-               irq_desc[i].handler = &level_irq_type;
-               pnx8550_ack(i); /* mask the irq just in case  */
+               set_irq_chip_and_handler(i, &level_irq_type, handle_level_irq);
+               mask_irq(i);    /* mask the irq just in case  */
        }
 
        /* init of GIC/IPC interrupts */
@@ -251,7 +208,7 @@ void __init arch_init_irq(void)
                if (gic_int_line == (PNX8550_INT_GPIO0 - PNX8550_INT_GIC_MIN)) {
                        /* PCI INT through gpio 8, which is setup in
                         * pnx8550_setup.c and routed to GPIO
-                        * Interrupt Level 0 (GPIO Connection 58).
+                        * Interrupt Level 0 (GPIO Connection 58).
                         * Set it active low. */
 
                        PNX8550_GIC_REQ(gic_int_line) = 0x1E020000;
@@ -264,7 +221,7 @@ void __init arch_init_irq(void)
                /* mask/priority is still 0 so we will not get any
                 * interrupts until it is unmasked */
 
-               irq_desc[i].handler = &level_irq_type;
+               set_irq_chip_and_handler(i, &level_irq_type, handle_level_irq);
        }
 
        /* Priority level 0 */
@@ -273,20 +230,21 @@ void __init arch_init_irq(void)
        /* Set int vector table address */
        PNX8550_GIC_VECTOR_0 = PNX8550_GIC_VECTOR_1 = 0;
 
-       irq_desc[MIPS_CPU_GIC_IRQ].handler = &level_irq_type;
+       set_irq_chip_and_handler(MIPS_CPU_GIC_IRQ, &level_irq_type,
+                                handle_level_irq);
        setup_irq(MIPS_CPU_GIC_IRQ, &gic_action);
 
        /* init of Timer interrupts */
-       for (i = PNX8550_INT_TIMER_MIN; i <= PNX8550_INT_TIMER_MAX; i++) {
-               irq_desc[i].handler = &level_irq_type;
-       }
+       for (i = PNX8550_INT_TIMER_MIN; i <= PNX8550_INT_TIMER_MAX; i++)
+               set_irq_chip_and_handler(i, &level_irq_type, handle_level_irq);
 
        /* Stop Timer 1-3 */
        configPR = read_c0_config7();
        configPR |= 0x00000038;
        write_c0_config7(configPR);
 
-       irq_desc[MIPS_CPU_TIMER_IRQ].handler = &level_irq_type;
+       set_irq_chip_and_handler(MIPS_CPU_TIMER_IRQ, &level_irq_type,
+                                handle_level_irq);
        setup_irq(MIPS_CPU_TIMER_IRQ, &timer_action);
 }