mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-11 20:16:43 +07:00
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:
parent
02bf219d2f
commit
778ea833c5
@ -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
|
@ -8,6 +8,7 @@ Contents:
|
|||||||
:maxdepth: 2
|
:maxdepth: 2
|
||||||
|
|
||||||
intro
|
intro
|
||||||
|
driver
|
||||||
|
|
||||||
Core
|
Core
|
||||||
====
|
====
|
||||||
|
@ -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.
|
||||||
|
Loading…
Reference in New Issue
Block a user