Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
[cascardo/linux.git] / arch / mips / loongson32 / common / irq.c
index 455a770..635a4ab 100644 (file)
@@ -62,12 +62,58 @@ static void ls1x_irq_unmask(struct irq_data *d)
                        | (1 << bit), LS1X_INTC_INTIEN(n));
 }
 
+static int ls1x_irq_settype(struct irq_data *d, unsigned int type)
+{
+       unsigned int bit = (d->irq - LS1X_IRQ_BASE) & 0x1f;
+       unsigned int n = (d->irq - LS1X_IRQ_BASE) >> 5;
+
+       switch (type) {
+       case IRQ_TYPE_LEVEL_HIGH:
+               __raw_writel(__raw_readl(LS1X_INTC_INTPOL(n))
+                       | (1 << bit), LS1X_INTC_INTPOL(n));
+               __raw_writel(__raw_readl(LS1X_INTC_INTEDGE(n))
+                       & ~(1 << bit), LS1X_INTC_INTEDGE(n));
+               break;
+       case IRQ_TYPE_LEVEL_LOW:
+               __raw_writel(__raw_readl(LS1X_INTC_INTPOL(n))
+                       & ~(1 << bit), LS1X_INTC_INTPOL(n));
+               __raw_writel(__raw_readl(LS1X_INTC_INTEDGE(n))
+                       & ~(1 << bit), LS1X_INTC_INTEDGE(n));
+               break;
+       case IRQ_TYPE_EDGE_RISING:
+               __raw_writel(__raw_readl(LS1X_INTC_INTPOL(n))
+                       | (1 << bit), LS1X_INTC_INTPOL(n));
+               __raw_writel(__raw_readl(LS1X_INTC_INTEDGE(n))
+                       | (1 << bit), LS1X_INTC_INTEDGE(n));
+               break;
+       case IRQ_TYPE_EDGE_FALLING:
+               __raw_writel(__raw_readl(LS1X_INTC_INTPOL(n))
+                       & ~(1 << bit), LS1X_INTC_INTPOL(n));
+               __raw_writel(__raw_readl(LS1X_INTC_INTEDGE(n))
+                       | (1 << bit), LS1X_INTC_INTEDGE(n));
+               break;
+       case IRQ_TYPE_EDGE_BOTH:
+               __raw_writel(__raw_readl(LS1X_INTC_INTPOL(n))
+                       & ~(1 << bit), LS1X_INTC_INTPOL(n));
+               __raw_writel(__raw_readl(LS1X_INTC_INTEDGE(n))
+                       | (1 << bit), LS1X_INTC_INTEDGE(n));
+               break;
+       case IRQ_TYPE_NONE:
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
 static struct irq_chip ls1x_irq_chip = {
        .name           = "LS1X-INTC",
        .irq_ack        = ls1x_irq_ack,
        .irq_mask       = ls1x_irq_mask,
        .irq_mask_ack   = ls1x_irq_mask_ack,
        .irq_unmask     = ls1x_irq_unmask,
+       .irq_set_type   = ls1x_irq_settype,
 };
 
 static void ls1x_irq_dispatch(int n)
@@ -107,7 +153,7 @@ asmlinkage void plat_irq_dispatch(void)
 
 }
 
-struct irqaction cascade_irqaction = {
+static struct irqaction cascade_irqaction = {
        .handler = no_action,
        .name = "cascade",
        .flags = IRQF_NO_THREAD,
@@ -120,7 +166,7 @@ static void __init ls1x_irq_init(int base)
        /* Disable interrupts and clear pending,
         * setup all IRQs as high level triggered
         */
-       for (n = 0; n < 4; n++) {
+       for (n = 0; n < INTN; n++) {
                __raw_writel(0x0, LS1X_INTC_INTIEN(n));
                __raw_writel(0xffffffff, LS1X_INTC_INTCLR(n));
                __raw_writel(0xffffffff, LS1X_INTC_INTPOL(n));
@@ -129,7 +175,7 @@ static void __init ls1x_irq_init(int base)
        }
 
 
-       for (n = base; n < LS1X_IRQS; n++) {
+       for (n = base; n < NR_IRQS; n++) {
                irq_set_chip_and_handler(n, &ls1x_irq_chip,
                                         handle_level_irq);
        }
@@ -138,6 +184,9 @@ static void __init ls1x_irq_init(int base)
        setup_irq(INT1_IRQ, &cascade_irqaction);
        setup_irq(INT2_IRQ, &cascade_irqaction);
        setup_irq(INT3_IRQ, &cascade_irqaction);
+#if defined(CONFIG_LOONGSON1_LS1C)
+       setup_irq(INT4_IRQ, &cascade_irqaction);
+#endif
 }
 
 void __init arch_init_irq(void)