Commit 317fdd19 authored by Marc Zyngier's avatar Marc Zyngier Committed by sanglipeng
Browse files

gpio: Allow per-parent interrupt data

stable inclusion
from stable-v5.10.186
commit 304802e5b038e9e33e1b7fe5f933864e7a8e0ec1
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I8J4KH

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=304802e5b038e9e33e1b7fe5f933864e7a8e0ec1



--------------------------------

[ Upstream commit cfe6807d ]

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 aebdc8ab 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: default avatarMarc Zyngier <maz@kernel.org>
Signed-off-by: default avatarJoey Gouly <joey.gouly@arm.com>
Reviewed-by: default avatarLinus Walleij <linus.walleij@linaro.org>
Link: https://lore.kernel.org/r/20211026175815.52703-2-joey.gouly@arm.com


Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
Stable-dep-of: 8c00914e ("gpiolib: Fix GPIO chip IRQ initialization restriction")
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
Signed-off-by: default avatarsanglipeng <sanglipeng1@jd.com>
parent cdba4af8
Loading
Loading
Loading
Loading
+7 −2
Original line number Diff line number Diff line
@@ -1595,9 +1595,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
+17 −2
Original line number Diff line number Diff line
@@ -168,11 +168,18 @@ struct gpio_irq_chip {

	/**
	 * @parent_handler_data:
	 * @parent_handler_data_array:
	 *
	 * Data associated, and passed to, the handler for the parent
	 * interrupt.
	 * interrupt. Can either be a single pointer if @per_parent_data
	 * is false, or an array of @num_parents pointers otherwise.  If
	 * @per_parent_data is true, @parent_handler_data_array cannot be
	 * NULL.
	 */
	union {
		void *parent_handler_data;
		void **parent_handler_data_array;
	};

	/**
	 * @num_parents:
@@ -203,6 +210,14 @@ struct gpio_irq_chip {
	 */
	bool threaded;

	/**
	 * @per_parent_data:
	 *
	 * True if parent_handler_data_array describes a @num_parents
	 * sized array to be used as parent data.
	 */
	bool per_parent_data;

	/**
	 * @init_hw: optional routine to initialize hardware before
	 * an IRQ chip will be added. This is quite useful when