summaryrefslogtreecommitdiff
path: root/drivers/gpio/gpiolib.c
diff options
context:
space:
mode:
authorLinus Walleij <linus.walleij@linaro.org>2014-09-26 16:19:52 +0400
committerLinus Walleij <linus.walleij@linaro.org>2014-09-26 16:39:08 +0400
commit3f97d5fcf99cb87f590ffe1d9422b2a26a8ef3ed (patch)
treefd68ce986e6042edebb64bf8ad51aa7f222503f7 /drivers/gpio/gpiolib.c
parent83141a771975f4e54402ab05e5cbbc3c56f45bdd (diff)
downloadlinux-3f97d5fcf99cb87f590ffe1d9422b2a26a8ef3ed.tar.xz
gpio: handle also nested irqchips in the chained handler set-up
To unify how we connect cascaded IRQ chips to parent IRQs, if NULL us passed as handler to the gpiochip_set_chained_irqchip() function, assume the chips is nested rather than chained, and we still get the parent set up correctly by way of this function call. Alter the drivers for tc3589x and stmpe to use this to set up their chained handlers as a demonstration of the usage. Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/gpio/gpiolib.c')
-rw-r--r--drivers/gpio/gpiolib.c34
1 files changed, 19 insertions, 15 deletions
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 9362b5b817af..6e00c82be142 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -385,13 +385,14 @@ static struct gpio_chip *find_chip_by_name(const char *name)
*/
/**
- * gpiochip_add_chained_irqchip() - adds a chained irqchip to a gpiochip
- * @gpiochip: the gpiochip to add the irqchip to
- * @irqchip: the irqchip to add to the gpiochip
+ * gpiochip_set_chained_irqchip() - sets a chained irqchip to a gpiochip
+ * @gpiochip: the gpiochip to set the irqchip chain to
+ * @irqchip: the irqchip to chain to the gpiochip
* @parent_irq: the irq number corresponding to the parent IRQ for this
* chained irqchip
* @parent_handler: the parent interrupt handler for the accumulated IRQ
- * coming out of the gpiochip
+ * coming out of the gpiochip. If the interrupt is nested rather than
+ * cascaded, pass NULL in this handler argument
*/
void gpiochip_set_chained_irqchip(struct gpio_chip *gpiochip,
struct irq_chip *irqchip,
@@ -400,23 +401,26 @@ void gpiochip_set_chained_irqchip(struct gpio_chip *gpiochip,
{
unsigned int offset;
- if (gpiochip->can_sleep) {
- chip_err(gpiochip, "you cannot have chained interrupts on a chip that may sleep\n");
- return;
- }
if (!gpiochip->irqdomain) {
chip_err(gpiochip, "called %s before setting up irqchip\n",
__func__);
return;
}
- irq_set_chained_handler(parent_irq, parent_handler);
-
- /*
- * The parent irqchip is already using the chip_data for this
- * irqchip, so our callbacks simply use the handler_data.
- */
- irq_set_handler_data(parent_irq, gpiochip);
+ if (parent_handler) {
+ if (gpiochip->can_sleep) {
+ chip_err(gpiochip,
+ "you cannot have chained interrupts on a "
+ "chip that may sleep\n");
+ return;
+ }
+ irq_set_chained_handler(parent_irq, parent_handler);
+ /*
+ * The parent irqchip is already using the chip_data for this
+ * irqchip, so our callbacks simply use the handler_data.
+ */
+ irq_set_handler_data(parent_irq, gpiochip);
+ }
/* Set the parent IRQ for all affected IRQs */
for (offset = 0; offset < gpiochip->ngpio; offset++)