123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778 |
- =====================
- GPIO Driver Interface
- =====================
- This document serves as a guide for writers of GPIO chip drivers.
- Each GPIO controller driver needs to include the following header, which defines
- the structures used to define a GPIO driver::
- #include <linux/gpio/driver.h>
- Internal Representation of GPIOs
- ================================
- A GPIO chip handles one or more GPIO lines. To be considered a GPIO chip, the
- lines must conform to the definition: General Purpose Input/Output. If the
- line is not general purpose, it is not GPIO and should not be handled by a
- 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
- of a general purpose I/O. On the other hand a LED driver line may be used as a
- 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
- assigned), and for each GPIO line the global number will be (base + hardware
- number). Although the integer representation is considered deprecated, it still
- has many users and thus needs to be maintained.
- 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
- global numbers 0..63 with one set of GPIO controllers, 64-79 with another type
- of GPIO controller, and on one particular board 80-95 with an FPGA. The legacy
- numbers need not be contiguous; either of those platforms could also use numbers
- 2000-2063 to identify GPIO lines in a bank of I2C GPIO expanders.
- Controller Drivers: gpio_chip
- =============================
- 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
- common to each controller of that type, these should be assigned by the
- driver code:
- - methods to establish GPIO line direction
- - methods used to access GPIO line values
- - method to set electrical configuration for 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
- - optional line names array to identify lines
- - optional debugfs dump method (showing extra state information)
- - optional base number (will be automatically assigned if omitted)
- - optional label for diagnostics and GPIO chip mapping using platform data
- The code implementing a gpio_chip should support multiple instances of the
- controller, preferably using the driver model. That code will configure each
- gpio_chip and issue gpiochip_add(), gpiochip_add_data(), or
- devm_gpiochip_add_data(). Removing a GPIO controller should be rare; use
- gpiochip_remove() when it is unavoidable.
- 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.
- Chips such as audio codecs will have complex non-GPIO states.
- Any debugfs dump method should normally ignore lines which haven't been
- requested. They can use gpiochip_is_requested(), which returns either
- NULL or the label associated with that GPIO line when it was requested.
- Realtime considerations: the GPIO driver should not use spinlock_t or any
- sleepable APIs (like PM runtime) in its gpio_chip implementation (.get/.set
- and direction control callbacks) if it is expected to call GPIO APIs from
- atomic context on realtime kernels (inside hard IRQ handlers and similar
- contexts). Normally this should not be required.
- GPIO electrical configuration
- -----------------------------
- GPIO lines can be configured for several electrical modes of operation by using
- the .set_config() callback. Currently this API supports setting:
- - 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
- semantics as the generic pin control drivers. This is not a coincidence: it is
- possible to assign the .set_config() to the function gpiochip_generic_config()
- which will result in pinctrl_gpio_set_config() being called and eventually
- ending up in the pin control back-end "behind" the GPIO controller, usually
- closer to the actual pins. This way the pin controller can manage the below
- listed GPIO configurations.
- If a pin controller back-end is used, the GPIO controller or hardware
- 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.
- GPIO lines with debounce support
- --------------------------------
- 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
- line is pulled high/low quickly at very short intervals for mechanical
- reasons. This can result in the value being unstable or irqs firing repeatedly
- unless the line is debounced.
- Debouncing in practice involves setting up a timer when something happens on
- the line, wait a little while and then sample the line again, so see if it
- still has the same value (low or high). This could also be repeated by a clever
- state machine, waiting for a line to become stable. In either case, it sets
- a certain number of milliseconds for debouncing, or just "on/off" if that time
- is not configurable.
- GPIO lines with open drain/source support
- -----------------------------------------
- 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
- is not open, it will present a high-impedance (tristate) to the external rail::
- CMOS CONFIGURATION TTL CONFIGURATION
- ||--- out +--- out
- in ----|| |/
- ||--+ in ----|
- | |\
- GND GND
- 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
- where the output resides.
- - 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
- 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
- wire-OR bus.
- 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
- the rail actively pulls it down.
- The level on the line will go as high as the VDD on the pull-up resistor, which
- may be higher than the level supported by the transistor, achieving a
- level-shift to the higher VDD.
- Integrated electronics often have an output driver stage in the form of a CMOS
- "totem-pole" with one N-MOS and one P-MOS transistor where one of them drives
- the line high and one of them drives the line low. This is called a push-pull
- output. The "totem-pole" looks like so::
- VDD
- |
- OD ||--+
- +--/ ---o|| P-MOS-FET
- | ||--+
- IN --+ +----- out
- | ||--+
- +--/ ----|| N-MOS-FET
- OS ||--+
- |
- GND
- The desired output signal (e.g. coming directly from some GPIO output register)
- arrives at IN. The switches named "OD" and "OS" are normally closed, creating
- a push-pull circuit.
- Consider the little "switches" named "OD" and "OS" that enable/disable the
- P-MOS or N-MOS transistor right after the split of the input. As you can see,
- either transistor will go totally numb if this switch is open. The totem-pole
- is then halved and give high impedance instead of actively driving the line
- high or low respectively. That is usually how software-controlled open
- drain/source works.
- Some GPIO hardware come in open drain / open source configuration. Some are
- hard-wired lines that will only support open drain or open source no matter
- what: there is only one transistor there. Some are software-configurable:
- by flipping a bit in a register the output can be configured as open drain
- or open source, in practice by flicking open the switches labeled "OD" and "OS"
- in the drawing above.
- By disabling the P-MOS transistor, the output can be driven between GND and
- high impedance (open drain), and by disabling the N-MOS transistor, the output
- can be driven between VDD and high impedance (open source). In the first case,
- a pull-up resistor is needed on the outgoing rail to complete the circuit, and
- in the second case, a pull-down resistor is needed on the rail.
- Hardware that supports open drain or open source or both, can implement a
- special callback in the gpio_chip: .set_config() that takes a generic
- pinconf packed value telling whether to configure the line as open drain,
- open source or push-pull. This will happen in response to the
- GPIO_OPEN_DRAIN or GPIO_OPEN_SOURCE flag set in the machine file, or coming
- from other hardware descriptions.
- If this state can not be configured in hardware, i.e. if the GPIO hardware does
- not support open drain/open source in hardware, the GPIO library will instead
- use a trick: when a line is set as output, if the line is flagged as open
- drain, and the IN output value is low, it will be driven low as usual. But
- if the IN output value is set to high, it will instead *NOT* be driven high,
- instead it will be switched to input, as input mode is high impedance, thus
- achieving an "open drain emulation" of sorts: electrically the behaviour will
- be identical, with the exception of possible hardware glitches when switching
- the mode of the line.
- For open source configuration the same principle is used, just that instead
- 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 with 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
- ===========================
- It is custom that GPIO drivers (GPIO chips) are also providing interrupts,
- 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.
- The IRQ portions of the GPIO block are implemented using an irq_chip, using
- the header <linux/irq.h>. So this combined driver is utilizing two sub-
- systems simultaneously: gpio and irq.
- It is legal for any IRQ consumer to request an IRQ from any irqchip even if it
- 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.
- 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 fired, but it
- may still be necessary to acknowledge the interrupt and set up 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
- on an irqchip. Create the callbacks if needed.[2]
- 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
- gets called in a chain from the parent IRQ handler, most typically the
- system interrupt controller. This means that 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 foo_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: no
- slow bus traffic like I2C can be used.
- Realtime considerations: Note that chained IRQ handlers will not be forced
- threaded on -RT. As a result, spinlock_t or any sleepable APIs (like PM
- 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,
- see below) a chained IRQ handler can be converted to generic irq handler and
- this way it will become a threaded IRQ handler on -RT and a hard IRQ handler
- 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
- forced to a thread. The "fake?" raw lock can be used to work around this
- problem::
- raw_spinlock_t wa_lock;
- static irqreturn_t omap_gpio_irq_handler(int irq, void *gpiobank)
- unsigned long wa_lock_flags;
- raw_spin_lock_irqsave(&bank->wa_lock, wa_lock_flags);
- generic_handle_irq(irq_find_mapping(bank->chip.irq.domain, bit));
- raw_spin_unlock_irqrestore(&bank->wa_lock, wa_lock_flags);
- - GENERIC CHAINED GPIO IRQCHIPS: these are the same as "CHAINED GPIO irqchips",
- but chained IRQ handlers are not used. Instead GPIO IRQs dispatching is
- performed by generic IRQ handler which is configured using request_irq().
- The GPIO irqchip will then end up calling something like this sequence in
- its interrupt handler::
- static irqreturn_t gpio_rcar_irq_handler(int irq, void *dev_id)
- for each detected GPIO IRQ
- generic_handle_irq(...);
- Realtime considerations: this kind of handlers will be forced threaded on -RT,
- and as result the IRQ core will complain that generic_handle_irq() is called
- 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.
- 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 foo_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.
- 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
- associated irqdomain and resource allocation callbacks. These are activated
- by selecting the Kconfig symbol GPIOLIB_IRQCHIP. If the symbol
- IRQ_DOMAIN_HIERARCHY is also selected, hierarchical helpers will also be
- provided. A big portion of overhead code will be managed by gpiolib,
- under the assumption that your interrupts are 1-to-1-mapped to the
- GPIO line index:
- .. csv-table::
- :header: GPIO line offset, Hardware IRQ
- 0,0
- 1,1
- 2,2
- ...,...
- ngpio-1, ngpio-1
- If some GPIO lines do not have corresponding IRQs, the bitmask valid_mask
- and the flag need_valid_mask in gpio_irq_chip can be used to mask off some
- lines as invalid for associating with IRQs.
- The preferred way to set up the helpers is to fill in the
- struct gpio_irq_chip inside struct gpio_chip before adding the gpio_chip.
- If you do this, the additional irq_chip will be set up by gpiolib at the
- same time as setting up the rest of the GPIO functionality. The following
- is a typical example of a chained cascaded interrupt handler using
- the gpio_irq_chip. Note how the mask/unmask (or disable/enable) functions
- call into the core gpiolib code:
- .. code-block:: c
- /* Typical state container */
- struct my_gpio {
- struct gpio_chip gc;
- };
- static void my_gpio_mask_irq(struct irq_data *d)
- {
- struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
- irq_hw_number_t hwirq = irqd_to_hwirq(d);
- /*
- * Perform any necessary action to mask the interrupt,
- * and then call into the core code to synchronise the
- * state.
- */
- gpiochip_disable_irq(gc, hwirq);
- }
- static void my_gpio_unmask_irq(struct irq_data *d)
- {
- struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
- irq_hw_number_t hwirq = irqd_to_hwirq(d);
- gpiochip_enable_irq(gc, hwirq);
- /*
- * Perform any necessary action to unmask the interrupt,
- * after having called into the core code to synchronise
- * the state.
- */
- }
- /*
- * Statically populate the irqchip. Note that it is made const
- * (further indicated by the IRQCHIP_IMMUTABLE flag), and that
- * the GPIOCHIP_IRQ_RESOURCE_HELPER macro adds some extra
- * callbacks to the structure.
- */
- static const struct irq_chip my_gpio_irq_chip = {
- .name = "my_gpio_irq",
- .irq_ack = my_gpio_ack_irq,
- .irq_mask = my_gpio_mask_irq,
- .irq_unmask = my_gpio_unmask_irq,
- .irq_set_type = my_gpio_set_irq_type,
- .flags = IRQCHIP_IMMUTABLE,
- /* Provide the gpio resource callbacks */
- GPIOCHIP_IRQ_RESOURCE_HELPERS,
- };
- int irq; /* from platform etc */
- struct my_gpio *g;
- struct gpio_irq_chip *girq;
- /* Get a pointer to the gpio_irq_chip */
- girq = &g->gc.irq;
- gpio_irq_chip_set_chip(girq, &my_gpio_irq_chip);
- girq->parent_handler = ftgpio_gpio_irq_handler;
- girq->num_parents = 1;
- girq->parents = devm_kcalloc(dev, 1, sizeof(*girq->parents),
- GFP_KERNEL);
- if (!girq->parents)
- return -ENOMEM;
- girq->default_type = IRQ_TYPE_NONE;
- girq->handler = handle_bad_irq;
- girq->parents[0] = irq;
- return devm_gpiochip_add_data(dev, &g->gc, g);
- The helper supports using threaded interrupts as well. Then you just request
- the interrupt separately and go with it:
- .. code-block:: c
- /* Typical state container */
- struct my_gpio {
- struct gpio_chip gc;
- };
- static void my_gpio_mask_irq(struct irq_data *d)
- {
- struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
- irq_hw_number_t hwirq = irqd_to_hwirq(d);
- /*
- * Perform any necessary action to mask the interrupt,
- * and then call into the core code to synchronise the
- * state.
- */
- gpiochip_disable_irq(gc, hwirq);
- }
- static void my_gpio_unmask_irq(struct irq_data *d)
- {
- struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
- irq_hw_number_t hwirq = irqd_to_hwirq(d);
- gpiochip_enable_irq(gc, hwirq);
- /*
- * Perform any necessary action to unmask the interrupt,
- * after having called into the core code to synchronise
- * the state.
- */
- }
- /*
- * Statically populate the irqchip. Note that it is made const
- * (further indicated by the IRQCHIP_IMMUTABLE flag), and that
- * the GPIOCHIP_IRQ_RESOURCE_HELPER macro adds some extra
- * callbacks to the structure.
- */
- static const struct irq_chip my_gpio_irq_chip = {
- .name = "my_gpio_irq",
- .irq_ack = my_gpio_ack_irq,
- .irq_mask = my_gpio_mask_irq,
- .irq_unmask = my_gpio_unmask_irq,
- .irq_set_type = my_gpio_set_irq_type,
- .flags = IRQCHIP_IMMUTABLE,
- /* Provide the gpio resource callbacks */
- GPIOCHIP_IRQ_RESOURCE_HELPERS,
- };
- int irq; /* from platform etc */
- struct my_gpio *g;
- struct gpio_irq_chip *girq;
- ret = devm_request_threaded_irq(dev, irq, NULL,
- irq_thread_fn, IRQF_ONESHOT, "my-chip", g);
- if (ret < 0)
- return ret;
- /* Get a pointer to the gpio_irq_chip */
- girq = &g->gc.irq;
- gpio_irq_chip_set_chip(girq, &my_gpio_irq_chip);
- /* This will let us handle the parent IRQ in the driver */
- girq->parent_handler = NULL;
- girq->num_parents = 0;
- girq->parents = NULL;
- girq->default_type = IRQ_TYPE_NONE;
- girq->handler = handle_bad_irq;
- return devm_gpiochip_add_data(dev, &g->gc, g);
- The helper supports using hierarchical interrupt controllers as well.
- In this case the typical set-up will look like this:
- .. code-block:: c
- /* Typical state container with dynamic irqchip */
- struct my_gpio {
- struct gpio_chip gc;
- struct fwnode_handle *fwnode;
- };
- static void my_gpio_mask_irq(struct irq_data *d)
- {
- struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
- irq_hw_number_t hwirq = irqd_to_hwirq(d);
- /*
- * Perform any necessary action to mask the interrupt,
- * and then call into the core code to synchronise the
- * state.
- */
- gpiochip_disable_irq(gc, hwirq);
- irq_mask_mask_parent(d);
- }
- static void my_gpio_unmask_irq(struct irq_data *d)
- {
- struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
- irq_hw_number_t hwirq = irqd_to_hwirq(d);
- gpiochip_enable_irq(gc, hwirq);
- /*
- * Perform any necessary action to unmask the interrupt,
- * after having called into the core code to synchronise
- * the state.
- */
- irq_mask_unmask_parent(d);
- }
- /*
- * Statically populate the irqchip. Note that it is made const
- * (further indicated by the IRQCHIP_IMMUTABLE flag), and that
- * the GPIOCHIP_IRQ_RESOURCE_HELPER macro adds some extra
- * callbacks to the structure.
- */
- static const struct irq_chip my_gpio_irq_chip = {
- .name = "my_gpio_irq",
- .irq_ack = my_gpio_ack_irq,
- .irq_mask = my_gpio_mask_irq,
- .irq_unmask = my_gpio_unmask_irq,
- .irq_set_type = my_gpio_set_irq_type,
- .flags = IRQCHIP_IMMUTABLE,
- /* Provide the gpio resource callbacks */
- GPIOCHIP_IRQ_RESOURCE_HELPERS,
- };
- struct my_gpio *g;
- struct gpio_irq_chip *girq;
- /* Get a pointer to the gpio_irq_chip */
- girq = &g->gc.irq;
- gpio_irq_chip_set_chip(girq, &my_gpio_irq_chip);
- girq->default_type = IRQ_TYPE_NONE;
- girq->handler = handle_bad_irq;
- girq->fwnode = g->fwnode;
- girq->parent_domain = parent;
- girq->child_to_parent_hwirq = my_gpio_child_to_parent_hwirq;
- return devm_gpiochip_add_data(dev, &g->gc, g);
- As you can see pretty similar, but you do not supply a parent handler for
- the IRQ, instead a parent irqdomain, an fwnode for the hardware and
- a function .child_to_parent_hwirq() that has the purpose of looking up
- the parent hardware irq from a child (i.e. this gpio chip) hardware irq.
- As always it is good to look at examples in the kernel tree for advice
- on how to find the required pieces.
- If there is a need to exclude certain GPIO lines from the IRQ domain handled by
- these helpers, we can set .irq.need_valid_mask of the gpiochip before
- devm_gpiochip_add_data() or gpiochip_add_data() is called. This allocates an
- .irq.valid_mask with as many bits set as there are GPIO lines in the chip, each
- bit representing line 0..n-1. Drivers can exclude GPIO lines by clearing bits
- from this mask. The mask can be filled in the init_valid_mask() callback
- that is part of the struct gpio_irq_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.
- - Nominally set gpio_irq_chip.handler to handle_bad_irq. Then, if your irqchip
- is cascaded, set the handler to handle_level_irq() and/or handle_edge_irq()
- in the irqchip .set_type() callback depending on what your controller
- supports and what is requested by the consumer.
- Locking IRQ usage
- -----------------
- Since GPIO and irq_chip are orthogonal, we can get conflicts between different
- use cases. For example a GPIO line used for IRQs should be an input line,
- it does not make sense to fire interrupts on an output GPIO.
- 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.
- 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::
- int gpiochip_lock_as_irq(struct gpio_chip *chip, unsigned int offset)
- This will prevent the use of non-irq related GPIO APIs until the GPIO IRQ lock
- is released::
- void gpiochip_unlock_as_irq(struct gpio_chip *chip, unsigned int offset)
- When implementing an irqchip inside a GPIO driver, these two functions should
- typically be called in the .startup() and .shutdown() callbacks from the
- irqchip.
- When using the gpiolib irqchip helpers, these callbacks are automatically
- assigned.
- 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
- the IRQ is enabled or disabled. In order to inform gpiolib about this,
- the irqchip driver should call::
- void gpiochip_disable_irq(struct gpio_chip *chip, unsigned int offset)
- This allows drivers to drive the GPIO as an output while the IRQ is
- disabled. When the IRQ is enabled again, a driver should call::
- void gpiochip_enable_irq(struct gpio_chip *chip, unsigned int offset)
- When implementing an irqchip inside a GPIO driver, these two functions should
- typically be called in the .irq_disable() and .irq_enable() callbacks from the
- irqchip.
- When IRQCHIP_IMMUTABLE is not advertised by the irqchip, these callbacks
- are automatically assigned. This behaviour is deprecated and on its way
- to be removed from the kernel.
- Real-Time compliance for GPIO IRQ chips
- ---------------------------------------
- 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
- in mind and do the proper testing to assure they are real time-enabled.
- So, pay attention on above realtime considerations in the documentation.
- 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()
- and .irq_bus_unlock() callbacks
- - Chained GPIO irqchips: ensure spinlock_t or any sleepable APIs are not used
- from the chained IRQ handler
- - Generic chained GPIO irqchips: take care about generic_handle_irq() calls and
- apply corresponding work-around
- - Chained GPIO irqchips: get rid of the chained IRQ handler and use generic irq
- handler if possible
- - regmap_mmio: it is possible to disable internal locking in regmap by setting
- .disable_locking and handling the locking in the GPIO driver
- - Test your driver with the appropriate in-kernel real-time test cases for both
- level and edge IRQs
- * [1] http://www.spinics.net/lists/linux-omap/msg120425.html
- * [2] https://lore.kernel.org/r/[email protected]
- * [3] https://lore.kernel.org/r/[email protected]
- Requesting self-owned GPIO pins
- ===============================
- Sometimes it is useful to allow a GPIO chip driver to request its own GPIO
- descriptors through the gpiolib API. A GPIO driver can use the following
- functions to request and free descriptors::
- struct gpio_desc *gpiochip_request_own_desc(struct gpio_desc *desc,
- u16 hwnum,
- const char *label,
- enum gpiod_flags flags)
- void gpiochip_free_own_desc(struct gpio_desc *desc)
- Descriptors requested with gpiochip_request_own_desc() must be released with
- gpiochip_free_own_desc().
- 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
- calling driver.
|