Commit 576efd11 authored by Jarkko Nikula's avatar Jarkko Nikula Committed by Tony Lindgren

[PATCH] ARM: OMAP: Improved GPIO level interrupt handling for 24xx

Improved GPIO level interrupt handling for 24xx
parent 69898301
...@@ -757,22 +757,28 @@ static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc, ...@@ -757,22 +757,28 @@ static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc,
if (bank->method == METHOD_GPIO_24XX) if (bank->method == METHOD_GPIO_24XX)
isr_reg = bank->base + OMAP24XX_GPIO_IRQSTATUS1; isr_reg = bank->base + OMAP24XX_GPIO_IRQSTATUS1;
#endif #endif
while(1) { while(1) {
u32 isr_saved, level_mask = 0; u32 isr_saved, level_mask = 0;
isr_saved = isr = __raw_readl(isr_reg); isr_saved = isr = __raw_readl(isr_reg);
if (cpu_is_omap24xx()) if (cpu_is_omap24xx())
level_mask = __raw_readl(bank->base + level_mask =
OMAP24XX_GPIO_LEVELDETECT0) | __raw_readl(bank->base +
OMAP24XX_GPIO_LEVELDETECT0) |
__raw_readl(bank->base + __raw_readl(bank->base +
OMAP24XX_GPIO_LEVELDETECT1); OMAP24XX_GPIO_LEVELDETECT1);
/* clear edge sensitive interrupts before handler(s) */ /* clear edge sensitive interrupts before handler(s) are
called so that we don't miss any interrupt occurred while
executing them */
_enable_gpio_irqbank(bank, isr_saved & ~level_mask, 0); _enable_gpio_irqbank(bank, isr_saved & ~level_mask, 0);
_clear_gpio_irqbank(bank, isr_saved & ~level_mask); _clear_gpio_irqbank(bank, isr_saved & ~level_mask);
_enable_gpio_irqbank(bank, isr_saved & ~level_mask, 1); _enable_gpio_irqbank(bank, isr_saved & ~level_mask, 1);
desc->chip->unmask(irq);
/* if there is only edge sensitive GPIO pin interrupts
configured, we could unmask GPIO bank interrupt immediately */
if (!level_mask)
desc->chip->unmask(irq);
if (!isr) if (!isr)
break; break;
...@@ -785,12 +791,20 @@ static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc, ...@@ -785,12 +791,20 @@ static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc,
d = irq_desc + gpio_irq; d = irq_desc + gpio_irq;
desc_handle_irq(gpio_irq, d, regs); desc_handle_irq(gpio_irq, d, regs);
} }
/* clear level sensitive interrupts after handler(s) */
if (cpu_is_omap24xx()) { if (cpu_is_omap24xx()) {
/* clear level sensitive interrupts after handler(s) */
_enable_gpio_irqbank(bank, isr_saved & level_mask, 0); _enable_gpio_irqbank(bank, isr_saved & level_mask, 0);
_clear_gpio_irqbank(bank, isr_saved & level_mask); _clear_gpio_irqbank(bank, isr_saved & level_mask);
_enable_gpio_irqbank(bank, isr_saved & level_mask, 1); _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);
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment