aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-nomadik
diff options
context:
space:
mode:
authorRabin Vincent <rabin.vincent@stericsson.com>2010-03-03 04:50:27 +0100
committerRussell King <rmk+kernel@arm.linux.org.uk>2010-03-19 18:29:31 +0000
commitaaedaa2b5c610ae97f863078075d8d3c6ef91575 (patch)
treed7b8635882c06dcc36afa332a6aad82f613180f6 /arch/arm/plat-nomadik
parentc0fcb8dba829421fe20652a376a2bedaf168238f (diff)
downloadkernel_samsung_smdk4412-aaedaa2b5c610ae97f863078075d8d3c6ef91575.zip
kernel_samsung_smdk4412-aaedaa2b5c610ae97f863078075d8d3c6ef91575.tar.gz
kernel_samsung_smdk4412-aaedaa2b5c610ae97f863078075d8d3c6ef91575.tar.bz2
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: Alessandro Rubini <rubini@unipv.it> Acked-by: Linus Walleij <linus.walleij@stericsson.com> Signed-off-by: Rabin Vincent <rabin.vincent@stericsson.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/plat-nomadik')
-rw-r--r--arch/arm/plat-nomadik/gpio.c16
1 files changed, 11 insertions, 5 deletions
diff --git a/arch/arm/plat-nomadik/gpio.c b/arch/arm/plat-nomadik/gpio.c
index a9ee988..4c3ea1a 100644
--- a/arch/arm/plat-nomadik/gpio.c
+++ b/arch/arm/plat-nomadik/gpio.c
@@ -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)
{
struct nmk_gpio_chip *nmk_chip;
- struct irq_chip *host_chip;
+ struct irq_chip *host_chip = get_irq_chip(irq);
unsigned int gpio_irq;
u32 pending;
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);
first_irq = NOMADIK_GPIO_TO_IRQ(nmk_chip->chip.base);
while ( (pending = readl(nmk_chip->addr + NMK_GPIO_IS)) ) {
gpio_irq = first_irq + __ffs(pending);
generic_handle_irq(gpio_irq);
}
- if (0) {/* don't ack parent irq, as ack == disable */
- host_chip = get_irq_chip(irq);
- host_chip->ack(irq);
- }
+
+ host_chip->unmask(irq);
}
static int nmk_gpio_init_irq(struct nmk_gpio_chip *nmk_chip)