]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
[PATCH] ARM: OMAP: GPIO-patch for 24xx
authorJarkko Nikula <>
Tue, 15 Nov 2005 20:24:31 +0000 (12:24 -0800)
committerTony Lindgren <tony@atomide.com>
Tue, 15 Nov 2005 20:24:31 +0000 (12:24 -0800)
GPIO-patch for 24xx

arch/arm/plat-omap/gpio.c

index 76f721d8513745280cfb7822331dea015cf2f327..beecfc15cad72db4765f39bb2106d5f09c37e4ad 100644 (file)
@@ -491,7 +491,9 @@ static int gpio_irq_type(unsigned irq, unsigned type)
        if (check_gpio(gpio) < 0)
                return -EINVAL;
 
-       if (type & (__IRQT_LOWLVL|__IRQT_HIGHLVL|IRQT_PROBE))
+       if (type & IRQT_PROBE)
+               return -EINVAL;
+       if (!cpu_is_omap24xx() && (type & (__IRQT_LOWLVL|__IRQT_HIGHLVL)))
                return -EINVAL;
 
        bank = get_gpio_bank(gpio);
@@ -757,10 +759,19 @@ static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc,
 #endif
 
        while(1) {
-               isr = __raw_readl(isr_reg);
-               _enable_gpio_irqbank(bank, isr, 0);
-               _clear_gpio_irqbank(bank, isr);
-               _enable_gpio_irqbank(bank, isr, 1);
+               u32 isr_saved, level_mask = 0;
+
+               isr_saved = isr = __raw_readl(isr_reg);
+               if (cpu_is_omap24xx())
+                       level_mask = __raw_readl(bank->base +
+                               OMAP24XX_GPIO_LEVELDETECT0) |
+                               __raw_readl(bank->base +
+                               OMAP24XX_GPIO_LEVELDETECT1);
+
+               /* clear edge sensitive interrupts before handler(s) */
+               _enable_gpio_irqbank(bank, isr_saved & ~level_mask, 0);
+               _clear_gpio_irqbank(bank, isr_saved & ~level_mask);
+               _enable_gpio_irqbank(bank, isr_saved & ~level_mask, 1);
                desc->chip->unmask(irq);
 
                if (!isr)
@@ -774,6 +785,12 @@ static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc,
                        d = irq_desc + gpio_irq;
                        desc_handle_irq(gpio_irq, d, regs);
                }
+               /* clear level sensitive interrupts after handler(s) */
+               if (cpu_is_omap24xx()) {
+                       _enable_gpio_irqbank(bank, isr_saved & level_mask, 0);
+                       _clear_gpio_irqbank(bank, isr_saved & level_mask);
+                       _enable_gpio_irqbank(bank, isr_saved & level_mask, 1);
+               }
        }
 }