Skip to content

Commit cfe6807

Browse files
Marc ZyngierLinus Walleij
authored andcommitted
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 aebdc8a 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>
1 parent 6880fa6 commit cfe6807

2 files changed

Lines changed: 24 additions & 4 deletions

File tree

drivers/gpio/gpiolib.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1534,9 +1534,14 @@ static int gpiochip_add_irqchip(struct gpio_chip *gc,
15341534
}
15351535

15361536
if (gc->irq.parent_handler) {
1537-
void *data = gc->irq.parent_handler_data ?: gc;
1538-
15391537
for (i = 0; i < gc->irq.num_parents; i++) {
1538+
void *data;
1539+
1540+
if (gc->irq.per_parent_data)
1541+
data = gc->irq.parent_handler_data_array[i];
1542+
else
1543+
data = gc->irq.parent_handler_data ?: gc;
1544+
15401545
/*
15411546
* The parent IRQ chip is already using the chip_data
15421547
* for this IRQ chip, so our callbacks simply use the

include/linux/gpio/driver.h

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -168,11 +168,18 @@ struct gpio_irq_chip {
168168

169169
/**
170170
* @parent_handler_data:
171+
* @parent_handler_data_array:
171172
*
172173
* Data associated, and passed to, the handler for the parent
173-
* interrupt.
174+
* interrupt. Can either be a single pointer if @per_parent_data
175+
* is false, or an array of @num_parents pointers otherwise. If
176+
* @per_parent_data is true, @parent_handler_data_array cannot be
177+
* NULL.
174178
*/
175-
void *parent_handler_data;
179+
union {
180+
void *parent_handler_data;
181+
void **parent_handler_data_array;
182+
};
176183

177184
/**
178185
* @num_parents:
@@ -203,6 +210,14 @@ struct gpio_irq_chip {
203210
*/
204211
bool threaded;
205212

213+
/**
214+
* @per_parent_data:
215+
*
216+
* True if parent_handler_data_array describes a @num_parents
217+
* sized array to be used as parent data.
218+
*/
219+
bool per_parent_data;
220+
206221
/**
207222
* @init_hw: optional routine to initialize hardware before
208223
* an IRQ chip will be added. This is quite useful when

0 commit comments

Comments
 (0)