forked from Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
221 lines
8.3 KiB
221 lines
8.3 KiB
.. SPDX-License-Identifier: GPL-2.0-only |
|
|
|
==================== |
|
Reset controller API |
|
==================== |
|
|
|
Introduction |
|
============ |
|
|
|
Reset controllers are central units that control the reset signals to multiple |
|
peripherals. |
|
The reset controller API is split into two parts: |
|
the `consumer driver interface <#consumer-driver-interface>`__ (`API reference |
|
<#reset-consumer-api>`__), which allows peripheral drivers to request control |
|
over their reset input signals, and the `reset controller driver interface |
|
<#reset-controller-driver-interface>`__ (`API reference |
|
<#reset-controller-driver-api>`__), which is used by drivers for reset |
|
controller devices to register their reset controls to provide them to the |
|
consumers. |
|
|
|
While some reset controller hardware units also implement system restart |
|
functionality, restart handlers are out of scope for the reset controller API. |
|
|
|
Glossary |
|
-------- |
|
|
|
The reset controller API uses these terms with a specific meaning: |
|
|
|
Reset line |
|
|
|
Physical reset line carrying a reset signal from a reset controller |
|
hardware unit to a peripheral module. |
|
|
|
Reset control |
|
|
|
Control method that determines the state of one or multiple reset lines. |
|
Most commonly this is a single bit in reset controller register space that |
|
either allows direct control over the physical state of the reset line, or |
|
is self-clearing and can be used to trigger a predetermined pulse on the |
|
reset line. |
|
In more complicated reset controls, a single trigger action can launch a |
|
carefully timed sequence of pulses on multiple reset lines. |
|
|
|
Reset controller |
|
|
|
A hardware module that provides a number of reset controls to control a |
|
number of reset lines. |
|
|
|
Reset consumer |
|
|
|
Peripheral module or external IC that is put into reset by the signal on a |
|
reset line. |
|
|
|
Consumer driver interface |
|
========================= |
|
|
|
This interface provides an API that is similar to the kernel clock framework. |
|
Consumer drivers use get and put operations to acquire and release reset |
|
controls. |
|
Functions are provided to assert and deassert the controlled reset lines, |
|
trigger reset pulses, or to query reset line status. |
|
|
|
When requesting reset controls, consumers can use symbolic names for their |
|
reset inputs, which are mapped to an actual reset control on an existing reset |
|
controller device by the core. |
|
|
|
A stub version of this API is provided when the reset controller framework is |
|
not in use in order to minimize the need to use ifdefs. |
|
|
|
Shared and exclusive resets |
|
--------------------------- |
|
|
|
The reset controller API provides either reference counted deassertion and |
|
assertion or direct, exclusive control. |
|
The distinction between shared and exclusive reset controls is made at the time |
|
the reset control is requested, either via devm_reset_control_get_shared() or |
|
via devm_reset_control_get_exclusive(). |
|
This choice determines the behavior of the API calls made with the reset |
|
control. |
|
|
|
Shared resets behave similarly to clocks in the kernel clock framework. |
|
They provide reference counted deassertion, where only the first deassert, |
|
which increments the deassertion reference count to one, and the last assert |
|
which decrements the deassertion reference count back to zero, have a physical |
|
effect on the reset line. |
|
|
|
Exclusive resets on the other hand guarantee direct control. |
|
That is, an assert causes the reset line to be asserted immediately, and a |
|
deassert causes the reset line to be deasserted immediately. |
|
|
|
Assertion and deassertion |
|
------------------------- |
|
|
|
Consumer drivers use the reset_control_assert() and reset_control_deassert() |
|
functions to assert and deassert reset lines. |
|
For shared reset controls, calls to the two functions must be balanced. |
|
|
|
Note that since multiple consumers may be using a shared reset control, there |
|
is no guarantee that calling reset_control_assert() on a shared reset control |
|
will actually cause the reset line to be asserted. |
|
Consumer drivers using shared reset controls should assume that the reset line |
|
may be kept deasserted at all times. |
|
The API only guarantees that the reset line can not be asserted as long as any |
|
consumer has requested it to be deasserted. |
|
|
|
Triggering |
|
---------- |
|
|
|
Consumer drivers use reset_control_reset() to trigger a reset pulse on a |
|
self-deasserting reset control. |
|
In general, these resets can not be shared between multiple consumers, since |
|
requesting a pulse from any consumer driver will reset all connected |
|
peripherals. |
|
|
|
The reset controller API allows requesting self-deasserting reset controls as |
|
shared, but for those only the first trigger request causes an actual pulse to |
|
be issued on the reset line. |
|
All further calls to this function have no effect until all consumers have |
|
called reset_control_rearm(). |
|
For shared reset controls, calls to the two functions must be balanced. |
|
This allows devices that only require an initial reset at any point before the |
|
driver is probed or resumed to share a pulsed reset line. |
|
|
|
Querying |
|
-------- |
|
|
|
Only some reset controllers support querying the current status of a reset |
|
line, via reset_control_status(). |
|
If supported, this function returns a positive non-zero value if the given |
|
reset line is asserted. |
|
The reset_control_status() function does not accept a |
|
`reset control array <#reset-control-arrays>`__ handle as its input parameter. |
|
|
|
Optional resets |
|
--------------- |
|
|
|
Often peripherals require a reset line on some platforms but not on others. |
|
For this, reset controls can be requested as optional using |
|
devm_reset_control_get_optional_exclusive() or |
|
devm_reset_control_get_optional_shared(). |
|
These functions return a NULL pointer instead of an error when the requested |
|
reset control is not specified in the device tree. |
|
Passing a NULL pointer to the reset_control functions causes them to return |
|
quietly without an error. |
|
|
|
Reset control arrays |
|
-------------------- |
|
|
|
Some drivers need to assert a bunch of reset lines in no particular order. |
|
devm_reset_control_array_get() returns an opaque reset control handle that can |
|
be used to assert, deassert, or trigger all specified reset controls at once. |
|
The reset control API does not guarantee the order in which the individual |
|
controls therein are handled. |
|
|
|
Reset controller driver interface |
|
================================= |
|
|
|
Drivers for reset controller modules provide the functionality necessary to |
|
assert or deassert reset signals, to trigger a reset pulse on a reset line, or |
|
to query its current state. |
|
All functions are optional. |
|
|
|
Initialization |
|
-------------- |
|
|
|
Drivers fill a struct :c:type:`reset_controller_dev` and register it with |
|
reset_controller_register() in their probe function. |
|
The actual functionality is implemented in callback functions via a struct |
|
:c:type:`reset_control_ops`. |
|
|
|
API reference |
|
============= |
|
|
|
The reset controller API is documented here in two parts: |
|
the `reset consumer API <#reset-consumer-api>`__ and the `reset controller |
|
driver API <#reset-controller-driver-api>`__. |
|
|
|
Reset consumer API |
|
------------------ |
|
|
|
Reset consumers can control a reset line using an opaque reset control handle, |
|
which can be obtained from devm_reset_control_get_exclusive() or |
|
devm_reset_control_get_shared(). |
|
Given the reset control, consumers can call reset_control_assert() and |
|
reset_control_deassert(), trigger a reset pulse using reset_control_reset(), or |
|
query the reset line status using reset_control_status(). |
|
|
|
.. kernel-doc:: include/linux/reset.h |
|
:internal: |
|
|
|
.. kernel-doc:: drivers/reset/core.c |
|
:functions: reset_control_reset |
|
reset_control_assert |
|
reset_control_deassert |
|
reset_control_status |
|
reset_control_acquire |
|
reset_control_release |
|
reset_control_rearm |
|
reset_control_put |
|
of_reset_control_get_count |
|
of_reset_control_array_get |
|
devm_reset_control_array_get |
|
reset_control_get_count |
|
|
|
Reset controller driver API |
|
--------------------------- |
|
|
|
Reset controller drivers are supposed to implement the necessary functions in |
|
a static constant structure :c:type:`reset_control_ops`, allocate and fill out |
|
a struct :c:type:`reset_controller_dev`, and register it using |
|
devm_reset_controller_register(). |
|
|
|
.. kernel-doc:: include/linux/reset-controller.h |
|
:internal: |
|
|
|
.. kernel-doc:: drivers/reset/core.c |
|
:functions: of_reset_simple_xlate |
|
reset_controller_register |
|
reset_controller_unregister |
|
devm_reset_controller_register |
|
reset_controller_add_lookup
|
|
|