222 lines
		
	
	
		
			8.3 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
	
	
			
		
		
	
	
			222 lines
		
	
	
		
			8.3 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
	
	
| .. 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
 |