summaryrefslogtreecommitdiff
path: root/drivers/gpio
diff options
context:
space:
mode:
authorMarc Zyngier <maz@kernel.org>2021-10-26 20:58:11 +0300
committerLinus Walleij <linus.walleij@linaro.org>2021-10-27 01:16:00 +0300
commitcfe6807d82e97e81c3209dca9448f091e1448a57 (patch)
treedf4d6b96d951f7c7fe7e2891af335c25236378f5 /drivers/gpio
parent6880fa6c56601bb8ed59df6c30fd390cc5f6dd8f (diff)
downloadlinux-cfe6807d82e97e81c3209dca9448f091e1448a57.tar.xz
gpio: Allow per-parent interrupt data
The core gpiolib code is able to deal with multiple interrupt parents for a single gpio irqchip. It however only allows a single piece of data to be conveyed to all flow handlers (either the gpio_chip or some other, driver-specific data). This means that drivers have to go through some interesting dance to find the correct context, something that isn't great in interrupt context (see aebdc8abc9db86e2bd33070fc2f961012fff74b4 for a prime example). Instead, offer an optional way for a pinctrl/gpio driver to provide an array of pointers which gets used to provide the correct context to the flow handler. Signed-off-by: Marc Zyngier <maz@kernel.org> Signed-off-by: Joey Gouly <joey.gouly@arm.com> Reviewed-by: Linus Walleij <linus.walleij@linaro.org> Link: https://lore.kernel.org/r/20211026175815.52703-2-joey.gouly@arm.com Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/gpio')
-rw-r--r--drivers/gpio/gpiolib.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index d1b9b721218f..abfbf546d159 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -1534,9 +1534,14 @@ static int gpiochip_add_irqchip(struct gpio_chip *gc,
}
if (gc->irq.parent_handler) {
- void *data = gc->irq.parent_handler_data ?: gc;
-
for (i = 0; i < gc->irq.num_parents; i++) {
+ void *data;
+
+ if (gc->irq.per_parent_data)
+ data = gc->irq.parent_handler_data_array[i];
+ else
+ data = gc->irq.parent_handler_data ?: gc;
+
/*
* The parent IRQ chip is already using the chip_data
* for this IRQ chip, so our callbacks simply use the