Documentation: gpio: Move driver documentation to driver-api

Move gpio/driver.txt to driver-api/gpio/driver.rst and make sure it
builds cleanly as ReST.

Signed-off-by: Jonathan Neuschäfer <j.neuschaefer@gmx.net>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
This commit is contained in:
Jonathan Neuschäfer 2018-03-09 00:40:20 +01:00 committed by Linus Walleij
parent 02bf219d2f
commit 778ea833c5
3 changed files with 41 additions and 40 deletions

View File

@ -1,3 +1,4 @@
================================
GPIO Descriptor Driver Interface GPIO Descriptor Driver Interface
================================ ================================
@ -53,9 +54,9 @@ common to each controller of that type:
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, possibly 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() when Removing a GPIO controller should be rare; use ``[devm_]gpiochip_remove()``
it is unavoidable. when it is unavoidable.
Often a gpio_chip is part of an instance-specific structure with states not 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.
@ -115,7 +116,7 @@ GPIOs 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
is not open, it will present a high-impedance (tristate) to the external rail. is not open, it will present a high-impedance (tristate) to the external rail::
CMOS CONFIGURATION TTL CONFIGURATION CMOS CONFIGURATION TTL CONFIGURATION
@ -148,19 +149,19 @@ level-shift to the higher VDD.
Integrated electronics often have an output driver stage in the form of a CMOS 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 "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 the line high and one of them drives the line low. This is called a push-pull
output. The "totem-pole" looks like so: output. The "totem-pole" looks like so::
VDD VDD
| |
OD ||--+ OD ||--+
+--/ ---o|| P-MOS-FET +--/ ---o|| P-MOS-FET
| ||--+ | ||--+
IN --+ +----- out IN --+ +----- out
| ||--+ | ||--+
+--/ ----|| N-MOS-FET +--/ ----|| N-MOS-FET
OS ||--+ OS ||--+
| |
GND GND
The desired output signal (e.g. coming directly from some GPIO output register) 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 arrives at IN. The switches named "OD" and "OS" are normally closed, creating
@ -219,8 +220,9 @@ systems simultaneously: gpio and irq.
RT_FULL: a realtime compliant GPIO driver should not use spinlock_t or any RT_FULL: a realtime compliant GPIO driver should not use spinlock_t or any
sleepable APIs (like PM runtime) as part of its irq_chip implementation. sleepable APIs (like PM runtime) as part of its irq_chip 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() * 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].
@ -232,12 +234,12 @@ GPIO irqchips usually fall in one of two categories:
system interrupt controller. This means that the GPIO irqchip handler will system interrupt controller. This means that the GPIO irqchip handler will
be called immediately from the parent irqchip, while holding the IRQs be called immediately from the parent irqchip, while holding the IRQs
disabled. The GPIO irqchip will then end up calling something like this disabled. The GPIO irqchip will then end up calling something like this
sequence in its interrupt handler: sequence in its interrupt handler::
static irqreturn_t foo_gpio_irq(int irq, void *data) static irqreturn_t foo_gpio_irq(int irq, void *data)
chained_irq_enter(...); chained_irq_enter(...);
generic_handle_irq(...); generic_handle_irq(...);
chained_irq_exit(...); chained_irq_exit(...);
Chained GPIO irqchips typically can NOT set the .can_sleep flag on Chained GPIO irqchips typically can NOT set the .can_sleep flag on
struct gpio_chip, as everything happens directly in the callbacks: no struct gpio_chip, as everything happens directly in the callbacks: no
@ -252,7 +254,7 @@ GPIO irqchips usually fall in one of two categories:
(for example, see [3]). (for example, see [3]).
Know W/A: The generic_handle_irq() is expected to be called with IRQ disabled, Know W/A: 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 W/A 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)
@ -265,11 +267,11 @@ GPIO irqchips usually fall in one of two categories:
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
its interrupt handler: its interrupt handler::
static irqreturn_t gpio_rcar_irq_handler(int irq, void *dev_id) static irqreturn_t gpio_rcar_irq_handler(int irq, void *dev_id)
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 RT_FULL: Such kind of handlers will be forced threaded on -RT, as result IRQ
core will complain that generic_handle_irq() is called with IRQ enabled and core will complain that generic_handle_irq() is called with IRQ enabled and
@ -282,11 +284,11 @@ GPIO irqchips usually fall in one of two categories:
in a quick IRQ handler with IRQs disabled. Instead they need to spawn a 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 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::
static irqreturn_t foo_gpio_irq(int irq, void *data) static irqreturn_t foo_gpio_irq(int irq, void *data)
... ...
handle_nested_irq(irq); handle_nested_irq(irq);
The hallmark of threaded GPIO irqchips is that they set the .can_sleep 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 flag on struct gpio_chip to true, indicating that this chip may sleep
@ -359,12 +361,12 @@ below exists.
Locking IRQ usage 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::
int gpiochip_lock_as_irq(struct gpio_chip *chip, unsigned int offset) 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 This will prevent the use of non-irq related GPIO APIs until the GPIO IRQ lock
is released: is released::
void gpiochip_unlock_as_irq(struct gpio_chip *chip, unsigned int offset) void gpiochip_unlock_as_irq(struct gpio_chip *chip, unsigned int offset)
@ -408,7 +410,7 @@ 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. Using gpio_request() for this purpose
does not help since it pins the module to the kernel forever (it calls does not help since it pins the module to the kernel forever (it calls
try_module_get()). A GPIO driver can use the following functions instead try_module_get()). A GPIO driver can use the following functions instead
to request and free descriptors without being pinned to the kernel forever. 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,
const char *label) const char *label)
@ -422,6 +424,6 @@ 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 * [1] http://www.spinics.net/lists/linux-omap/msg120425.html
[2] https://lkml.org/lkml/2015/9/25/494 * [2] https://lkml.org/lkml/2015/9/25/494
[3] https://lkml.org/lkml/2015/9/25/495 * [3] https://lkml.org/lkml/2015/9/25/495

View File

@ -8,6 +8,7 @@ Contents:
:maxdepth: 2 :maxdepth: 2
intro intro
driver
Core Core
==== ====

View File

@ -2,8 +2,6 @@
- This file - This file
consumer.txt consumer.txt
- How to obtain and use GPIOs in a driver - How to obtain and use GPIOs in a driver
driver.txt
- How to write a GPIO driver
drivers-on-gpio.txt: drivers-on-gpio.txt:
- Drivers in other subsystems that can use GPIO to provide more - Drivers in other subsystems that can use GPIO to provide more
complex functionality. complex functionality.