Commit aaedaa2b authored by Rabin Vincent's avatar Rabin Vincent Committed by Russell King

ARM: 5971/1: nomadik-gpio: mask/ack/unmask the parent irq

Since we register as a chained handler, we need to take care of acking
the parent irq.  Current code had the acking disabled because just
acking the interrupt disables it on some interrupt controllers (like the
VIC used on Nomadik).  However, not acking at all is incorrect because
interrupt controllers like the GIC need an EOI indication, which is done
in the ack routine.

Solve this by maskacking and unmasking it appropriately, similar to how
handle_level_irq operates.
Acked-by: default avatarAlessandro Rubini <rubini@unipv.it>
Acked-by: default avatarLinus Walleij <linus.walleij@stericsson.com>
Signed-off-by: default avatarRabin Vincent <rabin.vincent@stericsson.com>
Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent c0fcb8db
...@@ -211,21 +211,27 @@ static struct irq_chip nmk_gpio_irq_chip = { ...@@ -211,21 +211,27 @@ static struct irq_chip nmk_gpio_irq_chip = {
static void nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) static void nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
{ {
struct nmk_gpio_chip *nmk_chip; struct nmk_gpio_chip *nmk_chip;
struct irq_chip *host_chip; struct irq_chip *host_chip = get_irq_chip(irq);
unsigned int gpio_irq; unsigned int gpio_irq;
u32 pending; u32 pending;
unsigned int first_irq; unsigned int first_irq;
if (host_chip->mask_ack)
host_chip->mask_ack(irq);
else {
host_chip->mask(irq);
if (host_chip->ack)
host_chip->ack(irq);
}
nmk_chip = get_irq_data(irq); nmk_chip = get_irq_data(irq);
first_irq = NOMADIK_GPIO_TO_IRQ(nmk_chip->chip.base); first_irq = NOMADIK_GPIO_TO_IRQ(nmk_chip->chip.base);
while ( (pending = readl(nmk_chip->addr + NMK_GPIO_IS)) ) { while ( (pending = readl(nmk_chip->addr + NMK_GPIO_IS)) ) {
gpio_irq = first_irq + __ffs(pending); gpio_irq = first_irq + __ffs(pending);
generic_handle_irq(gpio_irq); generic_handle_irq(gpio_irq);
} }
if (0) {/* don't ack parent irq, as ack == disable */
host_chip = get_irq_chip(irq); host_chip->unmask(irq);
host_chip->ack(irq);
}
} }
static int nmk_gpio_init_irq(struct nmk_gpio_chip *nmk_chip) static int nmk_gpio_init_irq(struct nmk_gpio_chip *nmk_chip)
......
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