gpio interrupt on x86

Ian Lepore ian at freebsd.org
Thu May 30 15:35:56 UTC 2019


On Mon, 2019-05-27 at 18:17 +0300, Andriy Gapon wrote:
> I would like to run some code when an input pin changes its state.
> A GPIO controller that handles that pin is capable of generating an interrupt.
> I can configure the type of a signal change that would trigger the interrupt.
> The GPIO controller would generate the interrupt on that change.
> I would be able to query the controller for a specific pin (if interrupts for
> multiple pins are enabled).
> All is good.
> 
> Now, the question is how to _properly_ hook my code to the gpiobus hanging off
> the controller.
> I see that embedded (or not so embedded) platforms typically define a "slave"
> interrupt controller.  I guess that it defines a new interrupt number (and
> interrupt source, etc) for each interrupt capable pin.  And then hooking to that
> pin is a matter of just installing an interrupt handler for a specific interrupt
> and enabling it.
> 
> But I am not sure if the same approach would work on x86.
> Is there any other alternative approach?
> Perhaps even a more light-weight one?
> Any code examples?
> 
> Thank you.

The way this works on modern embedded systems is via INTRNG, a
framework that allows any number of interrupt controllers of differing
types and capabilities to coexist.  A gpio hardware driver registers
itself as an interrupt controller, then the interrupts it provides
(each gpio pin) are accessible as resources just like interrupts on the
primary controller, and so drivers just use interrupts that originate
from a gpio pin the same as they would any other interrupt.

Of course, one required piece of magic to make all this work is
metadata:  something needs to make the connection between the gpio
controller and pin, and the driver that wants to use changes on that
pin as an interrupt indication.  In the embedded world it's FDT data
that describes those connections, so that when a driver asks for
interrupt resource index N it reads the FDT data to find a cross-
reference to which gpio device and pin to use for that.  The
connections between the gpiopin interrupt source and the resources
allocated by other drivers are made in nexus.  This is because
typically there isn't a parent-child relationship between the device
that manages the gpio pins and the devices that want to use those pins
as a source of interrupts; nexus is the common ancestor of both.

The x86 world doesn't use INTRNG (but it must have something similar,
since all modern x86 hardware has multiple interrupt controllers).  So
I'm not sure how a gpio driver for x86 might be an interrupt source,
but there should be a way for that to happen.  The harder part, I
think, will be coming up with the metadata to allow another driver
which is not a [grand]child of the gpio controller to use those
interrupts.

-- Ian



More information about the freebsd-hackers mailing list