aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-nomadik
diff options
context:
space:
mode:
authorRabin Vincent <rabin.vincent@stericsson.com>2010-03-02 22:50:27 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2010-03-19 14:29:31 -0400
commitaaedaa2b5c610ae97f863078075d8d3c6ef91575 (patch)
treed7b8635882c06dcc36afa332a6aad82f613180f6 /arch/arm/plat-nomadik
parentc0fcb8dba829421fe20652a376a2bedaf168238f (diff)
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 a9ee9889a833..4c3ea1a922ac 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 = {
211static void nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) 211static void nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
212{ 212{
213 struct nmk_gpio_chip *nmk_chip; 213 struct nmk_gpio_chip *nmk_chip;
214 struct irq_chip *host_chip; 214 struct irq_chip *host_chip = get_irq_chip(irq);
215 unsigned int gpio_irq; 215 unsigned int gpio_irq;
216 u32 pending; 216 u32 pending;
217 unsigned int first_irq; 217 unsigned int first_irq;
218 218
219 if (host_chip->mask_ack)
220 host_chip->mask_ack(irq);
221 else {
222 host_chip->mask(irq);
223 if (host_chip->ack)
224 host_chip->ack(irq);
225 }
226
219 nmk_chip = get_irq_data(irq); 227 nmk_chip = get_irq_data(irq);
220 first_irq = NOMADIK_GPIO_TO_IRQ(nmk_chip->chip.base); 228 first_irq = NOMADIK_GPIO_TO_IRQ(nmk_chip->chip.base);
221 while ( (pending = readl(nmk_chip->addr + NMK_GPIO_IS)) ) { 229 while ( (pending = readl(nmk_chip->addr + NMK_GPIO_IS)) ) {
222 gpio_irq = first_irq + __ffs(pending); 230 gpio_irq = first_irq + __ffs(pending);
223 generic_handle_irq(gpio_irq); 231 generic_handle_irq(gpio_irq);
224 } 232 }
225 if (0) {/* don't ack parent irq, as ack == disable */ 233
226 host_chip = get_irq_chip(irq); 234 host_chip->unmask(irq);
227 host_chip->ack(irq);
228 }
229} 235}
230 236
231static int nmk_gpio_init_irq(struct nmk_gpio_chip *nmk_chip) 237static int nmk_gpio_init_irq(struct nmk_gpio_chip *nmk_chip)