aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Walleij <linus.walleij@linaro.org>2014-09-26 07:50:12 -0400
committerLinus Walleij <linus.walleij@linaro.org>2014-09-26 08:35:54 -0400
commit83141a771975f4e54402ab05e5cbbc3c56f45bdd (patch)
tree219158fd8726c5c50605508962554281509120d6 /drivers
parente3893386b90500d7f26fec3170bf96f67d3e557e (diff)
gpio: set parent irq on chained handlers
If the IRQ from the parent is nested the IRQ may need to be resent under certain conditions. Currently the chained IRQ handler in gpiolib does not handle connecting nested IRQs but it is conceptually correct to indicate the actual parent IRQ. Reported-by: Grygorii Strashko <grygorii.strashko@ti.com> Reported-by: Lothar Waßmann <LW@karo-electronics.de> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpio/gpiolib.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 550e575c6ffb..9362b5b817af 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -398,17 +398,30 @@ void gpiochip_set_chained_irqchip(struct gpio_chip *gpiochip,
398 int parent_irq, 398 int parent_irq,
399 irq_flow_handler_t parent_handler) 399 irq_flow_handler_t parent_handler)
400{ 400{
401 unsigned int offset;
402
401 if (gpiochip->can_sleep) { 403 if (gpiochip->can_sleep) {
402 chip_err(gpiochip, "you cannot have chained interrupts on a chip that may sleep\n"); 404 chip_err(gpiochip, "you cannot have chained interrupts on a chip that may sleep\n");
403 return; 405 return;
404 } 406 }
407 if (!gpiochip->irqdomain) {
408 chip_err(gpiochip, "called %s before setting up irqchip\n",
409 __func__);
410 return;
411 }
405 412
406 irq_set_chained_handler(parent_irq, parent_handler); 413 irq_set_chained_handler(parent_irq, parent_handler);
414
407 /* 415 /*
408 * The parent irqchip is already using the chip_data for this 416 * The parent irqchip is already using the chip_data for this
409 * irqchip, so our callbacks simply use the handler_data. 417 * irqchip, so our callbacks simply use the handler_data.
410 */ 418 */
411 irq_set_handler_data(parent_irq, gpiochip); 419 irq_set_handler_data(parent_irq, gpiochip);
420
421 /* Set the parent IRQ for all affected IRQs */
422 for (offset = 0; offset < gpiochip->ngpio; offset++)
423 irq_set_parent(irq_find_mapping(gpiochip->irqdomain, offset),
424 parent_irq);
412} 425}
413EXPORT_SYMBOL_GPL(gpiochip_set_chained_irqchip); 426EXPORT_SYMBOL_GPL(gpiochip_set_chained_irqchip);
414 427