| .. 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 |