219 lines · 8.2 KB · Text
RawDownload
.. SPDX-License-Identifier: GPL-2.0-only ====================Reset controller API==================== Introduction============ Reset controllers are central units that control the reset signals to multipleperipherals.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 controlover 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 resetcontroller devices to register their reset controls to provide them to theconsumers. While some reset controller hardware units also implement system restartfunctionality, 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 resetcontrols.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 theirreset inputs, which are mapped to an actual reset control on an existing resetcontroller device by the core. A stub version of this API is provided when the reset controller framework isnot in use in order to minimize the need to use ifdefs. Shared and exclusive resets--------------------------- The reset controller API provides either reference counted deassertion andassertion or direct, exclusive control.The distinction between shared and exclusive reset controls is made at the timethe reset control is requested, either via devm_reset_control_get_shared() orvia devm_reset_control_get_exclusive().This choice determines the behavior of the API calls made with the resetcontrol. 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 assertwhich decrements the deassertion reference count back to zero, have a physicaleffect 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 adeassert 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, thereis no guarantee that calling reset_control_assert() on a shared reset controlwill actually cause the reset line to be asserted.Consumer drivers using shared reset controls should assume that the reset linemay be kept deasserted at all times.The API only guarantees that the reset line can not be asserted as long as anyconsumer has requested it to be deasserted. Triggering---------- Consumer drivers use reset_control_reset() to trigger a reset pulse on aself-deasserting reset control.In general, these resets can not be shared between multiple consumers, sincerequesting a pulse from any consumer driver will reset all connectedperipherals. The reset controller API allows requesting self-deasserting reset controls asshared, but for those only the first trigger request causes an actual pulse tobe issued on the reset line.All further calls to this function have no effect until all consumers havecalled 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 thedriver is probed or resumed to share a pulsed reset line. Querying-------- Only some reset controllers support querying the current status of a resetline, via reset_control_status().If supported, this function returns a positive non-zero value if the givenreset 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 usingdevm_reset_control_get_optional_exclusive() ordevm_reset_control_get_optional_shared().These functions return a NULL pointer instead of an error when the requestedreset control is not specified in the device tree.Passing a NULL pointer to the reset_control functions causes them to returnquietly 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 canbe used to assert, deassert, or trigger all specified reset controls at once.The reset control API does not guarantee the order in which the individualcontrols therein are handled. Reset controller driver interface================================= Drivers for reset controller modules provide the functionality necessary toassert or deassert reset signals, to trigger a reset pulse on a reset line, orto query its current state.All functions are optional. Initialization-------------- Drivers fill a struct :c:type:`reset_controller_dev` and register it withreset_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 controllerdriver 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() ordevm_reset_control_get_shared().Given the reset control, consumers can call reset_control_assert() andreset_control_deassert(), trigger a reset pulse using reset_control_reset(), orquery 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               devm_reset_control_array_get               reset_control_get_count Reset controller driver API--------------------------- Reset controller drivers are supposed to implement the necessary functions ina static constant structure :c:type:`reset_control_ops`, allocate and fill outa struct :c:type:`reset_controller_dev`, and register it usingdevm_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