X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Farm%2Fplat-omap%2Fgpio.c;h=d3c8ea7eecfd216846d5b2f94161d721e17b2d20;hb=9464c7cf61b9433057924c36e6e02f303a00e768;hp=cd7f973fb286618e23c1370dd56b532e9b5cbc15;hpb=41689045f6a3cbe0550e1d34e9cc20d2e8c432ba;p=linux-2.6.git diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c index cd7f973fb..d3c8ea7ee 100644 --- a/arch/arm/plat-omap/gpio.c +++ b/arch/arm/plat-omap/gpio.c @@ -11,6 +11,7 @@ * published by the Free Software Foundation. */ +#include #include #include #include @@ -536,49 +537,6 @@ static inline void _clear_gpio_irqstatus(struct gpio_bank *bank, int gpio) _clear_gpio_irqbank(bank, 1 << get_gpio_index(gpio)); } -static u32 _get_gpio_irqbank_mask(struct gpio_bank *bank) -{ - void __iomem *reg = bank->base; - int inv = 0; - u32 l; - u32 mask; - - switch (bank->method) { - case METHOD_MPUIO: - reg += OMAP_MPUIO_GPIO_MASKIT; - mask = 0xffff; - inv = 1; - break; - case METHOD_GPIO_1510: - reg += OMAP1510_GPIO_INT_MASK; - mask = 0xffff; - inv = 1; - break; - case METHOD_GPIO_1610: - reg += OMAP1610_GPIO_IRQENABLE1; - mask = 0xffff; - break; - case METHOD_GPIO_730: - reg += OMAP730_GPIO_INT_MASK; - mask = 0xffffffff; - inv = 1; - break; - case METHOD_GPIO_24XX: - reg += OMAP24XX_GPIO_IRQENABLE1; - mask = 0xffffffff; - break; - default: - BUG(); - return 0; - } - - l = __raw_readl(reg); - if (inv) - l = ~l; - l &= mask; - return l; -} - static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enable) { void __iomem *reg = bank->base; @@ -778,12 +736,10 @@ static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc, u32 isr; unsigned int gpio_irq; struct gpio_bank *bank; - u32 retrigger = 0; - int unmasked = 0; desc->chip->ack(irq); - bank = get_irq_data(irq); + bank = (struct gpio_bank *) desc->data; if (bank->method == METHOD_MPUIO) isr_reg = bank->base + OMAP_MPUIO_GPIO_INT; #ifdef CONFIG_ARCH_OMAP15XX @@ -804,22 +760,18 @@ static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc, #endif while(1) { u32 isr_saved, level_mask = 0; - u32 enabled; - enabled = _get_gpio_irqbank_mask(bank); - isr_saved = isr = __raw_readl(isr_reg) & enabled; + isr_saved = isr = __raw_readl(isr_reg); if (cpu_is_omap15xx() && (bank->method == METHOD_MPUIO)) isr &= 0x0000ffff; - if (cpu_is_omap24xx()) { + if (cpu_is_omap24xx()) level_mask = __raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT0) | __raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT1); - level_mask &= enabled; - } /* clear edge sensitive interrupts before handler(s) are called so that we don't miss any interrupt occurred while @@ -830,55 +782,19 @@ static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc, /* if there is only edge sensitive GPIO pin interrupts configured, we could unmask GPIO bank interrupt immediately */ - if (!level_mask && !unmasked) { - unmasked = 1; + if (!level_mask) desc->chip->unmask(irq); - } - isr |= retrigger; - retrigger = 0; if (!isr) break; gpio_irq = bank->virtual_irq_start; for (; isr != 0; isr >>= 1, gpio_irq++) { struct irqdesc *d; - int irq_mask; if (!(isr & 1)) continue; d = irq_desc + gpio_irq; - /* Don't run the handler if it's already running - * or was disabled lazely. - */ - if (unlikely((d->depth || - (d->status & IRQ_INPROGRESS)))) { - irq_mask = 1 << - (gpio_irq - bank->virtual_irq_start); - /* The unmasking will be done by - * enable_irq in case it is disabled or - * after returning from the handler if - * it's already running. - */ - _enable_gpio_irqbank(bank, irq_mask, 0); - if (!d->depth) { - /* Level triggered interrupts - * won't ever be reentered - */ - BUG_ON(level_mask & irq_mask); - d->status |= IRQ_PENDING; - } - continue; - } - desc_handle_irq(gpio_irq, d, regs); - - if (unlikely((d->status & IRQ_PENDING) && !d->depth)) { - irq_mask = 1 << - (gpio_irq - bank->virtual_irq_start); - d->status &= ~IRQ_PENDING; - _enable_gpio_irqbank(bank, irq_mask, 1); - retrigger |= irq_mask; - } } if (cpu_is_omap24xx()) { @@ -888,14 +804,13 @@ static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc, _enable_gpio_irqbank(bank, isr_saved & level_mask, 1); } + /* if bank has any level sensitive GPIO pin interrupt + configured, we must unmask the bank interrupt only after + handler(s) are executed in order to avoid spurious bank + interrupt */ + if (level_mask) + desc->chip->unmask(irq); } - /* if bank has any level sensitive GPIO pin interrupt - configured, we must unmask the bank interrupt only after - handler(s) are executed in order to avoid spurious bank - interrupt */ - if (!unmasked) - desc->chip->unmask(irq); - } static void gpio_ack_irq(unsigned int irq) @@ -944,8 +859,7 @@ static void mpuio_unmask_irq(unsigned int irq) _set_gpio_irqenable(bank, gpio, 1); } -static struct irq_chip gpio_irq_chip = { - .name = "GPIO", +static struct irqchip gpio_irq_chip = { .ack = gpio_ack_irq, .mask = gpio_mask_irq, .unmask = gpio_unmask_irq, @@ -953,11 +867,10 @@ static struct irq_chip gpio_irq_chip = { .set_wake = gpio_wake_enable, }; -static struct irq_chip mpuio_irq_chip = { - .name = "MPUIO", +static struct irqchip mpuio_irq_chip = { .ack = mpuio_ack_irq, .mask = mpuio_mask_irq, - .unmask = mpuio_unmask_irq + .unmask = mpuio_unmask_irq }; static int initialized;