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