diff mbox

gpio: document gpio irqchips a bit more, describe helpers

Message ID 1397047047-20870-1-git-send-email-linus.walleij@linaro.org
State Accepted
Commit 90887db8837bb2ea57c3541d56a002e9654082b3
Headers show

Commit Message

Linus Walleij April 9, 2014, 12:37 p.m. UTC
This adds some documentation about the GPIO irqchips, what types
exist etc.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
 Documentation/gpio/driver.txt | 59 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 59 insertions(+)


Alexandre Courbot April 10, 2014, 7:23 a.m. UTC | #1
On Wed, Apr 9, 2014 at 9:37 PM, Linus Walleij <linus.walleij@linaro.org> wrote:
> This adds some documentation about the GPIO irqchips, what types
> exist etc.
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>

Great, that sheds some light to your recent IRQ work (which I still
have to understand in more detail).

Acked-by: Alexandre Courbot <acourbot@nvidia.com>
To unsubscribe from this list: send the line "unsubscribe linux-gpio" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox


diff --git a/Documentation/gpio/driver.txt b/Documentation/gpio/driver.txt
index f73cc7b5dc85..fa9a0a8b3734 100644
--- a/Documentation/gpio/driver.txt
+++ b/Documentation/gpio/driver.txt
@@ -73,6 +73,65 @@  The IRQ portions of the GPIO block are implemented using an irqchip, using
 the header <linux/irq.h>. So basically such a driver is utilizing two sub-
 systems simultaneously: gpio and irq.
+GPIO irqchips usually fall in one of two categories:
+* CHAINED GPIO irqchips: these are usually the type that is embedded on
+  an SoC. This means that there is a fast IRQ handler for the GPIOs that
+  gets called in a chain from the parent IRQ handler, most typically the
+  system interrupt controller. This means the GPIO irqchip is registered
+  using irq_set_chained_handler() or the corresponding
+  gpiochip_set_chained_irqchip() helper function, and the GPIO irqchip
+  handler will be called immediately from the parent irqchip, while
+  holding the IRQs disabled. The GPIO irqchip will then end up calling
+  something like this sequence in its interrupt handler:
+  static irqreturn_t tc3589x_gpio_irq(int irq, void *data)
+      chained_irq_enter(...);
+      generic_handle_irq(...);
+      chained_irq_exit(...);
+  Chained GPIO irqchips typically can NOT set the .can_sleep flag on
+  struct gpio_chip, as everything happens directly in the callbacks.
+* NESTED THREADED GPIO irqchips: these are off-chip GPIO expanders and any
+  other GPIO irqchip residing on the other side of a sleeping bus. Of course
+  such drivers that need slow bus traffic to read out IRQ status and similar,
+  traffic which may in turn incur other IRQs to happen, cannot be handled
+  in a quick IRQ handler with IRQs disabled. Instead they need to spawn a
+  thread and then mask the parent IRQ line until the interrupt is handled
+  by the driver. The hallmark of this driver is to call something like
+  this in its interrupt handler:
+  static irqreturn_t tc3589x_gpio_irq(int irq, void *data)
+      ...
+      handle_nested_irq(irq);
+  The hallmark of threaded GPIO irqchips is that they set the .can_sleep
+  flag on struct gpio_chip to true, indicating that this chip may sleep
+  when accessing the GPIOs.
+To help out in handling the set-up and management of GPIO irqchips and the
+associated irqdomain and resource allocation callbacks, the gpiolib has
+some helpers that can be enabled by selecting the GPIOLIB_IRQCHIP Kconfig
+* gpiochip_irqchip_add(): adds an irqchip to a gpiochip. It will pass
+  the struct gpio_chip* for the chip to all IRQ callbacks, so the callbacks
+  need to embed the gpio_chip in its state container and obtain a pointer
+  to the container using container_of().
+  (See Documentation/driver-model/design-patterns.txt)
+* gpiochip_set_chained_irqchip(): sets up a chained irq handler for a
+  gpio_chip from a parent IRQ and passes the struct gpio_chip* as handler
+  data. (Notice handler data, since the irqchip data is likely used by the
+  parent irqchip!) This is for the chained type of chip.
+To use the helpers please keep the following in mind:
+- Make sure to assign all relevant members of the struct gpio_chip so that
+  the irqchip can initialize. E.g. .dev and .can_sleep shall be set up
+  properly.
 It is legal for any IRQ consumer to request an IRQ from any irqchip no matter
 if that is a combined GPIO+IRQ driver. The basic premise is that gpio_chip and
 irq_chip are orthogonal, and offering their services independent of each