diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-18 17:39:57 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-18 17:39:57 +0000 |
commit | dc50eab76b709d68175a358d6e23a5a3890764d3 (patch) | |
tree | c754d0390db060af0213ff994f0ac310e4cfd6e9 /Documentation/driver-api | |
parent | Adding debian version 6.6.15-2. (diff) | |
download | linux-dc50eab76b709d68175a358d6e23a5a3890764d3.tar.xz linux-dc50eab76b709d68175a358d6e23a5a3890764d3.zip |
Merging upstream version 6.7.7.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'Documentation/driver-api')
-rw-r--r-- | Documentation/driver-api/80211/mac80211.rst | 2 | ||||
-rw-r--r-- | Documentation/driver-api/dma-buf.rst | 32 | ||||
-rw-r--r-- | Documentation/driver-api/dpll.rst | 551 | ||||
-rw-r--r-- | Documentation/driver-api/driver-model/devres.rst | 14 | ||||
-rw-r--r-- | Documentation/driver-api/gpio/consumer.rst | 4 | ||||
-rw-r--r-- | Documentation/driver-api/i3c/protocol.rst | 4 | ||||
-rw-r--r-- | Documentation/driver-api/index.rst | 1 | ||||
-rw-r--r-- | Documentation/driver-api/media/camera-sensor.rst | 192 | ||||
-rw-r--r-- | Documentation/driver-api/media/drivers/ccs/ccs.rst | 10 | ||||
-rw-r--r-- | Documentation/driver-api/media/v4l2-core.rst | 1 | ||||
-rw-r--r-- | Documentation/driver-api/media/v4l2-dev.rst | 8 | ||||
-rw-r--r-- | Documentation/driver-api/media/v4l2-videobuf.rst | 403 | ||||
-rw-r--r-- | Documentation/driver-api/pps.rst | 16 | ||||
-rw-r--r-- | Documentation/driver-api/pwm.rst | 6 | ||||
-rw-r--r-- | Documentation/driver-api/thermal/intel_dptf.rst | 64 | ||||
-rw-r--r-- | Documentation/driver-api/tty/index.rst | 1 | ||||
-rw-r--r-- | Documentation/driver-api/tty/tty_ioctl.rst | 10 | ||||
-rw-r--r-- | Documentation/driver-api/usb/dma.rst | 48 |
18 files changed, 784 insertions, 583 deletions
diff --git a/Documentation/driver-api/80211/mac80211.rst b/Documentation/driver-api/80211/mac80211.rst index 67d2e58b45..e38a220401 100644 --- a/Documentation/driver-api/80211/mac80211.rst +++ b/Documentation/driver-api/80211/mac80211.rst @@ -120,7 +120,7 @@ functions/definitions ieee80211_rx ieee80211_rx_ni ieee80211_rx_irqsafe - ieee80211_tx_status + ieee80211_tx_status_skb ieee80211_tx_status_ni ieee80211_tx_status_irqsafe ieee80211_rts_get diff --git a/Documentation/driver-api/dma-buf.rst b/Documentation/driver-api/dma-buf.rst index f92a32d095..0c153d79cc 100644 --- a/Documentation/driver-api/dma-buf.rst +++ b/Documentation/driver-api/dma-buf.rst @@ -5,14 +5,30 @@ The dma-buf subsystem provides the framework for sharing buffers for hardware (DMA) access across multiple device drivers and subsystems, and for synchronizing asynchronous hardware access. -This is used, for example, by drm "prime" multi-GPU support, but is of -course not limited to GPU use cases. - -The three main components of this are: (1) dma-buf, representing a -sg_table and exposed to userspace as a file descriptor to allow passing -between devices, (2) fence, which provides a mechanism to signal when -one device has finished access, and (3) reservation, which manages the -shared or exclusive fence(s) associated with the buffer. +As an example, it is used extensively by the DRM subsystem to exchange +buffers between processes, contexts, library APIs within the same +process, and also to exchange buffers with other subsystems such as +V4L2. + +This document describes the way in which kernel subsystems can use and +interact with the three main primitives offered by dma-buf: + + - dma-buf, representing a sg_table and exposed to userspace as a file + descriptor to allow passing between processes, subsystems, devices, + etc; + - dma-fence, providing a mechanism to signal when an asynchronous + hardware operation has completed; and + - dma-resv, which manages a set of dma-fences for a particular dma-buf + allowing implicit (kernel-ordered) synchronization of work to + preserve the illusion of coherent access + + +Userspace API principles and use +-------------------------------- + +For more details on how to design your subsystem's API for dma-buf use, please +see Documentation/userspace-api/dma-buf-alloc-exchange.rst. + Shared DMA Buffers ------------------ diff --git a/Documentation/driver-api/dpll.rst b/Documentation/driver-api/dpll.rst new file mode 100644 index 0000000000..e3d593841a --- /dev/null +++ b/Documentation/driver-api/dpll.rst @@ -0,0 +1,551 @@ +.. SPDX-License-Identifier: GPL-2.0 + +=============================== +The Linux kernel dpll subsystem +=============================== + +DPLL +==== + +PLL - Phase Locked Loop is an electronic circuit which syntonizes clock +signal of a device with an external clock signal. Effectively enabling +device to run on the same clock signal beat as provided on a PLL input. + +DPLL - Digital Phase Locked Loop is an integrated circuit which in +addition to plain PLL behavior incorporates a digital phase detector +and may have digital divider in the loop. As a result, the frequency on +DPLL's input and output may be configurable. + +Subsystem +========= + +The main purpose of dpll subsystem is to provide general interface +to configure devices that use any kind of Digital PLL and could use +different sources of input signal to synchronize to, as well as +different types of outputs. +The main interface is NETLINK_GENERIC based protocol with an event +monitoring multicast group defined. + +Device object +============= + +Single dpll device object means single Digital PLL circuit and bunch of +connected pins. +It reports the supported modes of operation and current status to the +user in response to the `do` request of netlink command +``DPLL_CMD_DEVICE_GET`` and list of dplls registered in the subsystem +with `dump` netlink request of the same command. +Changing the configuration of dpll device is done with `do` request of +netlink ``DPLL_CMD_DEVICE_SET`` command. +A device handle is ``DPLL_A_ID``, it shall be provided to get or set +configuration of particular device in the system. It can be obtained +with a ``DPLL_CMD_DEVICE_GET`` `dump` request or +a ``DPLL_CMD_DEVICE_ID_GET`` `do` request, where the one must provide +attributes that result in single device match. + +Pin object +========== + +A pin is amorphic object which represents either input or output, it +could be internal component of the device, as well as externally +connected. +The number of pins per dpll vary, but usually multiple pins shall be +provided for a single dpll device. +Pin's properties, capabilities and status is provided to the user in +response to `do` request of netlink ``DPLL_CMD_PIN_GET`` command. +It is also possible to list all the pins that were registered in the +system with `dump` request of ``DPLL_CMD_PIN_GET`` command. +Configuration of a pin can be changed by `do` request of netlink +``DPLL_CMD_PIN_SET`` command. +Pin handle is a ``DPLL_A_PIN_ID``, it shall be provided to get or set +configuration of particular pin in the system. It can be obtained with +``DPLL_CMD_PIN_GET`` `dump` request or ``DPLL_CMD_PIN_ID_GET`` `do` +request, where user provides attributes that result in single pin match. + +Pin selection +============= + +In general, selected pin (the one which signal is driving the dpll +device) can be obtained from ``DPLL_A_PIN_STATE`` attribute, and only +one pin shall be in ``DPLL_PIN_STATE_CONNECTED`` state for any dpll +device. + +Pin selection can be done either manually or automatically, depending +on hardware capabilities and active dpll device work mode +(``DPLL_A_MODE`` attribute). The consequence is that there are +differences for each mode in terms of available pin states, as well as +for the states the user can request for a dpll device. + +In manual mode (``DPLL_MODE_MANUAL``) the user can request or receive +one of following pin states: + +- ``DPLL_PIN_STATE_CONNECTED`` - the pin is used to drive dpll device +- ``DPLL_PIN_STATE_DISCONNECTED`` - the pin is not used to drive dpll + device + +In automatic mode (``DPLL_MODE_AUTOMATIC``) the user can request or +receive one of following pin states: + +- ``DPLL_PIN_STATE_SELECTABLE`` - the pin shall be considered as valid + input for automatic selection algorithm +- ``DPLL_PIN_STATE_DISCONNECTED`` - the pin shall be not considered as + a valid input for automatic selection algorithm + +In automatic mode (``DPLL_MODE_AUTOMATIC``) the user can only receive +pin state ``DPLL_PIN_STATE_CONNECTED`` once automatic selection +algorithm locks a dpll device with one of the inputs. + +Shared pins +=========== + +A single pin object can be attached to multiple dpll devices. +Then there are two groups of configuration knobs: + +1) Set on a pin - the configuration affects all dpll devices pin is + registered to (i.e., ``DPLL_A_PIN_FREQUENCY``), +2) Set on a pin-dpll tuple - the configuration affects only selected + dpll device (i.e., ``DPLL_A_PIN_PRIO``, ``DPLL_A_PIN_STATE``, + ``DPLL_A_PIN_DIRECTION``). + +MUX-type pins +============= + +A pin can be MUX-type, it aggregates child pins and serves as a pin +multiplexer. One or more pins are registered with MUX-type instead of +being directly registered to a dpll device. +Pins registered with a MUX-type pin provide user with additional nested +attribute ``DPLL_A_PIN_PARENT_PIN`` for each parent they were registered +with. +If a pin was registered with multiple parent pins, they behave like a +multiple output multiplexer. In this case output of a +``DPLL_CMD_PIN_GET`` would contain multiple pin-parent nested +attributes with current state related to each parent, like:: + + 'pin': [{{ + 'clock-id': 282574471561216, + 'module-name': 'ice', + 'capabilities': 4, + 'id': 13, + 'parent-pin': [ + {'parent-id': 2, 'state': 'connected'}, + {'parent-id': 3, 'state': 'disconnected'} + ], + 'type': 'synce-eth-port' + }}] + +Only one child pin can provide its signal to the parent MUX-type pin at +a time, the selection is done by requesting change of a child pin state +on desired parent, with the use of ``DPLL_A_PIN_PARENT`` nested +attribute. Example of netlink `set state on parent pin` message format: + + ========================== ============================================= + ``DPLL_A_PIN_ID`` child pin id + ``DPLL_A_PIN_PARENT_PIN`` nested attribute for requesting configuration + related to parent pin + ``DPLL_A_PIN_PARENT_ID`` parent pin id + ``DPLL_A_PIN_STATE`` requested pin state on parent + ========================== ============================================= + +Pin priority +============ + +Some devices might offer a capability of automatic pin selection mode +(enum value ``DPLL_MODE_AUTOMATIC`` of ``DPLL_A_MODE`` attribute). +Usually, automatic selection is performed on the hardware level, which +means only pins directly connected to the dpll can be used for automatic +input pin selection. +In automatic selection mode, the user cannot manually select a input +pin for the device, instead the user shall provide all directly +connected pins with a priority ``DPLL_A_PIN_PRIO``, the device would +pick a highest priority valid signal and use it to control the DPLL +device. Example of netlink `set priority on parent pin` message format: + + ============================ ============================================= + ``DPLL_A_PIN_ID`` configured pin id + ``DPLL_A_PIN_PARENT_DEVICE`` nested attribute for requesting configuration + related to parent dpll device + ``DPLL_A_PIN_PARENT_ID`` parent dpll device id + ``DPLL_A_PIN_PRIO`` requested pin prio on parent dpll + ============================ ============================================= + +Child pin of MUX-type pin is not capable of automatic input pin selection, +in order to configure active input of a MUX-type pin, the user needs to +request desired pin state of the child pin on the parent pin, +as described in the ``MUX-type pins`` chapter. + +Phase offset measurement and adjustment +======================================== + +Device may provide ability to measure a phase difference between signals +on a pin and its parent dpll device. If pin-dpll phase offset measurement +is supported, it shall be provided with ``DPLL_A_PIN_PHASE_OFFSET`` +attribute for each parent dpll device. + +Device may also provide ability to adjust a signal phase on a pin. +If pin phase adjustment is supported, minimal and maximal values that pin +handle shall be provide to the user on ``DPLL_CMD_PIN_GET`` respond +with ``DPLL_A_PIN_PHASE_ADJUST_MIN`` and ``DPLL_A_PIN_PHASE_ADJUST_MAX`` +attributes. Configured phase adjust value is provided with +``DPLL_A_PIN_PHASE_ADJUST`` attribute of a pin, and value change can be +requested with the same attribute with ``DPLL_CMD_PIN_SET`` command. + + =============================== ====================================== + ``DPLL_A_PIN_ID`` configured pin id + ``DPLL_A_PIN_PHASE_ADJUST_MIN`` attr minimum value of phase adjustment + ``DPLL_A_PIN_PHASE_ADJUST_MAX`` attr maximum value of phase adjustment + ``DPLL_A_PIN_PHASE_ADJUST`` attr configured value of phase + adjustment on parent dpll device + ``DPLL_A_PIN_PARENT_DEVICE`` nested attribute for requesting + configuration on given parent dpll + device + ``DPLL_A_PIN_PARENT_ID`` parent dpll device id + ``DPLL_A_PIN_PHASE_OFFSET`` attr measured phase difference + between a pin and parent dpll device + =============================== ====================================== + +All phase related values are provided in pico seconds, which represents +time difference between signals phase. The negative value means that +phase of signal on pin is earlier in time than dpll's signal. Positive +value means that phase of signal on pin is later in time than signal of +a dpll. + +Phase adjust (also min and max) values are integers, but measured phase +offset values are fractional with 3-digit decimal places and shell be +divided with ``DPLL_PIN_PHASE_OFFSET_DIVIDER`` to get integer part and +modulo divided to get fractional part. + +Configuration commands group +============================ + +Configuration commands are used to get information about registered +dpll devices (and pins), as well as set configuration of device or pins. +As dpll devices must be abstracted and reflect real hardware, +there is no way to add new dpll device via netlink from user space and +each device should be registered by its driver. + +All netlink commands require ``GENL_ADMIN_PERM``. This is to prevent +any spamming/DoS from unauthorized userspace applications. + +List of netlink commands with possible attributes +================================================= + +Constants identifying command types for dpll device uses a +``DPLL_CMD_`` prefix and suffix according to command purpose. +The dpll device related attributes use a ``DPLL_A_`` prefix and +suffix according to attribute purpose. + + ==================================== ================================= + ``DPLL_CMD_DEVICE_ID_GET`` command to get device ID + ``DPLL_A_MODULE_NAME`` attr module name of registerer + ``DPLL_A_CLOCK_ID`` attr Unique Clock Identifier + (EUI-64), as defined by the + IEEE 1588 standard + ``DPLL_A_TYPE`` attr type of dpll device + ==================================== ================================= + + ==================================== ================================= + ``DPLL_CMD_DEVICE_GET`` command to get device info or + dump list of available devices + ``DPLL_A_ID`` attr unique dpll device ID + ``DPLL_A_MODULE_NAME`` attr module name of registerer + ``DPLL_A_CLOCK_ID`` attr Unique Clock Identifier + (EUI-64), as defined by the + IEEE 1588 standard + ``DPLL_A_MODE`` attr selection mode + ``DPLL_A_MODE_SUPPORTED`` attr available selection modes + ``DPLL_A_LOCK_STATUS`` attr dpll device lock status + ``DPLL_A_TEMP`` attr device temperature info + ``DPLL_A_TYPE`` attr type of dpll device + ==================================== ================================= + + ==================================== ================================= + ``DPLL_CMD_DEVICE_SET`` command to set dpll device config + ``DPLL_A_ID`` attr internal dpll device index + ``DPLL_A_MODE`` attr selection mode to configure + ==================================== ================================= + +Constants identifying command types for pins uses a +``DPLL_CMD_PIN_`` prefix and suffix according to command purpose. +The pin related attributes use a ``DPLL_A_PIN_`` prefix and suffix +according to attribute purpose. + + ==================================== ================================= + ``DPLL_CMD_PIN_ID_GET`` command to get pin ID + ``DPLL_A_PIN_MODULE_NAME`` attr module name of registerer + ``DPLL_A_PIN_CLOCK_ID`` attr Unique Clock Identifier + (EUI-64), as defined by the + IEEE 1588 standard + ``DPLL_A_PIN_BOARD_LABEL`` attr pin board label provided + by registerer + ``DPLL_A_PIN_PANEL_LABEL`` attr pin panel label provided + by registerer + ``DPLL_A_PIN_PACKAGE_LABEL`` attr pin package label provided + by registerer + ``DPLL_A_PIN_TYPE`` attr type of a pin + ==================================== ================================= + + ==================================== ================================== + ``DPLL_CMD_PIN_GET`` command to get pin info or dump + list of available pins + ``DPLL_A_PIN_ID`` attr unique a pin ID + ``DPLL_A_PIN_MODULE_NAME`` attr module name of registerer + ``DPLL_A_PIN_CLOCK_ID`` attr Unique Clock Identifier + (EUI-64), as defined by the + IEEE 1588 standard + ``DPLL_A_PIN_BOARD_LABEL`` attr pin board label provided + by registerer + ``DPLL_A_PIN_PANEL_LABEL`` attr pin panel label provided + by registerer + ``DPLL_A_PIN_PACKAGE_LABEL`` attr pin package label provided + by registerer + ``DPLL_A_PIN_TYPE`` attr type of a pin + ``DPLL_A_PIN_FREQUENCY`` attr current frequency of a pin + ``DPLL_A_PIN_FREQUENCY_SUPPORTED`` nested attr provides supported + frequencies + ``DPLL_A_PIN_ANY_FREQUENCY_MIN`` attr minimum value of frequency + ``DPLL_A_PIN_ANY_FREQUENCY_MAX`` attr maximum value of frequency + ``DPLL_A_PIN_PHASE_ADJUST_MIN`` attr minimum value of phase + adjustment + ``DPLL_A_PIN_PHASE_ADJUST_MAX`` attr maximum value of phase + adjustment + ``DPLL_A_PIN_PHASE_ADJUST`` attr configured value of phase + adjustment on parent device + ``DPLL_A_PIN_PARENT_DEVICE`` nested attr for each parent device + the pin is connected with + ``DPLL_A_PIN_PARENT_ID`` attr parent dpll device id + ``DPLL_A_PIN_PRIO`` attr priority of pin on the + dpll device + ``DPLL_A_PIN_STATE`` attr state of pin on the parent + dpll device + ``DPLL_A_PIN_DIRECTION`` attr direction of a pin on the + parent dpll device + ``DPLL_A_PIN_PHASE_OFFSET`` attr measured phase difference + between a pin and parent dpll + ``DPLL_A_PIN_PARENT_PIN`` nested attr for each parent pin + the pin is connected with + ``DPLL_A_PIN_PARENT_ID`` attr parent pin id + ``DPLL_A_PIN_STATE`` attr state of pin on the parent + pin + ``DPLL_A_PIN_CAPABILITIES`` attr bitmask of pin capabilities + ==================================== ================================== + + ==================================== ================================= + ``DPLL_CMD_PIN_SET`` command to set pins configuration + ``DPLL_A_PIN_ID`` attr unique a pin ID + ``DPLL_A_PIN_FREQUENCY`` attr requested frequency of a pin + ``DPLL_A_PIN_PHASE_ADJUST`` attr requested value of phase + adjustment on parent device + ``DPLL_A_PIN_PARENT_DEVICE`` nested attr for each parent dpll + device configuration request + ``DPLL_A_PIN_PARENT_ID`` attr parent dpll device id + ``DPLL_A_PIN_DIRECTION`` attr requested direction of a pin + ``DPLL_A_PIN_PRIO`` attr requested priority of pin on + the dpll device + ``DPLL_A_PIN_STATE`` attr requested state of pin on + the dpll device + ``DPLL_A_PIN_PARENT_PIN`` nested attr for each parent pin + configuration request + ``DPLL_A_PIN_PARENT_ID`` attr parent pin id + ``DPLL_A_PIN_STATE`` attr requested state of pin on + parent pin + ==================================== ================================= + +Netlink dump requests +===================== + +The ``DPLL_CMD_DEVICE_GET`` and ``DPLL_CMD_PIN_GET`` commands are +capable of dump type netlink requests, in which case the response is in +the same format as for their ``do`` request, but every device or pin +registered in the system is returned. + +SET commands format +=================== + +``DPLL_CMD_DEVICE_SET`` - to target a dpll device, the user provides +``DPLL_A_ID``, which is unique identifier of dpll device in the system, +as well as parameter being configured (``DPLL_A_MODE``). + +``DPLL_CMD_PIN_SET`` - to target a pin user must provide a +``DPLL_A_PIN_ID``, which is unique identifier of a pin in the system. +Also configured pin parameters must be added. +If ``DPLL_A_PIN_FREQUENCY`` is configured, this affects all the dpll +devices that are connected with the pin, that is why frequency attribute +shall not be enclosed in ``DPLL_A_PIN_PARENT_DEVICE``. +Other attributes: ``DPLL_A_PIN_PRIO``, ``DPLL_A_PIN_STATE`` or +``DPLL_A_PIN_DIRECTION`` must be enclosed in +``DPLL_A_PIN_PARENT_DEVICE`` as their configuration relates to only one +of parent dplls, targeted by ``DPLL_A_PIN_PARENT_ID`` attribute which is +also required inside that nest. +For MUX-type pins the ``DPLL_A_PIN_STATE`` attribute is configured in +similar way, by enclosing required state in ``DPLL_A_PIN_PARENT_PIN`` +nested attribute and targeted parent pin id in ``DPLL_A_PIN_PARENT_ID``. + +In general, it is possible to configure multiple parameters at once, but +internally each parameter change will be invoked separately, where order +of configuration is not guaranteed by any means. + +Configuration pre-defined enums +=============================== + +.. kernel-doc:: include/uapi/linux/dpll.h + +Notifications +============= + +dpll device can provide notifications regarding status changes of the +device, i.e. lock status changes, input/output changes or other alarms. +There is one multicast group that is used to notify user-space apps via +netlink socket: ``DPLL_MCGRP_MONITOR`` + +Notifications messages: + + ============================== ===================================== + ``DPLL_CMD_DEVICE_CREATE_NTF`` dpll device was created + ``DPLL_CMD_DEVICE_DELETE_NTF`` dpll device was deleted + ``DPLL_CMD_DEVICE_CHANGE_NTF`` dpll device has changed + ``DPLL_CMD_PIN_CREATE_NTF`` dpll pin was created + ``DPLL_CMD_PIN_DELETE_NTF`` dpll pin was deleted + ``DPLL_CMD_PIN_CHANGE_NTF`` dpll pin has changed + ============================== ===================================== + +Events format is the same as for the corresponding get command. +Format of ``DPLL_CMD_DEVICE_`` events is the same as response of +``DPLL_CMD_DEVICE_GET``. +Format of ``DPLL_CMD_PIN_`` events is same as response of +``DPLL_CMD_PIN_GET``. + +Device driver implementation +============================ + +Device is allocated by dpll_device_get() call. Second call with the +same arguments will not create new object but provides pointer to +previously created device for given arguments, it also increases +refcount of that object. +Device is deallocated by dpll_device_put() call, which first +decreases the refcount, once refcount is cleared the object is +destroyed. + +Device should implement set of operations and register device via +dpll_device_register() at which point it becomes available to the +users. Multiple driver instances can obtain reference to it with +dpll_device_get(), as well as register dpll device with their own +ops and priv. + +The pins are allocated separately with dpll_pin_get(), it works +similarly to dpll_device_get(). Function first creates object and then +for each call with the same arguments only the object refcount +increases. Also dpll_pin_put() works similarly to dpll_device_put(). + +A pin can be registered with parent dpll device or parent pin, depending +on hardware needs. Each registration requires registerer to provide set +of pin callbacks, and private data pointer for calling them: + +- dpll_pin_register() - register pin with a dpll device, +- dpll_pin_on_pin_register() - register pin with another MUX type pin. + +Notifications of adding or removing dpll devices are created within +subsystem itself. +Notifications about registering/deregistering pins are also invoked by +the subsystem. +Notifications about status changes either of dpll device or a pin are +invoked in two ways: + +- after successful change was requested on dpll subsystem, the subsystem + calls corresponding notification, +- requested by device driver with dpll_device_change_ntf() or + dpll_pin_change_ntf() when driver informs about the status change. + +The device driver using dpll interface is not required to implement all +the callback operation. Nevertheless, there are few required to be +implemented. +Required dpll device level callback operations: + +- ``.mode_get``, +- ``.lock_status_get``. + +Required pin level callback operations: + +- ``.state_on_dpll_get`` (pins registered with dpll device), +- ``.state_on_pin_get`` (pins registered with parent pin), +- ``.direction_get``. + +Every other operation handler is checked for existence and +``-EOPNOTSUPP`` is returned in case of absence of specific handler. + +The simplest implementation is in the OCP TimeCard driver. The ops +structures are defined like this: + +.. code-block:: c + + static const struct dpll_device_ops dpll_ops = { + .lock_status_get = ptp_ocp_dpll_lock_status_get, + .mode_get = ptp_ocp_dpll_mode_get, + .mode_supported = ptp_ocp_dpll_mode_supported, + }; + + static const struct dpll_pin_ops dpll_pins_ops = { + .frequency_get = ptp_ocp_dpll_frequency_get, + .frequency_set = ptp_ocp_dpll_frequency_set, + .direction_get = ptp_ocp_dpll_direction_get, + .direction_set = ptp_ocp_dpll_direction_set, + .state_on_dpll_get = ptp_ocp_dpll_state_get, + }; + +The registration part is then looks like this part: + +.. code-block:: c + + clkid = pci_get_dsn(pdev); + bp->dpll = dpll_device_get(clkid, 0, THIS_MODULE); + if (IS_ERR(bp->dpll)) { + err = PTR_ERR(bp->dpll); + dev_err(&pdev->dev, "dpll_device_alloc failed\n"); + goto out; + } + + err = dpll_device_register(bp->dpll, DPLL_TYPE_PPS, &dpll_ops, bp); + if (err) + goto out; + + for (i = 0; i < OCP_SMA_NUM; i++) { + bp->sma[i].dpll_pin = dpll_pin_get(clkid, i, THIS_MODULE, &bp->sma[i].dpll_prop); + if (IS_ERR(bp->sma[i].dpll_pin)) { + err = PTR_ERR(bp->dpll); + goto out_dpll; + } + + err = dpll_pin_register(bp->dpll, bp->sma[i].dpll_pin, &dpll_pins_ops, + &bp->sma[i]); + if (err) { + dpll_pin_put(bp->sma[i].dpll_pin); + goto out_dpll; + } + } + +In the error path we have to rewind every allocation in the reverse order: + +.. code-block:: c + + while (i) { + --i; + dpll_pin_unregister(bp->dpll, bp->sma[i].dpll_pin, &dpll_pins_ops, &bp->sma[i]); + dpll_pin_put(bp->sma[i].dpll_pin); + } + dpll_device_put(bp->dpll); + +More complex example can be found in Intel's ICE driver or nVidia's mlx5 driver. + +SyncE enablement +================ +For SyncE enablement it is required to allow control over dpll device +for a software application which monitors and configures the inputs of +dpll device in response to current state of a dpll device and its +inputs. +In such scenario, dpll device input signal shall be also configurable +to drive dpll with signal recovered from the PHY netdevice. +This is done by exposing a pin to the netdevice - attaching pin to the +netdevice itself with +``netdev_dpll_pin_set(struct net_device *dev, struct dpll_pin *dpll_pin)``. +Exposed pin id handle ``DPLL_A_PIN_ID`` is then identifiable by the user +as it is attached to rtnetlink respond to get ``RTM_NEWLINK`` command in +nested attribute ``IFLA_DPLL_PIN``. diff --git a/Documentation/driver-api/driver-model/devres.rst b/Documentation/driver-api/driver-model/devres.rst index 8be086b3f8..c5f99d834e 100644 --- a/Documentation/driver-api/driver-model/devres.rst +++ b/Documentation/driver-api/driver-model/devres.rst @@ -322,10 +322,8 @@ IOMAP devm_platform_ioremap_resource_byname() devm_platform_get_and_ioremap_resource() devm_iounmap() - pcim_iomap() - pcim_iomap_regions() : do request_region() and iomap() on multiple BARs - pcim_iomap_table() : array of mapped addresses indexed by BAR - pcim_iounmap() + + Note: For the PCI devices the specific pcim_*() functions may be used, see below. IRQ devm_free_irq() @@ -392,8 +390,16 @@ PCI devm_pci_alloc_host_bridge() : managed PCI host bridge allocation devm_pci_remap_cfgspace() : ioremap PCI configuration space devm_pci_remap_cfg_resource() : ioremap PCI configuration space resource + pcim_enable_device() : after success, all PCI ops become managed + pcim_iomap() : do iomap() on a single BAR + pcim_iomap_regions() : do request_region() and iomap() on multiple BARs + pcim_iomap_regions_request_all() : do request_region() on all and iomap() on multiple BARs + pcim_iomap_table() : array of mapped addresses indexed by BAR + pcim_iounmap() : do iounmap() on a single BAR + pcim_iounmap_regions() : do iounmap() and release_region() on multiple BARs pcim_pin_device() : keep PCI device enabled after release + pcim_set_mwi() : enable Memory-Write-Invalidate PCI transaction PHY devm_usb_get_phy() diff --git a/Documentation/driver-api/gpio/consumer.rst b/Documentation/driver-api/gpio/consumer.rst index de6fc79ad6..3e588b9d67 100644 --- a/Documentation/driver-api/gpio/consumer.rst +++ b/Documentation/driver-api/gpio/consumer.rst @@ -29,6 +29,10 @@ warnings. These stubs are used for two use cases: will use it under other compile-time configurations. In this case the consumer must make sure not to call into these functions, or the user will be met with console warnings that may be perceived as intimidating. + Combining truly optional GPIOLIB usage with calls to + ``[devm_]gpiod_get_optional()`` is a *bad idea*, and will result in weird + error messages. Use the ordinary getter functions with optional GPIOLIB: + some open coding of error handling should be expected when you do this. All the functions that work with the descriptor-based GPIO interface are prefixed with ``gpiod_``. The ``gpio_`` prefix is used for the legacy diff --git a/Documentation/driver-api/i3c/protocol.rst b/Documentation/driver-api/i3c/protocol.rst index 02653defa0..23a0b93c62 100644 --- a/Documentation/driver-api/i3c/protocol.rst +++ b/Documentation/driver-api/i3c/protocol.rst @@ -71,8 +71,8 @@ During DAA, each I3C device reports 3 important things: related capabilities * DCR: Device Characteristic Register. This 8-bit register describes the functionalities provided by the device -* Provisional ID: A 48-bit unique identifier. On a given bus there should be no - Provisional ID collision, otherwise the discovery mechanism may fail. +* Provisioned ID: A 48-bit unique identifier. On a given bus there should be no + Provisioned ID collision, otherwise the discovery mechanism may fail. I3C slave events ================ diff --git a/Documentation/driver-api/index.rst b/Documentation/driver-api/index.rst index 1e16a40da3..f549a68951 100644 --- a/Documentation/driver-api/index.rst +++ b/Documentation/driver-api/index.rst @@ -114,6 +114,7 @@ available subsections can be seen below. zorro hte/index wmi + dpll .. only:: subproject and html diff --git a/Documentation/driver-api/media/camera-sensor.rst b/Documentation/driver-api/media/camera-sensor.rst index 93f4f2536c..6456145f96 100644 --- a/Documentation/driver-api/media/camera-sensor.rst +++ b/Documentation/driver-api/media/camera-sensor.rst @@ -1,8 +1,14 @@ .. SPDX-License-Identifier: GPL-2.0 +.. _media_writing_camera_sensor_drivers: + Writing camera sensor drivers ============================= +This document covers the in-kernel APIs only. For the best practices on +userspace API implementation in camera sensor drivers, please see +:ref:`media_using_camera_sensor_drivers`. + CSI-2 and parallel (BT.601 and BT.656) busses --------------------------------------------- @@ -13,7 +19,7 @@ Handling clocks Camera sensors have an internal clock tree including a PLL and a number of divisors. The clock tree is generally configured by the driver based on a few -input parameters that are specific to the hardware:: the external clock frequency +input parameters that are specific to the hardware: the external clock frequency and the link frequency. The two parameters generally are obtained from system firmware. **No other frequencies should be used in any circumstances.** @@ -32,110 +38,61 @@ can rely on this frequency being used. Devicetree ~~~~~~~~~~ -The currently preferred way to achieve this is using ``assigned-clocks``, -``assigned-clock-parents`` and ``assigned-clock-rates`` properties. See -``Documentation/devicetree/bindings/clock/clock-bindings.txt`` for more -information. The driver then gets the frequency using ``clk_get_rate()``. +The preferred way to achieve this is using ``assigned-clocks``, +``assigned-clock-parents`` and ``assigned-clock-rates`` properties. See the +`clock device tree bindings +<https://github.com/devicetree-org/dt-schema/blob/main/dtschema/schemas/clock/clock.yaml>`_ +for more information. The driver then gets the frequency using +``clk_get_rate()``. This approach has the drawback that there's no guarantee that the frequency hasn't been modified directly or indirectly by another driver, or supported by the board's clock tree to begin with. Changes to the Common Clock Framework API are required to ensure reliability. -Frame size ----------- - -There are two distinct ways to configure the frame size produced by camera -sensors. - -Freely configurable camera sensor drivers -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Freely configurable camera sensor drivers expose the device's internal -processing pipeline as one or more sub-devices with different cropping and -scaling configurations. The output size of the device is the result of a series -of cropping and scaling operations from the device's pixel array's size. - -An example of such a driver is the CCS driver (see ``drivers/media/i2c/ccs``). - -Register list based drivers -~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Register list based drivers generally, instead of able to configure the device -they control based on user requests, are limited to a number of preset -configurations that combine a number of different parameters that on hardware -level are independent. How a driver picks such configuration is based on the -format set on a source pad at the end of the device's internal pipeline. - -Most sensor drivers are implemented this way, see e.g. -``drivers/media/i2c/imx319.c`` for an example. - -Frame interval configuration ----------------------------- - -There are two different methods for obtaining possibilities for different frame -intervals as well as configuring the frame interval. Which one to implement -depends on the type of the device. - -Raw camera sensors -~~~~~~~~~~~~~~~~~~ - -Instead of a high level parameter such as frame interval, the frame interval is -a result of the configuration of a number of camera sensor implementation -specific parameters. Luckily, these parameters tend to be the same for more or -less all modern raw camera sensors. - -The frame interval is calculated using the following equation:: - - frame interval = (analogue crop width + horizontal blanking) * - (analogue crop height + vertical blanking) / pixel rate - -The formula is bus independent and is applicable for raw timing parameters on -large variety of devices beyond camera sensors. Devices that have no analogue -crop, use the full source image size, i.e. pixel array size. - -Horizontal and vertical blanking are specified by ``V4L2_CID_HBLANK`` and -``V4L2_CID_VBLANK``, respectively. The unit of the ``V4L2_CID_HBLANK`` control -is pixels and the unit of the ``V4L2_CID_VBLANK`` is lines. The pixel rate in -the sensor's **pixel array** is specified by ``V4L2_CID_PIXEL_RATE`` in the same -sub-device. The unit of that control is pixels per second. - -Register list based drivers need to implement read-only sub-device nodes for the -purpose. Devices that are not register list based need these to configure the -device's internal processing pipeline. - -The first entity in the linear pipeline is the pixel array. The pixel array may -be followed by other entities that are there to allow configuring binning, -skipping, scaling or digital crop :ref:`v4l2-subdev-selections`. - -USB cameras etc. devices -~~~~~~~~~~~~~~~~~~~~~~~~ - -USB video class hardware, as well as many cameras offering a similar higher -level interface natively, generally use the concept of frame interval (or frame -rate) on device level in firmware or hardware. This means lower level controls -implemented by raw cameras may not be used on uAPI (or even kAPI) to control the -frame interval on these devices. - Power management ---------------- -Always use runtime PM to manage the power states of your device. Camera sensor -drivers are in no way special in this respect: they are responsible for -controlling the power state of the device they otherwise control as well. In -general, the device must be powered on at least when its registers are being -accessed and when it is streaming. - -Existing camera sensor drivers may rely on the old -struct v4l2_subdev_core_ops->s_power() callback for bridge or ISP drivers to -manage their power state. This is however **deprecated**. If you feel you need -to begin calling an s_power from an ISP or a bridge driver, instead please add -runtime PM support to the sensor driver you are using. Likewise, new drivers -should not use s_power. - -Please see examples in e.g. ``drivers/media/i2c/ov8856.c`` and -``drivers/media/i2c/ccs/ccs-core.c``. The two drivers work in both ACPI -and DT based systems. +Camera sensors are used in conjunction with other devices to form a camera +pipeline. They must obey the rules listed herein to ensure coherent power +management over the pipeline. + +Camera sensor drivers are responsible for controlling the power state of the +device they otherwise control as well. They shall use runtime PM to manage +power states. Runtime PM shall be enabled at probe time and disabled at remove +time. Drivers should enable runtime PM autosuspend. + +The runtime PM handlers shall handle clocks, regulators, GPIOs, and other +system resources required to power the sensor up and down. For drivers that +don't use any of those resources (such as drivers that support ACPI systems +only), the runtime PM handlers may be left unimplemented. + +In general, the device shall be powered on at least when its registers are +being accessed and when it is streaming. Drivers should use +``pm_runtime_resume_and_get()`` when starting streaming and +``pm_runtime_put()`` or ``pm_runtime_put_autosuspend()`` when stopping +streaming. They may power the device up at probe time (for example to read +identification registers), but should not keep it powered unconditionally after +probe. + +At system suspend time, the whole camera pipeline must stop streaming, and +restart when the system is resumed. This requires coordination between the +camera sensor and the rest of the camera pipeline. Bridge drivers are +responsible for this coordination, and instruct camera sensors to stop and +restart streaming by calling the appropriate subdev operations +(``.s_stream()``, ``.enable_streams()`` or ``.disable_streams()``). Camera +sensor drivers shall therefore **not** keep track of the streaming state to +stop streaming in the PM suspend handler and restart it in the resume handler. +Drivers should in general not implement the system PM handlers. + +Camera sensor drivers shall **not** implement the subdev ``.s_power()`` +operation, as it is deprecated. While this operation is implemented in some +existing drivers as they predate the deprecation, new drivers shall use runtime +PM instead. If you feel you need to begin calling ``.s_power()`` from an ISP or +a bridge driver, instead add runtime PM support to the sensor driver you are +using and drop its ``.s_power()`` handler. + +Please also see :ref:`examples <media-camera-sensor-examples>`. Control framework ~~~~~~~~~~~~~~~~~ @@ -155,21 +112,36 @@ access the device. Rotation, orientation and flipping ---------------------------------- -Some systems have the camera sensor mounted upside down compared to its natural -mounting rotation. In such cases, drivers shall expose the information to -userspace with the :ref:`V4L2_CID_CAMERA_SENSOR_ROTATION -<v4l2-camera-sensor-rotation>` control. - -Sensor drivers shall also report the sensor's mounting orientation with the -:ref:`V4L2_CID_CAMERA_SENSOR_ORIENTATION <v4l2-camera-sensor-orientation>`. - Use ``v4l2_fwnode_device_parse()`` to obtain rotation and orientation information from system firmware and ``v4l2_ctrl_new_fwnode_properties()`` to register the appropriate controls. -Sensor drivers that have any vertical or horizontal flips embedded in the -register programming sequences shall initialize the V4L2_CID_HFLIP and -V4L2_CID_VFLIP controls with the values programmed by the register sequences. -The default values of these controls shall be 0 (disabled). Especially these -controls shall not be inverted, independently of the sensor's mounting -rotation. +.. _media-camera-sensor-examples: + +Example drivers +--------------- + +Features implemented by sensor drivers vary, and depending on the set of +supported features and other qualities, particular sensor drivers better serve +the purpose of an example. The following drivers are known to be good examples: + +.. flat-table:: Example sensor drivers + :header-rows: 0 + :widths: 1 1 1 2 + + * - Driver name + - File(s) + - Driver type + - Example topic + * - CCS + - ``drivers/media/i2c/ccs/`` + - Freely configurable + - Power management (ACPI and DT), UAPI + * - imx219 + - ``drivers/media/i2c/imx219.c`` + - Register list based + - Power management (DT), UAPI, mode selection + * - imx319 + - ``drivers/media/i2c/imx319.c`` + - Register list based + - Power management (ACPI and DT) diff --git a/Documentation/driver-api/media/drivers/ccs/ccs.rst b/Documentation/driver-api/media/drivers/ccs/ccs.rst index 7389204afc..776eec72bc 100644 --- a/Documentation/driver-api/media/drivers/ccs/ccs.rst +++ b/Documentation/driver-api/media/drivers/ccs/ccs.rst @@ -30,7 +30,7 @@ that purpose, selection target ``V4L2_SEL_TGT_COMPOSE`` is supported on the sink pad (0). Additionally, if a device has no scaler or digital crop functionality, the -source pad (1) expses another digital crop selection rectangle that can only +source pad (1) exposes another digital crop selection rectangle that can only crop at the end of the lines and frames. Scaler @@ -78,6 +78,14 @@ For SMIA (non-++) compliant devices the static data file name is vvvv or vv denotes MIPI and SMIA manufacturer IDs respectively, mmmm model ID and rrrr or rr revision number. +CCS tools +~~~~~~~~~ + +`CCS tools <https://github.com/MIPI-Alliance/ccs-tools/>`_ is a set of +tools for working with CCS static data files. CCS tools includes a +definition of the human-readable CCS static data YAML format and includes a +program to convert it to a binary. + Register definition generator ----------------------------- diff --git a/Documentation/driver-api/media/v4l2-core.rst b/Documentation/driver-api/media/v4l2-core.rst index 239045ecc8..58cba831ad 100644 --- a/Documentation/driver-api/media/v4l2-core.rst +++ b/Documentation/driver-api/media/v4l2-core.rst @@ -13,7 +13,6 @@ Video4Linux devices v4l2-subdev v4l2-event v4l2-controls - v4l2-videobuf v4l2-videobuf2 v4l2-dv-timings v4l2-flash-led-class diff --git a/Documentation/driver-api/media/v4l2-dev.rst b/Documentation/driver-api/media/v4l2-dev.rst index 99e3b5fa74..d5cb19b21a 100644 --- a/Documentation/driver-api/media/v4l2-dev.rst +++ b/Documentation/driver-api/media/v4l2-dev.rst @@ -157,14 +157,6 @@ changing the e.g. exposure of the webcam. Of course, you can always do all the locking yourself by leaving both lock pointers at ``NULL``. -If you use the old :ref:`videobuf framework <vb_framework>` then you must -pass the :c:type:`video_device`->lock to the videobuf queue initialize -function: if videobuf has to wait for a frame to arrive, then it will -temporarily unlock the lock and relock it afterwards. If your driver also -waits in the code, then you should do the same to allow other -processes to access the device node while the first process is waiting for -something. - In the case of :ref:`videobuf2 <vb2_framework>` you will need to implement the ``wait_prepare()`` and ``wait_finish()`` callbacks to unlock/lock if applicable. If you use the ``queue->lock`` pointer, then you can use the helper functions diff --git a/Documentation/driver-api/media/v4l2-videobuf.rst b/Documentation/driver-api/media/v4l2-videobuf.rst deleted file mode 100644 index 4b1d84eefe..0000000000 --- a/Documentation/driver-api/media/v4l2-videobuf.rst +++ /dev/null @@ -1,403 +0,0 @@ -.. SPDX-License-Identifier: GPL-2.0 - -.. _vb_framework: - -Videobuf Framework -================== - -Author: Jonathan Corbet <corbet@lwn.net> - -Current as of 2.6.33 - -.. note:: - - The videobuf framework was deprecated in favor of videobuf2. Shouldn't - be used on new drivers. - -Introduction ------------- - -The videobuf layer functions as a sort of glue layer between a V4L2 driver -and user space. It handles the allocation and management of buffers for -the storage of video frames. There is a set of functions which can be used -to implement many of the standard POSIX I/O system calls, including read(), -poll(), and, happily, mmap(). Another set of functions can be used to -implement the bulk of the V4L2 ioctl() calls related to streaming I/O, -including buffer allocation, queueing and dequeueing, and streaming -control. Using videobuf imposes a few design decisions on the driver -author, but the payback comes in the form of reduced code in the driver and -a consistent implementation of the V4L2 user-space API. - -Buffer types ------------- - -Not all video devices use the same kind of buffers. In fact, there are (at -least) three common variations: - - - Buffers which are scattered in both the physical and (kernel) virtual - address spaces. (Almost) all user-space buffers are like this, but it - makes great sense to allocate kernel-space buffers this way as well when - it is possible. Unfortunately, it is not always possible; working with - this kind of buffer normally requires hardware which can do - scatter/gather DMA operations. - - - Buffers which are physically scattered, but which are virtually - contiguous; buffers allocated with vmalloc(), in other words. These - buffers are just as hard to use for DMA operations, but they can be - useful in situations where DMA is not available but virtually-contiguous - buffers are convenient. - - - Buffers which are physically contiguous. Allocation of this kind of - buffer can be unreliable on fragmented systems, but simpler DMA - controllers cannot deal with anything else. - -Videobuf can work with all three types of buffers, but the driver author -must pick one at the outset and design the driver around that decision. - -[It's worth noting that there's a fourth kind of buffer: "overlay" buffers -which are located within the system's video memory. The overlay -functionality is considered to be deprecated for most use, but it still -shows up occasionally in system-on-chip drivers where the performance -benefits merit the use of this technique. Overlay buffers can be handled -as a form of scattered buffer, but there are very few implementations in -the kernel and a description of this technique is currently beyond the -scope of this document.] - -Data structures, callbacks, and initialization ----------------------------------------------- - -Depending on which type of buffers are being used, the driver should -include one of the following files: - -.. code-block:: none - - <media/videobuf-dma-sg.h> /* Physically scattered */ - <media/videobuf-vmalloc.h> /* vmalloc() buffers */ - <media/videobuf-dma-contig.h> /* Physically contiguous */ - -The driver's data structure describing a V4L2 device should include a -struct videobuf_queue instance for the management of the buffer queue, -along with a list_head for the queue of available buffers. There will also -need to be an interrupt-safe spinlock which is used to protect (at least) -the queue. - -The next step is to write four simple callbacks to help videobuf deal with -the management of buffers: - -.. code-block:: none - - struct videobuf_queue_ops { - int (*buf_setup)(struct videobuf_queue *q, - unsigned int *count, unsigned int *size); - int (*buf_prepare)(struct videobuf_queue *q, - struct videobuf_buffer *vb, - enum v4l2_field field); - void (*buf_queue)(struct videobuf_queue *q, - struct videobuf_buffer *vb); - void (*buf_release)(struct videobuf_queue *q, - struct videobuf_buffer *vb); - }; - -buf_setup() is called early in the I/O process, when streaming is being -initiated; its purpose is to tell videobuf about the I/O stream. The count -parameter will be a suggested number of buffers to use; the driver should -check it for rationality and adjust it if need be. As a practical rule, a -minimum of two buffers are needed for proper streaming, and there is -usually a maximum (which cannot exceed 32) which makes sense for each -device. The size parameter should be set to the expected (maximum) size -for each frame of data. - -Each buffer (in the form of a struct videobuf_buffer pointer) will be -passed to buf_prepare(), which should set the buffer's size, width, height, -and field fields properly. If the buffer's state field is -VIDEOBUF_NEEDS_INIT, the driver should pass it to: - -.. code-block:: none - - int videobuf_iolock(struct videobuf_queue* q, struct videobuf_buffer *vb, - struct v4l2_framebuffer *fbuf); - -Among other things, this call will usually allocate memory for the buffer. -Finally, the buf_prepare() function should set the buffer's state to -VIDEOBUF_PREPARED. - -When a buffer is queued for I/O, it is passed to buf_queue(), which should -put it onto the driver's list of available buffers and set its state to -VIDEOBUF_QUEUED. Note that this function is called with the queue spinlock -held; if it tries to acquire it as well things will come to a screeching -halt. Yes, this is the voice of experience. Note also that videobuf may -wait on the first buffer in the queue; placing other buffers in front of it -could again gum up the works. So use list_add_tail() to enqueue buffers. - -Finally, buf_release() is called when a buffer is no longer intended to be -used. The driver should ensure that there is no I/O active on the buffer, -then pass it to the appropriate free routine(s): - -.. code-block:: none - - /* Scatter/gather drivers */ - int videobuf_dma_unmap(struct videobuf_queue *q, - struct videobuf_dmabuf *dma); - int videobuf_dma_free(struct videobuf_dmabuf *dma); - - /* vmalloc drivers */ - void videobuf_vmalloc_free (struct videobuf_buffer *buf); - - /* Contiguous drivers */ - void videobuf_dma_contig_free(struct videobuf_queue *q, - struct videobuf_buffer *buf); - -One way to ensure that a buffer is no longer under I/O is to pass it to: - -.. code-block:: none - - int videobuf_waiton(struct videobuf_buffer *vb, int non_blocking, int intr); - -Here, vb is the buffer, non_blocking indicates whether non-blocking I/O -should be used (it should be zero in the buf_release() case), and intr -controls whether an interruptible wait is used. - -File operations ---------------- - -At this point, much of the work is done; much of the rest is slipping -videobuf calls into the implementation of the other driver callbacks. The -first step is in the open() function, which must initialize the -videobuf queue. The function to use depends on the type of buffer used: - -.. code-block:: none - - void videobuf_queue_sg_init(struct videobuf_queue *q, - struct videobuf_queue_ops *ops, - struct device *dev, - spinlock_t *irqlock, - enum v4l2_buf_type type, - enum v4l2_field field, - unsigned int msize, - void *priv); - - void videobuf_queue_vmalloc_init(struct videobuf_queue *q, - struct videobuf_queue_ops *ops, - struct device *dev, - spinlock_t *irqlock, - enum v4l2_buf_type type, - enum v4l2_field field, - unsigned int msize, - void *priv); - - void videobuf_queue_dma_contig_init(struct videobuf_queue *q, - struct videobuf_queue_ops *ops, - struct device *dev, - spinlock_t *irqlock, - enum v4l2_buf_type type, - enum v4l2_field field, - unsigned int msize, - void *priv); - -In each case, the parameters are the same: q is the queue structure for the -device, ops is the set of callbacks as described above, dev is the device -structure for this video device, irqlock is an interrupt-safe spinlock to -protect access to the data structures, type is the buffer type used by the -device (cameras will use V4L2_BUF_TYPE_VIDEO_CAPTURE, for example), field -describes which field is being captured (often V4L2_FIELD_NONE for -progressive devices), msize is the size of any containing structure used -around struct videobuf_buffer, and priv is a private data pointer which -shows up in the priv_data field of struct videobuf_queue. Note that these -are void functions which, evidently, are immune to failure. - -V4L2 capture drivers can be written to support either of two APIs: the -read() system call and the rather more complicated streaming mechanism. As -a general rule, it is necessary to support both to ensure that all -applications have a chance of working with the device. Videobuf makes it -easy to do that with the same code. To implement read(), the driver need -only make a call to one of: - -.. code-block:: none - - ssize_t videobuf_read_one(struct videobuf_queue *q, - char __user *data, size_t count, - loff_t *ppos, int nonblocking); - - ssize_t videobuf_read_stream(struct videobuf_queue *q, - char __user *data, size_t count, - loff_t *ppos, int vbihack, int nonblocking); - -Either one of these functions will read frame data into data, returning the -amount actually read; the difference is that videobuf_read_one() will only -read a single frame, while videobuf_read_stream() will read multiple frames -if they are needed to satisfy the count requested by the application. A -typical driver read() implementation will start the capture engine, call -one of the above functions, then stop the engine before returning (though a -smarter implementation might leave the engine running for a little while in -anticipation of another read() call happening in the near future). - -The poll() function can usually be implemented with a direct call to: - -.. code-block:: none - - unsigned int videobuf_poll_stream(struct file *file, - struct videobuf_queue *q, - poll_table *wait); - -Note that the actual wait queue eventually used will be the one associated -with the first available buffer. - -When streaming I/O is done to kernel-space buffers, the driver must support -the mmap() system call to enable user space to access the data. In many -V4L2 drivers, the often-complex mmap() implementation simplifies to a -single call to: - -.. code-block:: none - - int videobuf_mmap_mapper(struct videobuf_queue *q, - struct vm_area_struct *vma); - -Everything else is handled by the videobuf code. - -The release() function requires two separate videobuf calls: - -.. code-block:: none - - void videobuf_stop(struct videobuf_queue *q); - int videobuf_mmap_free(struct videobuf_queue *q); - -The call to videobuf_stop() terminates any I/O in progress - though it is -still up to the driver to stop the capture engine. The call to -videobuf_mmap_free() will ensure that all buffers have been unmapped; if -so, they will all be passed to the buf_release() callback. If buffers -remain mapped, videobuf_mmap_free() returns an error code instead. The -purpose is clearly to cause the closing of the file descriptor to fail if -buffers are still mapped, but every driver in the 2.6.32 kernel cheerfully -ignores its return value. - -ioctl() operations ------------------- - -The V4L2 API includes a very long list of driver callbacks to respond to -the many ioctl() commands made available to user space. A number of these -- those associated with streaming I/O - turn almost directly into videobuf -calls. The relevant helper functions are: - -.. code-block:: none - - int videobuf_reqbufs(struct videobuf_queue *q, - struct v4l2_requestbuffers *req); - int videobuf_querybuf(struct videobuf_queue *q, struct v4l2_buffer *b); - int videobuf_qbuf(struct videobuf_queue *q, struct v4l2_buffer *b); - int videobuf_dqbuf(struct videobuf_queue *q, struct v4l2_buffer *b, - int nonblocking); - int videobuf_streamon(struct videobuf_queue *q); - int videobuf_streamoff(struct videobuf_queue *q); - -So, for example, a VIDIOC_REQBUFS call turns into a call to the driver's -vidioc_reqbufs() callback which, in turn, usually only needs to locate the -proper struct videobuf_queue pointer and pass it to videobuf_reqbufs(). -These support functions can replace a great deal of buffer management -boilerplate in a lot of V4L2 drivers. - -The vidioc_streamon() and vidioc_streamoff() functions will be a bit more -complex, of course, since they will also need to deal with starting and -stopping the capture engine. - -Buffer allocation ------------------ - -Thus far, we have talked about buffers, but have not looked at how they are -allocated. The scatter/gather case is the most complex on this front. For -allocation, the driver can leave buffer allocation entirely up to the -videobuf layer; in this case, buffers will be allocated as anonymous -user-space pages and will be very scattered indeed. If the application is -using user-space buffers, no allocation is needed; the videobuf layer will -take care of calling get_user_pages() and filling in the scatterlist array. - -If the driver needs to do its own memory allocation, it should be done in -the vidioc_reqbufs() function, *after* calling videobuf_reqbufs(). The -first step is a call to: - -.. code-block:: none - - struct videobuf_dmabuf *videobuf_to_dma(struct videobuf_buffer *buf); - -The returned videobuf_dmabuf structure (defined in -<media/videobuf-dma-sg.h>) includes a couple of relevant fields: - -.. code-block:: none - - struct scatterlist *sglist; - int sglen; - -The driver must allocate an appropriately-sized scatterlist array and -populate it with pointers to the pieces of the allocated buffer; sglen -should be set to the length of the array. - -Drivers using the vmalloc() method need not (and cannot) concern themselves -with buffer allocation at all; videobuf will handle those details. The -same is normally true of contiguous-DMA drivers as well; videobuf will -allocate the buffers (with dma_alloc_coherent()) when it sees fit. That -means that these drivers may be trying to do high-order allocations at any -time, an operation which is not always guaranteed to work. Some drivers -play tricks by allocating DMA space at system boot time; videobuf does not -currently play well with those drivers. - -As of 2.6.31, contiguous-DMA drivers can work with a user-supplied buffer, -as long as that buffer is physically contiguous. Normal user-space -allocations will not meet that criterion, but buffers obtained from other -kernel drivers, or those contained within huge pages, will work with these -drivers. - -Filling the buffers -------------------- - -The final part of a videobuf implementation has no direct callback - it's -the portion of the code which actually puts frame data into the buffers, -usually in response to interrupts from the device. For all types of -drivers, this process works approximately as follows: - - - Obtain the next available buffer and make sure that somebody is actually - waiting for it. - - - Get a pointer to the memory and put video data there. - - - Mark the buffer as done and wake up the process waiting for it. - -Step (1) above is done by looking at the driver-managed list_head structure -- the one which is filled in the buf_queue() callback. Because starting -the engine and enqueueing buffers are done in separate steps, it's possible -for the engine to be running without any buffers available - in the -vmalloc() case especially. So the driver should be prepared for the list -to be empty. It is equally possible that nobody is yet interested in the -buffer; the driver should not remove it from the list or fill it until a -process is waiting on it. That test can be done by examining the buffer's -done field (a wait_queue_head_t structure) with waitqueue_active(). - -A buffer's state should be set to VIDEOBUF_ACTIVE before being mapped for -DMA; that ensures that the videobuf layer will not try to do anything with -it while the device is transferring data. - -For scatter/gather drivers, the needed memory pointers will be found in the -scatterlist structure described above. Drivers using the vmalloc() method -can get a memory pointer with: - -.. code-block:: none - - void *videobuf_to_vmalloc(struct videobuf_buffer *buf); - -For contiguous DMA drivers, the function to use is: - -.. code-block:: none - - dma_addr_t videobuf_to_dma_contig(struct videobuf_buffer *buf); - -The contiguous DMA API goes out of its way to hide the kernel-space address -of the DMA buffer from drivers. - -The final step is to set the size field of the relevant videobuf_buffer -structure to the actual size of the captured image, set state to -VIDEOBUF_DONE, then call wake_up() on the done queue. At this point, the -buffer is owned by the videobuf layer and the driver should not touch it -again. - -Developers who are interested in more information can go into the relevant -header files; there are a few low-level functions declared there which have -not been talked about here. Note also that all of these calls are exported -GPL-only, so they will not be available to non-GPL kernel modules. diff --git a/Documentation/driver-api/pps.rst b/Documentation/driver-api/pps.rst index 2d6b99766e..78dded03e5 100644 --- a/Documentation/driver-api/pps.rst +++ b/Documentation/driver-api/pps.rst @@ -200,11 +200,17 @@ Generators Sometimes one needs to be able not only to catch PPS signals but to produce them also. For example, running a distributed simulation, which requires -computers' clock to be synchronized very tightly. One way to do this is to -invent some complicated hardware solutions but it may be neither necessary -nor affordable. The cheap way is to load a PPS generator on one of the -computers (master) and PPS clients on others (slaves), and use very simple -cables to deliver signals using parallel ports, for example. +computers' clock to be synchronized very tightly. + + +Parallel port generator +------------------------ + +One way to do this is to invent some complicated hardware solutions but it +may be neither necessary nor affordable. The cheap way is to load a PPS +generator on one of the computers (master) and PPS clients on others +(slaves), and use very simple cables to deliver signals using parallel +ports, for example. Parallel port cable pinout:: diff --git a/Documentation/driver-api/pwm.rst b/Documentation/driver-api/pwm.rst index 3fdc95f7a1..bb264490a8 100644 --- a/Documentation/driver-api/pwm.rst +++ b/Documentation/driver-api/pwm.rst @@ -111,13 +111,13 @@ channel that was exported. The following properties will then be available: duty_cycle The active time of the PWM signal (read/write). - Value is in nanoseconds and must be less than the period. + Value is in nanoseconds and must be less than or equal to the period. polarity Changes the polarity of the PWM signal (read/write). Writes to this property only work if the PWM chip supports changing - the polarity. The polarity can only be changed if the PWM is not - enabled. Value is the string "normal" or "inversed". + the polarity. + Value is the string "normal" or "inversed". enable Enable/disable the PWM signal (read/write). diff --git a/Documentation/driver-api/thermal/intel_dptf.rst b/Documentation/driver-api/thermal/intel_dptf.rst index 9ab4316322..8fb8c5b2d6 100644 --- a/Documentation/driver-api/thermal/intel_dptf.rst +++ b/Documentation/driver-api/thermal/intel_dptf.rst @@ -164,6 +164,16 @@ ABI. ``power_limit_1_tmax_us`` (RO) Maximum powercap sysfs constraint_1_time_window_us for Intel RAPL +``power_floor_status`` (RO) + When set to 1, the power floor of the system in the current + configuration has been reached. It needs to be reconfigured to allow + power to be reduced any further. + +``power_floor_enable`` (RW) + When set to 1, enable reading and notification of the power floor + status. Notifications are triggered for the power_floor_status + attribute value changes. + :file:`/sys/bus/pci/devices/0000\:00\:04.0/` ``tcc_offset_degree_celsius`` (RW) @@ -315,3 +325,57 @@ DPTF Fan Control ---------------------------------------- Refer to Documentation/admin-guide/acpi/fan_performance_states.rst + +Workload Type Hints +---------------------------------------- + +The firmware in Meteor Lake processor generation is capable of identifying +workload type and passing hints regarding it to the OS. A special sysfs +interface is provided to allow user space to obtain workload type hints from +the firmware and control the rate at which they are provided. + +User space can poll attribute "workload_type_index" for the current hint or +can receive a notification whenever the value of this attribute is updated. + +file:`/sys/bus/pci/devices/0000:00:04.0/workload_hint/` +Segment 0, bus 0, device 4, function 0 is reserved for the processor thermal +device on all Intel client processors. So, the above path doesn't change +based on the processor generation. + +``workload_hint_enable`` (RW) + Enable firmware to send workload type hints to user space. + +``notification_delay_ms`` (RW) + Minimum delay in milliseconds before firmware will notify OS. This is + for the rate control of notifications. This delay is between changing + the workload type prediction in the firmware and notifying the OS about + the change. The default delay is 1024 ms. The delay of 0 is invalid. + The delay is rounded up to the nearest power of 2 to simplify firmware + programming of the delay value. The read of notification_delay_ms + attribute shows the effective value used. + +``workload_type_index`` (RO) + Predicted workload type index. User space can get notification of + change via existing sysfs attribute change notification mechanism. + + The supported index values and their meaning for the Meteor Lake + processor generation are as follows: + + 0 - Idle: System performs no tasks, power and idle residency are + consistently low for long periods of time. + + 1 – Battery Life: Power is relatively low, but the processor may + still be actively performing a task, such as video playback for + a long period of time. + + 2 – Sustained: Power level that is relatively high for a long period + of time, with very few to no periods of idleness, which will + eventually exhaust RAPL Power Limit 1 and 2. + + 3 – Bursty: Consumes a relatively constant average amount of power, but + periods of relative idleness are interrupted by bursts of + activity. The bursts are relatively short and the periods of + relative idleness between them typically prevent RAPL Power + Limit 1 from being exhausted. + + 4 – Unknown: Can't classify. diff --git a/Documentation/driver-api/tty/index.rst b/Documentation/driver-api/tty/index.rst index 2d32606a42..b490da11f2 100644 --- a/Documentation/driver-api/tty/index.rst +++ b/Documentation/driver-api/tty/index.rst @@ -36,6 +36,7 @@ In-detail description of the named TTY structures is in separate documents: tty_struct tty_ldisc tty_buffer + tty_ioctl tty_internals Writing TTY Driver diff --git a/Documentation/driver-api/tty/tty_ioctl.rst b/Documentation/driver-api/tty/tty_ioctl.rst new file mode 100644 index 0000000000..3ff1ac5e07 --- /dev/null +++ b/Documentation/driver-api/tty/tty_ioctl.rst @@ -0,0 +1,10 @@ +.. SPDX-License-Identifier: GPL-2.0 + +================= +TTY IOCTL Helpers +================= + +.. kernel-doc:: drivers/tty/tty_ioctl.c + +.. kernel-doc:: include/linux/tty.h + :identifiers: tty_get_baud_rate diff --git a/Documentation/driver-api/usb/dma.rst b/Documentation/driver-api/usb/dma.rst index d32c27e11b..02f6825ff8 100644 --- a/Documentation/driver-api/usb/dma.rst +++ b/Documentation/driver-api/usb/dma.rst @@ -93,44 +93,18 @@ DMA address space of the device. However, most buffers passed to your driver can safely be used with such DMA mapping. (See the first section of Documentation/core-api/dma-api-howto.rst, titled "What memory is DMA-able?") -- When you're using scatterlists, you can map everything at once. On some - systems, this kicks in an IOMMU and turns the scatterlists into single - DMA transactions:: +- When you have the scatterlists which have been mapped for the USB controller, + you could use the new ``usb_sg_*()`` calls, which would turn scatterlist + into URBs:: - int usb_buffer_map_sg (struct usb_device *dev, unsigned pipe, - struct scatterlist *sg, int nents); + int usb_sg_init(struct usb_sg_request *io, struct usb_device *dev, + unsigned pipe, unsigned period, struct scatterlist *sg, + int nents, size_t length, gfp_t mem_flags); - void usb_buffer_dmasync_sg (struct usb_device *dev, unsigned pipe, - struct scatterlist *sg, int n_hw_ents); + void usb_sg_wait(struct usb_sg_request *io); - void usb_buffer_unmap_sg (struct usb_device *dev, unsigned pipe, - struct scatterlist *sg, int n_hw_ents); + void usb_sg_cancel(struct usb_sg_request *io); - It's probably easier to use the new ``usb_sg_*()`` calls, which do the DMA - mapping and apply other tweaks to make scatterlist i/o be fast. - -- Some drivers may prefer to work with the model that they're mapping large - buffers, synchronizing their safe re-use. (If there's no re-use, then let - usbcore do the map/unmap.) Large periodic transfers make good examples - here, since it's cheaper to just synchronize the buffer than to unmap it - each time an urb completes and then re-map it on during resubmission. - - These calls all work with initialized urbs: ``urb->dev``, ``urb->pipe``, - ``urb->transfer_buffer``, and ``urb->transfer_buffer_length`` must all be - valid when these calls are used (``urb->setup_packet`` must be valid too - if urb is a control request):: - - struct urb *usb_buffer_map (struct urb *urb); - - void usb_buffer_dmasync (struct urb *urb); - - void usb_buffer_unmap (struct urb *urb); - - The calls manage ``urb->transfer_dma`` for you, and set - ``URB_NO_TRANSFER_DMA_MAP`` so that usbcore won't map or unmap the buffer. - They cannot be used for setup_packet buffers in control requests. - -Note that several of those interfaces are currently commented out, since -they don't have current users. See the source code. Other than the dmasync -calls (where the underlying DMA primitives have changed), most of them can -easily be commented back in if you want to use them. + When the USB controller doesn't support DMA, the ``usb_sg_init()`` would try + to submit URBs in PIO way as long as the page in scatterlists is not in the + Highmem, which could be very rare in modern architectures. |