davinci: fixups for banked GPIO interrupt handling
[pandora-kernel.git] / arch / arm / mach-davinci / gpio.c
index 1aba41c..40327b5 100644 (file)
@@ -45,6 +45,7 @@ static struct gpio_controller __iomem * __init gpio2controller(unsigned gpio)
        return __gpio_to_controller(gpio);
 }
 
+static int __init davinci_gpio_irq_setup(void);
 
 /*--------------------------------------------------------------------------*/
 
@@ -157,6 +158,7 @@ static int __init davinci_gpio_setup(void)
                gpiochip_add(&chips[i].chip);
        }
 
+       davinci_gpio_irq_setup();
        return 0;
 }
 pure_initcall(davinci_gpio_setup);
@@ -187,10 +189,15 @@ static void gpio_irq_enable(unsigned irq)
 {
        struct gpio_controller *__iomem g = get_irq_chip_data(irq);
        u32 mask = __gpio_mask(irq_to_gpio(irq));
+       unsigned status = irq_desc[irq].status;
 
-       if (irq_desc[irq].status & IRQ_TYPE_EDGE_FALLING)
+       status &= IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING;
+       if (!status)
+               status = IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING;
+
+       if (status & IRQ_TYPE_EDGE_FALLING)
                __raw_writel(mask, &g->set_falling);
-       if (irq_desc[irq].status & IRQ_TYPE_EDGE_RISING)
+       if (status & IRQ_TYPE_EDGE_RISING)
                __raw_writel(mask, &g->set_rising);
 }
 
@@ -205,10 +212,13 @@ static int gpio_irq_type(unsigned irq, unsigned trigger)
        irq_desc[irq].status &= ~IRQ_TYPE_SENSE_MASK;
        irq_desc[irq].status |= trigger;
 
-       __raw_writel(mask, (trigger & IRQ_TYPE_EDGE_FALLING)
-                    ? &g->set_falling : &g->clr_falling);
-       __raw_writel(mask, (trigger & IRQ_TYPE_EDGE_RISING)
-                    ? &g->set_rising : &g->clr_rising);
+       /* don't enable the IRQ if it's currently disabled */
+       if (irq_desc[irq].depth == 0) {
+               __raw_writel(mask, (trigger & IRQ_TYPE_EDGE_FALLING)
+                            ? &g->set_falling : &g->clr_falling);
+               __raw_writel(mask, (trigger & IRQ_TYPE_EDGE_RISING)
+                            ? &g->set_rising : &g->clr_rising);
+       }
        return 0;
 }
 
@@ -230,6 +240,7 @@ gpio_irq_handler(unsigned irq, struct irq_desc *desc)
                mask <<= 16;
 
        /* temporarily mask (level sensitive) parent IRQ */
+       desc->chip->mask(irq);
        desc->chip->ack(irq);
        while (1) {
                u32             status;
@@ -325,4 +336,3 @@ static int __init davinci_gpio_irq_setup(void)
 
        return 0;
 }
-arch_initcall(davinci_gpio_irq_setup);