Commit 0fbee1df authored by Linus Walleij's avatar Linus Walleij

gpio: Update documentation

Strictify the language a bit, move things around, make proper
headings, mention pull-up and pull-down, expand unreadable
acronyms etc.
Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
parent 7358a821
================================ =====================
GPIO Descriptor Driver Interface GPIO Driver Interface
================================ =====================
This document serves as a guide for GPIO chip drivers writers. Note that it This document serves as a guide for writers of GPIO chip drivers.
describes the new descriptor-based interface. For a description of the
deprecated integer-based GPIO interface please refer to gpio-legacy.txt.
Each GPIO controller driver needs to include the following header, which defines Each GPIO controller driver needs to include the following header, which defines
the structures used to define a GPIO driver: the structures used to define a GPIO driver:
...@@ -15,32 +13,49 @@ the structures used to define a GPIO driver: ...@@ -15,32 +13,49 @@ the structures used to define a GPIO driver:
Internal Representation of GPIOs Internal Representation of GPIOs
================================ ================================
Inside a GPIO driver, individual GPIOs are identified by their hardware number, A GPIO chip handles one or more GPIO lines. To be considered a GPIO chip, the
which is a unique number between 0 and n, n being the number of GPIOs managed by lines must conform to the definition: General Purpose Input/Output. If the
the chip. This number is purely internal: the hardware number of a particular line is not general purpose, it is not GPIO and should not be handled by a
GPIO descriptor is never made visible outside of the driver. GPIO chip. The use case is the indicative: certain lines in a system may be
called GPIO but serve a very particular purpose thus not meeting the criteria
On top of this internal number, each GPIO also need to have a global number in of a general purpose I/O. On the other hand a LED driver line may be used as a
the integer GPIO namespace so that it can be used with the legacy GPIO GPIO and should therefore still be handled by a GPIO chip driver.
Inside a GPIO driver, individual GPIO lines are identified by their hardware
number, sometime also referred to as ``offset``, which is a unique number
between 0 and n-1, n being the number of GPIOs managed by the chip.
The hardware GPIO number should be something intuitive to the hardware, for
example if a system uses a memory-mapped set of I/O-registers where 32 GPIO
lines are handled by one bit per line in a 32-bit register, it makes sense to
use hardware offsets 0..31 for these, corresponding to bits 0..31 in the
register.
This number is purely internal: the hardware number of a particular GPIO
line is never made visible outside of the driver.
On top of this internal number, each GPIO line also needs to have a global
number in the integer GPIO namespace so that it can be used with the legacy GPIO
interface. Each chip must thus have a "base" number (which can be automatically interface. Each chip must thus have a "base" number (which can be automatically
assigned), and for each GPIO the global number will be (base + hardware number). assigned), and for each GPIO line the global number will be (base + hardware
Although the integer representation is considered deprecated, it still has many number). Although the integer representation is considered deprecated, it still
users and thus needs to be maintained. has many users and thus needs to be maintained.
So for example one platform could use numbers 32-159 for GPIOs, with a So for example one platform could use global numbers 32-159 for GPIOs, with a
controller defining 128 GPIOs at a "base" of 32 ; while another platform uses controller defining 128 GPIOs at a "base" of 32 ; while another platform uses
numbers 0..63 with one set of GPIO controllers, 64-79 with another type of GPIO global numbers 0..63 with one set of GPIO controllers, 64-79 with another type
controller, and on one particular board 80-95 with an FPGA. The numbers need not of GPIO controller, and on one particular board 80-95 with an FPGA. The legacy
be contiguous; either of those platforms could also use numbers 2000-2063 to numbers need not be contiguous; either of those platforms could also use numbers
identify GPIOs in a bank of I2C GPIO expanders. 2000-2063 to identify GPIO lines in a bank of I2C GPIO expanders.
Controller Drivers: gpio_chip Controller Drivers: gpio_chip
============================= =============================
In the gpiolib framework each GPIO controller is packaged as a "struct In the gpiolib framework each GPIO controller is packaged as a "struct
gpio_chip" (see linux/gpio/driver.h for its complete definition) with members gpio_chip" (see <linux/gpio/driver.h> for its complete definition) with members
common to each controller of that type: common to each controller of that type, these should be assigned by the
driver code:
- methods to establish GPIO line direction - methods to establish GPIO line direction
- methods used to access GPIO line values - methods used to access GPIO line values
...@@ -48,12 +63,12 @@ common to each controller of that type: ...@@ -48,12 +63,12 @@ common to each controller of that type:
- method to return the IRQ number associated to a given GPIO line - method to return the IRQ number associated to a given GPIO line
- flag saying whether calls to its methods may sleep - flag saying whether calls to its methods may sleep
- optional line names array to identify lines - optional line names array to identify lines
- optional debugfs dump method (showing extra state like pullup config) - optional debugfs dump method (showing extra state information)
- optional base number (will be automatically assigned if omitted) - optional base number (will be automatically assigned if omitted)
- optional label for diagnostics and GPIO chip mapping using platform data - optional label for diagnostics and GPIO chip mapping using platform data
The code implementing a gpio_chip should support multiple instances of the The code implementing a gpio_chip should support multiple instances of the
controller, possibly using the driver model. That code will configure each controller, preferably using the driver model. That code will configure each
gpio_chip and issue ``gpiochip_add[_data]()`` or ``devm_gpiochip_add_data()``. gpio_chip and issue ``gpiochip_add[_data]()`` or ``devm_gpiochip_add_data()``.
Removing a GPIO controller should be rare; use ``[devm_]gpiochip_remove()`` Removing a GPIO controller should be rare; use ``[devm_]gpiochip_remove()``
when it is unavoidable. when it is unavoidable.
...@@ -62,24 +77,28 @@ Often a gpio_chip is part of an instance-specific structure with states not ...@@ -62,24 +77,28 @@ Often a gpio_chip is part of an instance-specific structure with states not
exposed by the GPIO interfaces, such as addressing, power management, and more. exposed by the GPIO interfaces, such as addressing, power management, and more.
Chips such as audio codecs will have complex non-GPIO states. Chips such as audio codecs will have complex non-GPIO states.
Any debugfs dump method should normally ignore signals which haven't been Any debugfs dump method should normally ignore lines which haven't been
requested as GPIOs. They can use gpiochip_is_requested(), which returns either requested. They can use gpiochip_is_requested(), which returns either
NULL or the label associated with that GPIO when it was requested. NULL or the label associated with that GPIO line when it was requested.
RT_FULL: the GPIO driver should not use spinlock_t or any sleepable APIs Realtime considerations: the GPIO driver should not use spinlock_t or any
(like PM runtime) in its gpio_chip implementation (.get/.set and direction sleepable APIs (like PM runtime) in its gpio_chip implementation (.get/.set
control callbacks) if it is expected to call GPIO APIs from atomic context and direction control callbacks) if it is expected to call GPIO APIs from
on -RT (inside hard IRQ handlers and similar contexts). Normally this should atomic context on realtime kernels (inside hard IRQ handlers and similar
not be required. contexts). Normally this should not be required.
GPIO electrical configuration GPIO electrical configuration
----------------------------- -----------------------------
GPIOs can be configured for several electrical modes of operation by using the GPIO lines can be configured for several electrical modes of operation by using
.set_config() callback. Currently this API supports setting debouncing and the .set_config() callback. Currently this API supports setting:
single-ended modes (open drain/open source). These settings are described
below. - Debouncing
- Single-ended modes (open drain/open source)
- Pull up and pull down resistor enablement
These settings are described below.
The .set_config() callback uses the same enumerators and configuration The .set_config() callback uses the same enumerators and configuration
semantics as the generic pin control drivers. This is not a coincidence: it is semantics as the generic pin control drivers. This is not a coincidence: it is
...@@ -94,8 +113,8 @@ description needs to provide "GPIO ranges" mapping the GPIO line offsets to pin ...@@ -94,8 +113,8 @@ description needs to provide "GPIO ranges" mapping the GPIO line offsets to pin
numbers on the pin controller so they can properly cross-reference each other. numbers on the pin controller so they can properly cross-reference each other.
GPIOs with debounce support GPIO lines with debounce support
--------------------------- --------------------------------
Debouncing is a configuration set to a pin indicating that it is connected to Debouncing is a configuration set to a pin indicating that it is connected to
a mechanical switch or button, or similar that may bounce. Bouncing means the a mechanical switch or button, or similar that may bounce. Bouncing means the
...@@ -111,8 +130,8 @@ a certain number of milliseconds for debouncing, or just "on/off" if that time ...@@ -111,8 +130,8 @@ a certain number of milliseconds for debouncing, or just "on/off" if that time
is not configurable. is not configurable.
GPIOs with open drain/source support GPIO lines with open drain/source support
------------------------------------ -----------------------------------------
Open drain (CMOS) or open collector (TTL) means the line is not actively driven Open drain (CMOS) or open collector (TTL) means the line is not actively driven
high: instead you provide the drain/collector as output, so when the transistor high: instead you provide the drain/collector as output, so when the transistor
...@@ -132,13 +151,13 @@ This configuration is normally used as a way to achieve one of two things: ...@@ -132,13 +151,13 @@ This configuration is normally used as a way to achieve one of two things:
- Level-shifting: to reach a logical level higher than that of the silicon - Level-shifting: to reach a logical level higher than that of the silicon
where the output resides. where the output resides.
- inverse wire-OR on an I/O line, for example a GPIO line, making it possible - Inverse wire-OR on an I/O line, for example a GPIO line, making it possible
for any driving stage on the line to drive it low even if any other output for any driving stage on the line to drive it low even if any other output
to the same line is simultaneously driving it high. A special case of this to the same line is simultaneously driving it high. A special case of this
is driving the SCL and SDA lines of an I2C bus, which is by definition a is driving the SCL and SDA lines of an I2C bus, which is by definition a
wire-OR bus. wire-OR bus.
Both usecases require that the line be equipped with a pull-up resistor. This Both use cases require that the line be equipped with a pull-up resistor. This
resistor will make the line tend to high level unless one of the transistors on resistor will make the line tend to high level unless one of the transistors on
the rail actively pulls it down. the rail actively pulls it down.
...@@ -208,27 +227,91 @@ For open source configuration the same principle is used, just that instead ...@@ -208,27 +227,91 @@ For open source configuration the same principle is used, just that instead
of actively driving the line low, it is set to input. of actively driving the line low, it is set to input.
GPIO lines with pull up/down resistor support
---------------------------------------------
A GPIO line can support pull-up/down using the .set_config() callback. This
means that a pull up or pull-down resistor is available on the output of the
GPIO line, and this resistor is software controlled.
In discrete designs, a pull-up or pull-down resistor is simply soldered on
the circuit board. This is not something we deal or model in software. The
most you will think about these lines is that they will very likely be
configured as open drain or open source (see the section above).
The .set_config() callback can only turn pull up or down on and off, and will
no have any semantic knowledge about the resistance used. It will only say
switch a bit in a register enabling or disabling pull-up or pull-down.
If the GPIO line supports shunting in different resistance values for the
pull-up or pull-down resistor, the GPIO chip callback .set_config() will not
suffice. For these complex use cases, a combined GPIO chip and pin controller
need to be implemented, as the pin config interface of a pin controller
supports more versatile control over electrical properties and can handle
different pull-up or pull-down resistance values.
GPIO drivers providing IRQs GPIO drivers providing IRQs
--------------------------- ===========================
It is custom that GPIO drivers (GPIO chips) are also providing interrupts, It is custom that GPIO drivers (GPIO chips) are also providing interrupts,
most often cascaded off a parent interrupt controller, and in some special most often cascaded off a parent interrupt controller, and in some special
cases the GPIO logic is melded with a SoC's primary interrupt controller. cases the GPIO logic is melded with a SoC's primary interrupt controller.
The IRQ portions of the GPIO block are implemented using an irqchip, using The IRQ portions of the GPIO block are implemented using an irq_chip, using
the header <linux/irq.h>. So basically such a driver is utilizing two sub- the header <linux/irq.h>. So basically such a driver is utilizing two sub-
systems simultaneously: gpio and irq. systems simultaneously: gpio and irq.
RT_FULL: a realtime compliant GPIO driver should not use spinlock_t or any It is legal for any IRQ consumer to request an IRQ from any irqchip even if it
sleepable APIs (like PM runtime) as part of its irq_chip implementation. 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
other.
* spinlock_t should be replaced with raw_spinlock_t [1]. gpiod_to_irq() is just a convenience function to figure out the IRQ for a
* If sleepable APIs have to be used, these can be done from the .irq_bus_lock() certain GPIO line and should not be relied upon to have been called before
the IRQ is used.
Always prepare the hardware and make it ready for action in respective
callbacks from the GPIO and irq_chip APIs. Do not rely on gpiod_to_irq() having
been called first.
We can divide GPIO irqchips in two broad categories:
- CASCADED INTERRUPT CHIPS: this means that the GPIO chip has one common
interrupt output line, which is triggered by any enabled GPIO line on that
chip. The interrupt output line will then be routed to an parent interrupt
controller one level up, in the most simple case the systems primary
interrupt controller. This is modeled by an irqchip that will inspect bits
inside the GPIO controller to figure out which line fired it. The irqchip
part of the driver needs to inspect registers to figure this out and it
will likely also need to acknowledge that it is handling the interrupt
by clearing some bit (sometime implicitly, by just reading a status
register) and it will often need to set up the configuration such as
edge sensitivity (rising or falling edge, or high/low level interrupt for
example).
- HIERARCHICAL INTERRUPT CHIPS: this means that each GPIO line has a dedicated
irq line to a parent interrupt controller one level up. There is no need
to inquire the GPIO hardware to figure out which line has figured, but it
may still be necessary to acknowledge the interrupt and set up the
configuration such as edge sensitivity.
Realtime considerations: a realtime compliant GPIO driver should not use
spinlock_t or any sleepable APIs (like PM runtime) as part of its irqchip
implementation.
- spinlock_t should be replaced with raw_spinlock_t [1].
- If sleepable APIs have to be used, these can be done from the .irq_bus_lock()
and .irq_bus_unlock() callbacks, as these are the only slowpath callbacks and .irq_bus_unlock() callbacks, as these are the only slowpath callbacks
on an irqchip. Create the callbacks if needed [2]. on an irqchip. Create the callbacks if needed [2].
GPIO irqchips usually fall in one of two categories:
* CHAINED GPIO irqchips: these are usually the type that is embedded on Cascaded GPIO irqchips
----------------------
Cascaded GPIO irqchips usually fall in one of three categories:
- CHAINED CASCADED GPIO IRQCHIPS: these are usually the type that is embedded on
an SoC. This means that there is a fast IRQ flow handler for the GPIOs that an SoC. This means that there is a fast IRQ flow handler for the GPIOs that
gets called in a chain from the parent IRQ handler, most typically the gets called in a chain from the parent IRQ handler, most typically the
system interrupt controller. This means that the GPIO irqchip handler will system interrupt controller. This means that the GPIO irqchip handler will
...@@ -245,16 +328,19 @@ GPIO irqchips usually fall in one of two categories: ...@@ -245,16 +328,19 @@ GPIO irqchips usually fall in one of two categories:
struct gpio_chip, as everything happens directly in the callbacks: no struct gpio_chip, as everything happens directly in the callbacks: no
slow bus traffic like I2C can be used. slow bus traffic like I2C can be used.
RT_FULL: Note, chained IRQ handlers will not be forced threaded on -RT. Realtime considerations: Note that chained IRQ handlers will not be forced
As result, spinlock_t or any sleepable APIs (like PM runtime) can't be used threaded on -RT. As a result, spinlock_t or any sleepable APIs (like PM
in chained IRQ handler. runtime) can't be used in a chained IRQ handler.
If required (and if it can't be converted to the nested threaded GPIO irqchip)
a chained IRQ handler can be converted to generic irq handler and this way If required (and if it can't be converted to the nested threaded GPIO irqchip,
it will be a threaded IRQ handler on -RT and a hard IRQ handler on non-RT see below) a chained IRQ handler can be converted to generic irq handler and
(for example, see [3]). this way it will become a threaded IRQ handler on -RT and a hard IRQ handler
Know W/A: The generic_handle_irq() is expected to be called with IRQ disabled, on non-RT (for example, see [3]).
The generic_handle_irq() is expected to be called with IRQ disabled,
so the IRQ core will complain if it is called from an IRQ handler which is so the IRQ core will complain if it is called from an IRQ handler which is
forced to a thread. The "fake?" raw lock can be used to W/A this problem:: forced to a thread. The "fake?" raw lock can be used to work around this
problem::
raw_spinlock_t wa_lock; raw_spinlock_t wa_lock;
static irqreturn_t omap_gpio_irq_handler(int irq, void *gpiobank) static irqreturn_t omap_gpio_irq_handler(int irq, void *gpiobank)
...@@ -263,7 +349,7 @@ GPIO irqchips usually fall in one of two categories: ...@@ -263,7 +349,7 @@ GPIO irqchips usually fall in one of two categories:
generic_handle_irq(irq_find_mapping(bank->chip.irq.domain, bit)); generic_handle_irq(irq_find_mapping(bank->chip.irq.domain, bit));
raw_spin_unlock_irqrestore(&bank->wa_lock, wa_lock_flags); raw_spin_unlock_irqrestore(&bank->wa_lock, wa_lock_flags);
* GENERIC CHAINED GPIO irqchips: these are the same as "CHAINED GPIO irqchips", - GENERIC CHAINED GPIO IRQCHIPS: these are the same as "CHAINED GPIO irqchips",
but chained IRQ handlers are not used. Instead GPIO IRQs dispatching is but chained IRQ handlers are not used. Instead GPIO IRQs dispatching is
performed by generic IRQ handler which is configured using request_irq(). performed by generic IRQ handler which is configured using request_irq().
The GPIO irqchip will then end up calling something like this sequence in The GPIO irqchip will then end up calling something like this sequence in
...@@ -273,16 +359,19 @@ GPIO irqchips usually fall in one of two categories: ...@@ -273,16 +359,19 @@ GPIO irqchips usually fall in one of two categories:
for each detected GPIO IRQ for each detected GPIO IRQ
generic_handle_irq(...); generic_handle_irq(...);
RT_FULL: Such kind of handlers will be forced threaded on -RT, as result IRQ Realtime considerations: this kind of handlers will be forced threaded on -RT,
core will complain that generic_handle_irq() is called with IRQ enabled and and as result the IRQ core will complain that generic_handle_irq() is called
the same W/A as for "CHAINED GPIO irqchips" can be applied. with IRQ enabled and the same work around as for "CHAINED GPIO irqchips" can
be applied.
- NESTED THREADED GPIO IRQCHIPS: these are off-chip GPIO expanders and any
other GPIO irqchip residing on the other side of a sleeping bus such as I2C
or SPI.
* NESTED THREADED GPIO irqchips: these are off-chip GPIO expanders and any Of course such drivers that need slow bus traffic to read out IRQ status and
other GPIO irqchip residing on the other side of a sleeping bus. Of course similar, traffic which may in turn incur other IRQs to happen, cannot be
such drivers that need slow bus traffic to read out IRQ status and similar, handled in a quick IRQ handler with IRQs disabled. Instead they need to spawn
traffic which may in turn incur other IRQs to happen, cannot be handled a thread and then mask the parent IRQ line until the interrupt is 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 by the driver. The hallmark of this driver is to call something like
this in its interrupt handler:: this in its interrupt handler::
...@@ -294,36 +383,46 @@ GPIO irqchips usually fall in one of two categories: ...@@ -294,36 +383,46 @@ GPIO irqchips usually fall in one of two categories:
flag on struct gpio_chip to true, indicating that this chip may sleep flag on struct gpio_chip to true, indicating that this chip may sleep
when accessing the GPIOs. when accessing the GPIOs.
These kinds of irqchips are inherently realtime tolerant as they are
already set up to handle sleeping contexts.
Infrastructure helpers for GPIO irqchips
----------------------------------------
To help out in handling the set-up and management of GPIO irqchips and the To help out in handling the set-up and management of GPIO irqchips and the
associated irqdomain and resource allocation callbacks, the gpiolib has associated irqdomain and resource allocation callbacks, the gpiolib has
some helpers that can be enabled by selecting the GPIOLIB_IRQCHIP Kconfig some helpers that can be enabled by selecting the GPIOLIB_IRQCHIP Kconfig
symbol: symbol:
* gpiochip_irqchip_add(): adds a chained irqchip to a gpiochip. It will pass - gpiochip_irqchip_add(): adds a chained cascaded irqchip to a gpiochip. It
the struct gpio_chip* for the chip to all IRQ callbacks, so the callbacks will pass the struct gpio_chip* for the chip to all IRQ callbacks, so the
need to embed the gpio_chip in its state container and obtain a pointer callbacks need to embed the gpio_chip in its state container and obtain a
to the container using container_of(). pointer to the container using container_of().
(See Documentation/driver-model/design-patterns.txt) (See Documentation/driver-model/design-patterns.txt)
* gpiochip_irqchip_add_nested(): adds a nested irqchip to a gpiochip. - gpiochip_irqchip_add_nested(): adds a nested cascaded irqchip to a gpiochip,
as discussed above regarding different types of cascaded irqchips. The
cascaded irq has to be handled by a threaded interrupt handler.
Apart from that it works exactly like the chained irqchip. Apart from that it works exactly like the chained irqchip.
* gpiochip_set_chained_irqchip(): sets up a chained irq handler for a - gpiochip_set_chained_irqchip(): sets up a chained cascaded irq handler for a
gpio_chip from a parent IRQ and passes the struct gpio_chip* as handler 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 data. Notice that we pass is as the handler data, since the irqchip data is
parent irqchip!). likely used by the parent irqchip.
* gpiochip_set_nested_irqchip(): sets up a nested irq handler for a - gpiochip_set_nested_irqchip(): sets up a nested cascaded irq handler for a
gpio_chip from a parent IRQ. As the parent IRQ has usually been gpio_chip from a parent IRQ. As the parent IRQ has usually been
explicitly requested by the driver, this does very little more than explicitly requested by the driver, this does very little more than
mark all the child IRQs as having the other IRQ as parent. mark all the child IRQs as having the other IRQ as parent.
If there is a need to exclude certain GPIOs from the IRQ domain, you can If there is a need to exclude certain GPIO lines from the IRQ domain handled by
set .irq.need_valid_mask of the gpiochip before gpiochip_add_data() is these helpers, we can set .irq.need_valid_mask of the gpiochip before
called. This allocates an .irq.valid_mask with as many bits set as there [devm_]gpiochip_add_data() is called. This allocates an .irq.valid_mask with as
are GPIOs in the chip. Drivers can exclude GPIOs by clearing bits from this many bits set as there are GPIO lines in the chip, each bit representing line
mask. The mask must be filled in before gpiochip_irqchip_add() or 0..n-1. Drivers can exclude GPIO lines by clearing bits from this mask. The mask
gpiochip_irqchip_add_nested() is called. must be filled in before gpiochip_irqchip_add() or gpiochip_irqchip_add_nested()
is called.
To use the helpers please keep the following in mind: To use the helpers please keep the following in mind:
...@@ -333,33 +432,24 @@ To use the helpers please keep the following in mind: ...@@ -333,33 +432,24 @@ To use the helpers please keep the following in mind:
- Nominally set all handlers to handle_bad_irq() in the setup call and pass - Nominally set all handlers to handle_bad_irq() in the setup call and pass
handle_bad_irq() as flow handler parameter in gpiochip_irqchip_add() if it is handle_bad_irq() as flow handler parameter in gpiochip_irqchip_add() if it is
expected for GPIO driver that irqchip .set_type() callback have to be called expected for GPIO driver that irqchip .set_type() callback will be called
before using/enabling GPIO IRQ. Then set the handler to handle_level_irq() before using/enabling each GPIO IRQ. Then set the handler to
and/or handle_edge_irq() in the irqchip .set_type() callback depending on handle_level_irq() and/or handle_edge_irq() in the irqchip .set_type()
what your controller supports. callback depending on what your controller supports and what is requested
by the consumer.
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
other.
gpiod_to_irq() is just a convenience function to figure out the IRQ for a
certain GPIO line and should not be relied upon to have been called before
the IRQ is used.
So always prepare the hardware and make it ready for action in respective Locking IRQ usage
callbacks from the GPIO and irqchip APIs. Do not rely on gpiod_to_irq() having -----------------
been called first.
This orthogonality leads to ambiguities that we need to solve: if there is Since GPIO and irq_chip are orthogonal, we can get conflicts between different
competition inside the subsystem which side is using the resource (a certain use cases. For example a GPIO line used for IRQs should be an input line,
GPIO line and register for example) it needs to deny certain operations and it does not make sense to fire interrupts on an output GPIO.
keep track of usage inside of the gpiolib subsystem. This is why the API
below exists.
If there is competition inside the subsystem which side is using the
resource (a certain GPIO line and register for example) it needs to deny
certain operations and keep track of usage inside of the gpiolib subsystem.
Locking IRQ usage
-----------------
Input GPIOs can be used as IRQ signals. When this happens, a driver is requested Input GPIOs can be used as IRQ signals. When this happens, a driver is requested
to mark the GPIO as being used as an IRQ:: to mark the GPIO as being used as an IRQ::
...@@ -380,9 +470,15 @@ assigned. ...@@ -380,9 +470,15 @@ assigned.
Disabling and enabling IRQs Disabling and enabling IRQs
--------------------------- ---------------------------
In some (fringe) use cases, a driver may be using a GPIO line as input for IRQs,
but occasionally switch that line over to drive output and then back to being
an input with interrupts again. This happens on things like CEC (Consumer
Electronics Control).
When a GPIO is used as an IRQ signal, then gpiolib also needs to know if When a GPIO is used as an IRQ signal, then gpiolib also needs to know if
the IRQ is enabled or disabled. In order to inform gpiolib about this, the IRQ is enabled or disabled. In order to inform gpiolib about this,
a driver should call:: the irqchip driver should call::
void gpiochip_disable_irq(struct gpio_chip *chip, unsigned int offset) void gpiochip_disable_irq(struct gpio_chip *chip, unsigned int offset)
...@@ -398,40 +494,45 @@ irqchip. ...@@ -398,40 +494,45 @@ irqchip.
When using the gpiolib irqchip helpers, these callbacks are automatically When using the gpiolib irqchip helpers, these callbacks are automatically
assigned. assigned.
Real-Time compliance for GPIO IRQ chips Real-Time compliance for GPIO IRQ chips
--------------------------------------- ---------------------------------------
Any provider of irqchips needs to be carefully tailored to support Real Time Any provider of irqchips needs to be carefully tailored to support Real-Time
preemption. It is desirable that all irqchips in the GPIO subsystem keep this preemption. It is desirable that all irqchips in the GPIO subsystem keep this
in mind and do the proper testing to assure they are real time-enabled. in mind and do the proper testing to assure they are real time-enabled.
So, pay attention on above " RT_FULL:" notes, please.
The following is a checklist to follow when preparing a driver for real
time-compliance:
- ensure spinlock_t is not used as part irq_chip implementation; So, pay attention on above realtime considerations in the documentation.
- ensure that sleepable APIs are not used as part irq_chip implementation.
The following is a checklist to follow when preparing a driver for real-time
compliance:
- ensure spinlock_t is not used as part irq_chip implementation
- ensure that sleepable APIs are not used as part irq_chip implementation
If sleepable APIs have to be used, these can be done from the .irq_bus_lock() If sleepable APIs have to be used, these can be done from the .irq_bus_lock()
and .irq_bus_unlock() callbacks; and .irq_bus_unlock() callbacks
- Chained GPIO irqchips: ensure spinlock_t or any sleepable APIs are not used - Chained GPIO irqchips: ensure spinlock_t or any sleepable APIs are not used
from chained IRQ handler; from the chained IRQ handler
- Generic chained GPIO irqchips: take care about generic_handle_irq() calls and - Generic chained GPIO irqchips: take care about generic_handle_irq() calls and
apply corresponding W/A; apply corresponding work-around
- Chained GPIO irqchips: get rid of chained IRQ handler and use generic irq - Chained GPIO irqchips: get rid of the chained IRQ handler and use generic irq
handler if possible :) handler if possible
- regmap_mmio: Sry, but you are in trouble :( if MMIO regmap is used as for - regmap_mmio: it is possible to disable internal locking in regmap by setting
GPIO IRQ chip implementation; .disable_locking and handling the locking in the GPIO driver
- Test your driver with the appropriate in-kernel real time test cases for both - Test your driver with the appropriate in-kernel real-time test cases for both
level and edge IRQs. level and edge IRQs
* [1] http://www.spinics.net/lists/linux-omap/msg120425.html
* [2] https://lkml.org/lkml/2015/9/25/494
* [3] https://lkml.org/lkml/2015/9/25/495
Requesting self-owned GPIO pins Requesting self-owned GPIO pins
------------------------------- ===============================
Sometimes it is useful to allow a GPIO chip driver to request its own GPIO Sometimes it is useful to allow a GPIO chip driver to request its own GPIO
descriptors through the gpiolib API. Using gpio_request() for this purpose descriptors through the gpiolib API. A GPIO driver can use the following
does not help since it pins the module to the kernel forever (it calls functions to request and free descriptors::
try_module_get()). A GPIO driver can use the following functions instead
to request and free descriptors without being pinned to the kernel forever::
struct gpio_desc *gpiochip_request_own_desc(struct gpio_desc *desc, struct gpio_desc *gpiochip_request_own_desc(struct gpio_desc *desc,
u16 hwnum, u16 hwnum,
...@@ -446,7 +547,3 @@ gpiochip_free_own_desc(). ...@@ -446,7 +547,3 @@ gpiochip_free_own_desc().
These functions must be used with care since they do not affect module use These functions must be used with care since they do not affect module use
count. Do not use the functions to request gpio descriptors not owned by the count. Do not use the functions to request gpio descriptors not owned by the
calling driver. calling driver.
* [1] http://www.spinics.net/lists/linux-omap/msg120425.html
* [2] https://lkml.org/lkml/2015/9/25/494
* [3] https://lkml.org/lkml/2015/9/25/495
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment