aboutsummaryrefslogtreecommitdiffstats
path: root/Documentation/driver-api
diff options
context:
space:
mode:
Diffstat (limited to 'Documentation/driver-api')
-rw-r--r--Documentation/driver-api/aperture.rst13
-rw-r--r--Documentation/driver-api/auxiliary_bus.rst236
-rw-r--r--Documentation/driver-api/basics.rst3
-rw-r--r--Documentation/driver-api/cxl/memory-devices.rst323
-rw-r--r--Documentation/driver-api/device-io.rst9
-rw-r--r--Documentation/driver-api/dma-buf.rst15
-rw-r--r--Documentation/driver-api/dmaengine/dmatest.rst17
-rw-r--r--Documentation/driver-api/dmaengine/provider.rst21
-rw-r--r--Documentation/driver-api/driver-model/devres.rst25
-rw-r--r--Documentation/driver-api/firewire.rst4
-rw-r--r--Documentation/driver-api/firmware/core.rst1
-rw-r--r--Documentation/driver-api/firmware/firmware-usage-guidelines.rst44
-rw-r--r--Documentation/driver-api/firmware/fw_upload.rst126
-rw-r--r--Documentation/driver-api/firmware/index.rst1
-rw-r--r--Documentation/driver-api/firmware/other_interfaces.rst6
-rw-r--r--Documentation/driver-api/fpga/fpga-bridge.rst6
-rw-r--r--Documentation/driver-api/fpga/fpga-mgr.rst65
-rw-r--r--Documentation/driver-api/fpga/fpga-region.rst12
-rw-r--r--Documentation/driver-api/generic-counter.rst10
-rw-r--r--Documentation/driver-api/gpio/board.rst23
-rw-r--r--Documentation/driver-api/gpio/consumer.rst8
-rw-r--r--Documentation/driver-api/gpio/driver.rst187
-rw-r--r--Documentation/driver-api/gpio/intro.rst6
-rw-r--r--Documentation/driver-api/gpio/using-gpio.rst2
-rw-r--r--Documentation/driver-api/hte/hte.rst79
-rw-r--r--Documentation/driver-api/hte/index.rst22
-rw-r--r--Documentation/driver-api/hte/tegra194-hte.rst48
-rw-r--r--Documentation/driver-api/index.rst4
-rw-r--r--Documentation/driver-api/isa.rst2
-rw-r--r--Documentation/driver-api/libata.rst11
-rw-r--r--Documentation/driver-api/media/cec-core.rst13
-rw-r--r--Documentation/driver-api/media/drivers/davinci-vpbe-devel.rst20
-rw-r--r--Documentation/driver-api/media/drivers/fimc-devel.rst14
-rw-r--r--Documentation/driver-api/media/drivers/index.rst1
-rw-r--r--Documentation/driver-api/media/drivers/pxa_camera.rst2
-rw-r--r--Documentation/driver-api/media/mc-core.rst37
-rw-r--r--Documentation/driver-api/media/v4l2-event.rst2
-rw-r--r--Documentation/driver-api/media/v4l2-subdev.rst75
-rw-r--r--Documentation/driver-api/mtd/index.rst2
-rw-r--r--Documentation/driver-api/mtd/spi-intel.rst (renamed from Documentation/driver-api/mtd/intel-spi.rst)8
-rw-r--r--Documentation/driver-api/nvdimm/nvdimm.rst406
-rw-r--r--Documentation/driver-api/nvmem.rst28
-rw-r--r--Documentation/driver-api/pci/pci.rst2
-rw-r--r--Documentation/driver-api/pwm.rst9
-rw-r--r--Documentation/driver-api/serial/driver.rst482
-rw-r--r--Documentation/driver-api/serial/index.rst3
-rw-r--r--Documentation/driver-api/serial/n_gsm.rst153
-rw-r--r--Documentation/driver-api/serial/serial-rs485.rst38
-rw-r--r--Documentation/driver-api/serial/tty.rst328
-rw-r--r--Documentation/driver-api/surface_aggregator/client.rst6
-rw-r--r--Documentation/driver-api/thermal/index.rst1
-rw-r--r--Documentation/driver-api/thermal/intel_dptf.rst272
-rw-r--r--Documentation/driver-api/tty/index.rst73
-rw-r--r--Documentation/driver-api/tty/moxa-smartio.rst (renamed from Documentation/driver-api/serial/moxa-smartio.rst)0
-rw-r--r--Documentation/driver-api/tty/n_gsm.rst153
-rw-r--r--Documentation/driver-api/tty/n_tty.rst22
-rw-r--r--Documentation/driver-api/tty/tty_buffer.rst46
-rw-r--r--Documentation/driver-api/tty/tty_driver.rst128
-rw-r--r--Documentation/driver-api/tty/tty_internals.rst31
-rw-r--r--Documentation/driver-api/tty/tty_ldisc.rst85
-rw-r--r--Documentation/driver-api/tty/tty_port.rst70
-rw-r--r--Documentation/driver-api/tty/tty_struct.rst81
-rw-r--r--Documentation/driver-api/usb/writing_usb_driver.rst32
-rw-r--r--Documentation/driver-api/vfio-mediated-device.rst63
-rw-r--r--Documentation/driver-api/vfio-pci-device-specific-driver-acceptance.rst35
-rw-r--r--Documentation/driver-api/vme.rst4
66 files changed, 2337 insertions, 1717 deletions
diff --git a/Documentation/driver-api/aperture.rst b/Documentation/driver-api/aperture.rst
new file mode 100644
index 000000000000..d173f4e7a7d9
--- /dev/null
+++ b/Documentation/driver-api/aperture.rst
@@ -0,0 +1,13 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+Managing Ownership of the Framebuffer Aperture
+==============================================
+
+.. kernel-doc:: drivers/video/aperture.c
+ :doc: overview
+
+.. kernel-doc:: include/linux/aperture.h
+ :internal:
+
+.. kernel-doc:: drivers/video/aperture.c
+ :export:
diff --git a/Documentation/driver-api/auxiliary_bus.rst b/Documentation/driver-api/auxiliary_bus.rst
index ef902daf0d68..cec84908fbc0 100644
--- a/Documentation/driver-api/auxiliary_bus.rst
+++ b/Documentation/driver-api/auxiliary_bus.rst
@@ -6,231 +6,45 @@
Auxiliary Bus
=============
-In some subsystems, the functionality of the core device (PCI/ACPI/other) is
-too complex for a single device to be managed by a monolithic driver
-(e.g. Sound Open Firmware), multiple devices might implement a common
-intersection of functionality (e.g. NICs + RDMA), or a driver may want to
-export an interface for another subsystem to drive (e.g. SIOV Physical Function
-export Virtual Function management). A split of the functionality into child-
-devices representing sub-domains of functionality makes it possible to
-compartmentalize, layer, and distribute domain-specific concerns via a Linux
-device-driver model.
-
-An example for this kind of requirement is the audio subsystem where a single
-IP is handling multiple entities such as HDMI, Soundwire, local devices such as
-mics/speakers etc. The split for the core's functionality can be arbitrary or
-be defined by the DSP firmware topology and include hooks for test/debug. This
-allows for the audio core device to be minimal and focused on hardware-specific
-control and communication.
-
-Each auxiliary_device represents a part of its parent functionality. The
-generic behavior can be extended and specialized as needed by encapsulating an
-auxiliary_device within other domain-specific structures and the use of .ops
-callbacks. Devices on the auxiliary bus do not share any structures and the use
-of a communication channel with the parent is domain-specific.
-
-Note that ops are intended as a way to augment instance behavior within a class
-of auxiliary devices, it is not the mechanism for exporting common
-infrastructure from the parent. Consider EXPORT_SYMBOL_NS() to convey
-infrastructure from the parent module to the auxiliary module(s).
-
+.. kernel-doc:: drivers/base/auxiliary.c
+ :doc: PURPOSE
When Should the Auxiliary Bus Be Used
=====================================
-The auxiliary bus is to be used when a driver and one or more kernel modules,
-who share a common header file with the driver, need a mechanism to connect and
-provide access to a shared object allocated by the auxiliary_device's
-registering driver. The registering driver for the auxiliary_device(s) and the
-kernel module(s) registering auxiliary_drivers can be from the same subsystem,
-or from multiple subsystems.
-
-The emphasis here is on a common generic interface that keeps subsystem
-customization out of the bus infrastructure.
-
-One example is a PCI network device that is RDMA-capable and exports a child
-device to be driven by an auxiliary_driver in the RDMA subsystem. The PCI
-driver allocates and registers an auxiliary_device for each physical
-function on the NIC. The RDMA driver registers an auxiliary_driver that claims
-each of these auxiliary_devices. This conveys data/ops published by the parent
-PCI device/driver to the RDMA auxiliary_driver.
-
-Another use case is for the PCI device to be split out into multiple sub
-functions. For each sub function an auxiliary_device is created. A PCI sub
-function driver binds to such devices that creates its own one or more class
-devices. A PCI sub function auxiliary device is likely to be contained in a
-struct with additional attributes such as user defined sub function number and
-optional attributes such as resources and a link to the parent device. These
-attributes could be used by systemd/udev; and hence should be initialized
-before a driver binds to an auxiliary_device.
-
-A key requirement for utilizing the auxiliary bus is that there is no
-dependency on a physical bus, device, register accesses or regmap support.
-These individual devices split from the core cannot live on the platform bus as
-they are not physical devices that are controlled by DT/ACPI. The same
-argument applies for not using MFD in this scenario as MFD relies on individual
-function devices being physical devices.
-
-Auxiliary Device
-================
-
-An auxiliary_device represents a part of its parent device's functionality. It
-is given a name that, combined with the registering drivers KBUILD_MODNAME,
-creates a match_name that is used for driver binding, and an id that combined
-with the match_name provide a unique name to register with the bus subsystem.
-
-Registering an auxiliary_device is a two-step process. First call
-auxiliary_device_init(), which checks several aspects of the auxiliary_device
-struct and performs a device_initialize(). After this step completes, any
-error state must have a call to auxiliary_device_uninit() in its resolution path.
-The second step in registering an auxiliary_device is to perform a call to
-auxiliary_device_add(), which sets the name of the device and add the device to
-the bus.
-
-Unregistering an auxiliary_device is also a two-step process to mirror the
-register process. First call auxiliary_device_delete(), then call
-auxiliary_device_uninit().
-
-.. code-block:: c
-
- struct auxiliary_device {
- struct device dev;
- const char *name;
- u32 id;
- };
-
-If two auxiliary_devices both with a match_name "mod.foo" are registered onto
-the bus, they must have unique id values (e.g. "x" and "y") so that the
-registered devices names are "mod.foo.x" and "mod.foo.y". If match_name + id
-are not unique, then the device_add fails and generates an error message.
-
-The auxiliary_device.dev.type.release or auxiliary_device.dev.release must be
-populated with a non-NULL pointer to successfully register the auxiliary_device.
-
-The auxiliary_device.dev.parent must also be populated.
+.. kernel-doc:: drivers/base/auxiliary.c
+ :doc: USAGE
+
+
+Auxiliary Device Creation
+=========================
+
+.. kernel-doc:: include/linux/auxiliary_bus.h
+ :identifiers: auxiliary_device
+
+.. kernel-doc:: drivers/base/auxiliary.c
+ :identifiers: auxiliary_device_init __auxiliary_device_add
+ auxiliary_find_device
Auxiliary Device Memory Model and Lifespan
------------------------------------------
-The registering driver is the entity that allocates memory for the
-auxiliary_device and register it on the auxiliary bus. It is important to note
-that, as opposed to the platform bus, the registering driver is wholly
-responsible for the management for the memory used for the driver object.
-
-A parent object, defined in the shared header file, contains the
-auxiliary_device. It also contains a pointer to the shared object(s), which
-also is defined in the shared header. Both the parent object and the shared
-object(s) are allocated by the registering driver. This layout allows the
-auxiliary_driver's registering module to perform a container_of() call to go
-from the pointer to the auxiliary_device, that is passed during the call to the
-auxiliary_driver's probe function, up to the parent object, and then have
-access to the shared object(s).
-
-The memory for the auxiliary_device is freed only in its release() callback
-flow as defined by its registering driver.
-
-The memory for the shared object(s) must have a lifespan equal to, or greater
-than, the lifespan of the memory for the auxiliary_device. The auxiliary_driver
-should only consider that this shared object is valid as long as the
-auxiliary_device is still registered on the auxiliary bus. It is up to the
-registering driver to manage (e.g. free or keep available) the memory for the
-shared object beyond the life of the auxiliary_device.
-
-The registering driver must unregister all auxiliary devices before its own
-driver.remove() is completed.
+.. kernel-doc:: include/linux/auxiliary_bus.h
+ :doc: DEVICE_LIFESPAN
+
Auxiliary Drivers
=================
-Auxiliary drivers follow the standard driver model convention, where
-discovery/enumeration is handled by the core, and drivers
-provide probe() and remove() methods. They support power management
-and shutdown notifications using the standard conventions.
-
-.. code-block:: c
+.. kernel-doc:: include/linux/auxiliary_bus.h
+ :identifiers: auxiliary_driver module_auxiliary_driver
- struct auxiliary_driver {
- int (*probe)(struct auxiliary_device *,
- const struct auxiliary_device_id *id);
- void (*remove)(struct auxiliary_device *);
- void (*shutdown)(struct auxiliary_device *);
- int (*suspend)(struct auxiliary_device *, pm_message_t);
- int (*resume)(struct auxiliary_device *);
- struct device_driver driver;
- const struct auxiliary_device_id *id_table;
- };
-
-Auxiliary drivers register themselves with the bus by calling
-auxiliary_driver_register(). The id_table contains the match_names of auxiliary
-devices that a driver can bind with.
+.. kernel-doc:: drivers/base/auxiliary.c
+ :identifiers: __auxiliary_driver_register auxiliary_driver_unregister
Example Usage
=============
-Auxiliary devices are created and registered by a subsystem-level core device
-that needs to break up its functionality into smaller fragments. One way to
-extend the scope of an auxiliary_device is to encapsulate it within a domain-
-pecific structure defined by the parent device. This structure contains the
-auxiliary_device and any associated shared data/callbacks needed to establish
-the connection with the parent.
-
-An example is:
-
-.. code-block:: c
-
- struct foo {
- struct auxiliary_device auxdev;
- void (*connect)(struct auxiliary_device *auxdev);
- void (*disconnect)(struct auxiliary_device *auxdev);
- void *data;
- };
-
-The parent device then registers the auxiliary_device by calling
-auxiliary_device_init(), and then auxiliary_device_add(), with the pointer to
-the auxdev member of the above structure. The parent provides a name for the
-auxiliary_device that, combined with the parent's KBUILD_MODNAME, creates a
-match_name that is be used for matching and binding with a driver.
-
-Whenever an auxiliary_driver is registered, based on the match_name, the
-auxiliary_driver's probe() is invoked for the matching devices. The
-auxiliary_driver can also be encapsulated inside custom drivers that make the
-core device's functionality extensible by adding additional domain-specific ops
-as follows:
-
-.. code-block:: c
-
- struct my_ops {
- void (*send)(struct auxiliary_device *auxdev);
- void (*receive)(struct auxiliary_device *auxdev);
- };
-
-
- struct my_driver {
- struct auxiliary_driver auxiliary_drv;
- const struct my_ops ops;
- };
-
-An example of this type of usage is:
-
-.. code-block:: c
-
- const struct auxiliary_device_id my_auxiliary_id_table[] = {
- { .name = "foo_mod.foo_dev" },
- { },
- };
-
- const struct my_ops my_custom_ops = {
- .send = my_tx,
- .receive = my_rx,
- };
-
- const struct my_driver my_drv = {
- .auxiliary_drv = {
- .name = "myauxiliarydrv",
- .id_table = my_auxiliary_id_table,
- .probe = my_probe,
- .remove = my_remove,
- .shutdown = my_shutdown,
- },
- .ops = my_custom_ops,
- };
+.. kernel-doc:: drivers/base/auxiliary.c
+ :doc: EXAMPLE
+
diff --git a/Documentation/driver-api/basics.rst b/Documentation/driver-api/basics.rst
index 3e2dae954898..4b4d8e28d3be 100644
--- a/Documentation/driver-api/basics.rst
+++ b/Documentation/driver-api/basics.rst
@@ -107,9 +107,6 @@ Kernel utility functions
.. kernel-doc:: kernel/panic.c
:export:
-.. kernel-doc:: include/linux/overflow.h
- :internal:
-
Device Resource Management
--------------------------
diff --git a/Documentation/driver-api/cxl/memory-devices.rst b/Documentation/driver-api/cxl/memory-devices.rst
index 3b8f41395f6b..5149ecdc53c7 100644
--- a/Documentation/driver-api/cxl/memory-devices.rst
+++ b/Documentation/driver-api/cxl/memory-devices.rst
@@ -14,6 +14,303 @@ that optionally define a device's contribution to an interleaved address
range across multiple devices underneath a host-bridge or interleaved
across host-bridges.
+CXL Bus: Theory of Operation
+============================
+Similar to how a RAID driver takes disk objects and assembles them into a new
+logical device, the CXL subsystem is tasked to take PCIe and ACPI objects and
+assemble them into a CXL.mem decode topology. The need for runtime configuration
+of the CXL.mem topology is also similar to RAID in that different environments
+with the same hardware configuration may decide to assemble the topology in
+contrasting ways. One may choose performance (RAID0) striping memory across
+multiple Host Bridges and endpoints while another may opt for fault tolerance
+and disable any striping in the CXL.mem topology.
+
+Platform firmware enumerates a menu of interleave options at the "CXL root port"
+(Linux term for the top of the CXL decode topology). From there, PCIe topology
+dictates which endpoints can participate in which Host Bridge decode regimes.
+Each PCIe Switch in the path between the root and an endpoint introduces a point
+at which the interleave can be split. For example platform firmware may say at a
+given range only decodes to 1 one Host Bridge, but that Host Bridge may in turn
+interleave cycles across multiple Root Ports. An intervening Switch between a
+port and an endpoint may interleave cycles across multiple Downstream Switch
+Ports, etc.
+
+Here is a sample listing of a CXL topology defined by 'cxl_test'. The 'cxl_test'
+module generates an emulated CXL topology of 2 Host Bridges each with 2 Root
+Ports. Each of those Root Ports are connected to 2-way switches with endpoints
+connected to those downstream ports for a total of 8 endpoints::
+
+ # cxl list -BEMPu -b cxl_test
+ {
+ "bus":"root3",
+ "provider":"cxl_test",
+ "ports:root3":[
+ {
+ "port":"port5",
+ "host":"cxl_host_bridge.1",
+ "ports:port5":[
+ {
+ "port":"port8",
+ "host":"cxl_switch_uport.1",
+ "endpoints:port8":[
+ {
+ "endpoint":"endpoint9",
+ "host":"mem2",
+ "memdev":{
+ "memdev":"mem2",
+ "pmem_size":"256.00 MiB (268.44 MB)",
+ "ram_size":"256.00 MiB (268.44 MB)",
+ "serial":"0x1",
+ "numa_node":1,
+ "host":"cxl_mem.1"
+ }
+ },
+ {
+ "endpoint":"endpoint15",
+ "host":"mem6",
+ "memdev":{
+ "memdev":"mem6",
+ "pmem_size":"256.00 MiB (268.44 MB)",
+ "ram_size":"256.00 MiB (268.44 MB)",
+ "serial":"0x5",
+ "numa_node":1,
+ "host":"cxl_mem.5"
+ }
+ }
+ ]
+ },
+ {
+ "port":"port12",
+ "host":"cxl_switch_uport.3",
+ "endpoints:port12":[
+ {
+ "endpoint":"endpoint17",
+ "host":"mem8",
+ "memdev":{
+ "memdev":"mem8",
+ "pmem_size":"256.00 MiB (268.44 MB)",
+ "ram_size":"256.00 MiB (268.44 MB)",
+ "serial":"0x7",
+ "numa_node":1,
+ "host":"cxl_mem.7"
+ }
+ },
+ {
+ "endpoint":"endpoint13",
+ "host":"mem4",
+ "memdev":{
+ "memdev":"mem4",
+ "pmem_size":"256.00 MiB (268.44 MB)",
+ "ram_size":"256.00 MiB (268.44 MB)",
+ "serial":"0x3",
+ "numa_node":1,
+ "host":"cxl_mem.3"
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "port":"port4",
+ "host":"cxl_host_bridge.0",
+ "ports:port4":[
+ {
+ "port":"port6",
+ "host":"cxl_switch_uport.0",
+ "endpoints:port6":[
+ {
+ "endpoint":"endpoint7",
+ "host":"mem1",
+ "memdev":{
+ "memdev":"mem1",
+ "pmem_size":"256.00 MiB (268.44 MB)",
+ "ram_size":"256.00 MiB (268.44 MB)",
+ "serial":"0",
+ "numa_node":0,
+ "host":"cxl_mem.0"
+ }
+ },
+ {
+ "endpoint":"endpoint14",
+ "host":"mem5",
+ "memdev":{
+ "memdev":"mem5",
+ "pmem_size":"256.00 MiB (268.44 MB)",
+ "ram_size":"256.00 MiB (268.44 MB)",
+ "serial":"0x4",
+ "numa_node":0,
+ "host":"cxl_mem.4"
+ }
+ }
+ ]
+ },
+ {
+ "port":"port10",
+ "host":"cxl_switch_uport.2",
+ "endpoints:port10":[
+ {
+ "endpoint":"endpoint16",
+ "host":"mem7",
+ "memdev":{
+ "memdev":"mem7",
+ "pmem_size":"256.00 MiB (268.44 MB)",
+ "ram_size":"256.00 MiB (268.44 MB)",
+ "serial":"0x6",
+ "numa_node":0,
+ "host":"cxl_mem.6"
+ }
+ },
+ {
+ "endpoint":"endpoint11",
+ "host":"mem3",
+ "memdev":{
+ "memdev":"mem3",
+ "pmem_size":"256.00 MiB (268.44 MB)",
+ "ram_size":"256.00 MiB (268.44 MB)",
+ "serial":"0x2",
+ "numa_node":0,
+ "host":"cxl_mem.2"
+ }
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+
+In that listing each "root", "port", and "endpoint" object correspond a kernel
+'struct cxl_port' object. A 'cxl_port' is a device that can decode CXL.mem to
+its descendants. So "root" claims non-PCIe enumerable platform decode ranges and
+decodes them to "ports", "ports" decode to "endpoints", and "endpoints"
+represent the decode from SPA (System Physical Address) to DPA (Device Physical
+Address).
+
+Continuing the RAID analogy, disks have both topology metadata and on device
+metadata that determine RAID set assembly. CXL Port topology and CXL Port link
+status is metadata for CXL.mem set assembly. The CXL Port topology is enumerated
+by the arrival of a CXL.mem device. I.e. unless and until the PCIe core attaches
+the cxl_pci driver to a CXL Memory Expander there is no role for CXL Port
+objects. Conversely for hot-unplug / removal scenarios, there is no need for
+the Linux PCI core to tear down switch-level CXL resources because the endpoint
+->remove() event cleans up the port data that was established to support that
+Memory Expander.
+
+The port metadata and potential decode schemes that a give memory device may
+participate can be determined via a command like::
+
+ # cxl list -BDMu -d root -m mem3
+ {
+ "bus":"root3",
+ "provider":"cxl_test",
+ "decoders:root3":[
+ {
+ "decoder":"decoder3.1",
+ "resource":"0x8030000000",
+ "size":"512.00 MiB (536.87 MB)",
+ "volatile_capable":true,
+ "nr_targets":2
+ },
+ {
+ "decoder":"decoder3.3",
+ "resource":"0x8060000000",
+ "size":"512.00 MiB (536.87 MB)",
+ "pmem_capable":true,
+ "nr_targets":2
+ },
+ {
+ "decoder":"decoder3.0",
+ "resource":"0x8020000000",
+ "size":"256.00 MiB (268.44 MB)",
+ "volatile_capable":true,
+ "nr_targets":1
+ },
+ {
+ "decoder":"decoder3.2",
+ "resource":"0x8050000000",
+ "size":"256.00 MiB (268.44 MB)",
+ "pmem_capable":true,
+ "nr_targets":1
+ }
+ ],
+ "memdevs:root3":[
+ {
+ "memdev":"mem3",
+ "pmem_size":"256.00 MiB (268.44 MB)",
+ "ram_size":"256.00 MiB (268.44 MB)",
+ "serial":"0x2",
+ "numa_node":0,
+ "host":"cxl_mem.2"
+ }
+ ]
+ }
+
+...which queries the CXL topology to ask "given CXL Memory Expander with a kernel
+device name of 'mem3' which platform level decode ranges may this device
+participate". A given expander can participate in multiple CXL.mem interleave
+sets simultaneously depending on how many decoder resource it has. In this
+example mem3 can participate in one or more of a PMEM interleave that spans to
+Host Bridges, a PMEM interleave that targets a single Host Bridge, a Volatile
+memory interleave that spans 2 Host Bridges, and a Volatile memory interleave
+that only targets a single Host Bridge.
+
+Conversely the memory devices that can participate in a given platform level
+decode scheme can be determined via a command like the following::
+
+ # cxl list -MDu -d 3.2
+ [
+ {
+ "memdevs":[
+ {
+ "memdev":"mem1",
+ "pmem_size":"256.00 MiB (268.44 MB)",
+ "ram_size":"256.00 MiB (268.44 MB)",
+ "serial":"0",
+ "numa_node":0,
+ "host":"cxl_mem.0"
+ },
+ {
+ "memdev":"mem5",
+ "pmem_size":"256.00 MiB (268.44 MB)",
+ "ram_size":"256.00 MiB (268.44 MB)",
+ "serial":"0x4",
+ "numa_node":0,
+ "host":"cxl_mem.4"
+ },
+ {
+ "memdev":"mem7",
+ "pmem_size":"256.00 MiB (268.44 MB)",
+ "ram_size":"256.00 MiB (268.44 MB)",
+ "serial":"0x6",
+ "numa_node":0,
+ "host":"cxl_mem.6"
+ },
+ {
+ "memdev":"mem3",
+ "pmem_size":"256.00 MiB (268.44 MB)",
+ "ram_size":"256.00 MiB (268.44 MB)",
+ "serial":"0x2",
+ "numa_node":0,
+ "host":"cxl_mem.2"
+ }
+ ]
+ },
+ {
+ "root decoders":[
+ {
+ "decoder":"decoder3.2",
+ "resource":"0x8050000000",
+ "size":"256.00 MiB (268.44 MB)",
+ "pmem_capable":true,
+ "nr_targets":1
+ }
+ ]
+ }
+ ]
+
+...where the naming scheme for decoders is "decoder<port_id>.<instance_id>".
+
Driver Infrastructure
=====================
@@ -28,6 +325,14 @@ CXL Memory Device
.. kernel-doc:: drivers/cxl/pci.c
:internal:
+.. kernel-doc:: drivers/cxl/mem.c
+ :doc: cxl mem
+
+CXL Port
+--------
+.. kernel-doc:: drivers/cxl/port.c
+ :doc: cxl port
+
CXL Core
--------
.. kernel-doc:: drivers/cxl/cxl.h
@@ -36,10 +341,16 @@ CXL Core
.. kernel-doc:: drivers/cxl/cxl.h
:internal:
-.. kernel-doc:: drivers/cxl/core/bus.c
+.. kernel-doc:: drivers/cxl/core/port.c
:doc: cxl core
-.. kernel-doc:: drivers/cxl/core/bus.c
+.. kernel-doc:: drivers/cxl/core/port.c
+ :identifiers:
+
+.. kernel-doc:: drivers/cxl/core/pci.c
+ :doc: cxl core pci
+
+.. kernel-doc:: drivers/cxl/core/pci.c
:identifiers:
.. kernel-doc:: drivers/cxl/core/pmem.c
@@ -51,6 +362,14 @@ CXL Core
.. kernel-doc:: drivers/cxl/core/mbox.c
:doc: cxl mbox
+CXL Regions
+-----------
+.. kernel-doc:: drivers/cxl/core/region.c
+ :doc: cxl core region
+
+.. kernel-doc:: drivers/cxl/core/region.c
+ :identifiers:
+
External Interfaces
===================
diff --git a/Documentation/driver-api/device-io.rst b/Documentation/driver-api/device-io.rst
index e9f04b1815d1..4d2baac0311c 100644
--- a/Documentation/driver-api/device-io.rst
+++ b/Documentation/driver-api/device-io.rst
@@ -502,6 +502,15 @@ pcim_iomap()
Not using these wrappers may make drivers unusable on certain platforms with
stricter rules for mapping I/O memory.
+Generalizing Access to System and I/O Memory
+============================================
+
+.. kernel-doc:: include/linux/iosys-map.h
+ :doc: overview
+
+.. kernel-doc:: include/linux/iosys-map.h
+ :internal:
+
Public Functions Provided
=========================
diff --git a/Documentation/driver-api/dma-buf.rst b/Documentation/driver-api/dma-buf.rst
index 2cd7db82d9fe..36a76cbe9095 100644
--- a/Documentation/driver-api/dma-buf.rst
+++ b/Documentation/driver-api/dma-buf.rst
@@ -128,15 +128,6 @@ Kernel Functions and Structures Reference
.. kernel-doc:: include/linux/dma-buf.h
:internal:
-Buffer Mapping Helpers
-~~~~~~~~~~~~~~~~~~~~~~
-
-.. kernel-doc:: include/linux/dma-buf-map.h
- :doc: overview
-
-.. kernel-doc:: include/linux/dma-buf-map.h
- :internal:
-
Reservation Objects
-------------------
@@ -194,6 +185,12 @@ DMA Fence Chain
.. kernel-doc:: include/linux/dma-fence-chain.h
:internal:
+DMA Fence unwrap
+~~~~~~~~~~~~~~~~
+
+.. kernel-doc:: include/linux/dma-fence-unwrap.h
+ :internal:
+
DMA Fence uABI/Sync File
~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/Documentation/driver-api/dmaengine/dmatest.rst b/Documentation/driver-api/dmaengine/dmatest.rst
index ee268d445d38..cf9859cd0b43 100644
--- a/Documentation/driver-api/dmaengine/dmatest.rst
+++ b/Documentation/driver-api/dmaengine/dmatest.rst
@@ -6,6 +6,16 @@ Andy Shevchenko <andriy.shevchenko@linux.intel.com>
This small document introduces how to test DMA drivers using dmatest module.
+The dmatest module tests DMA memcpy, memset, XOR and RAID6 P+Q operations using
+various lengths and various offsets into the source and destination buffers. It
+will initialize both buffers with a repeatable pattern and verify that the DMA
+engine copies the requested region and nothing more. It will also verify that
+the bytes aren't swapped around, and that the source buffer isn't modified.
+
+The dmatest module can be configured to test a specific channel. It can also
+test multiple channels at the same time, and it can start multiple threads
+competing for the same channel.
+
.. note::
The test suite works only on the channels that have at least one
capability of the following: DMA_MEMCPY (memory-to-memory), DMA_MEMSET
@@ -143,13 +153,14 @@ Part 5 - Handling channel allocation
Allocating Channels
-------------------
-Channels are required to be configured prior to starting the test run.
-Attempting to run the test without configuring the channels will fail.
+Channels do not need to be configured prior to starting a test run. Attempting
+to run the test without configuring the channels will result in testing any
+channels that are available.
Example::
% echo 1 > /sys/module/dmatest/parameters/run
- dmatest: Could not start test, no channels configured
+ dmatest: No channels configured, continue with any
Channels are registered using the "channel" parameter. Channels can be requested by their
name, once requested, the channel is registered and a pending thread is added to the test list.
diff --git a/Documentation/driver-api/dmaengine/provider.rst b/Documentation/driver-api/dmaengine/provider.rst
index ddb0a81a796c..ceac2a300e32 100644
--- a/Documentation/driver-api/dmaengine/provider.rst
+++ b/Documentation/driver-api/dmaengine/provider.rst
@@ -162,6 +162,19 @@ Currently, the types available are:
- The device is able to do memory to memory copies
+ - No matter what the overall size of the combined chunks for source and
+ destination is, only as many bytes as the smallest of the two will be
+ transmitted. That means the number and size of the scatter-gather buffers in
+ both lists need not be the same, and that the operation functionally is
+ equivalent to a ``strncpy`` where the ``count`` argument equals the smallest
+ total size of the two scatter-gather list buffers.
+
+ - It's usually used for copying pixel data between host memory and
+ memory-mapped GPU device memory, such as found on modern PCI video graphics
+ cards. The most immediate example is the OpenGL API function
+ ``glReadPielx()``, which might require a verbatim copy of a huge framebuffer
+ from local device memory onto host memory.
+
- DMA_XOR
- The device is able to perform XOR operations on memory areas
@@ -183,6 +196,12 @@ Currently, the types available are:
- The device is able to perform parity check using RAID6 P+Q
algorithm against a memory buffer.
+- DMA_MEMSET
+
+ - The device is able to fill memory with the provided pattern
+
+ - The pattern is treated as a single byte signed value.
+
- DMA_INTERRUPT
- The device is able to trigger a dummy transfer that will
@@ -434,7 +453,7 @@ supported.
- Should use dma_set_residue to report it
- In the case of a cyclic transfer, it should only take into
- account the current period.
+ account the total size of the cyclic buffer.
- Should return DMA_OUT_OF_ORDER if the device does not support in order
completion and is completing the operation out of order.
diff --git a/Documentation/driver-api/driver-model/devres.rst b/Documentation/driver-api/driver-model/devres.rst
index 148e19381b79..56082265e8e5 100644
--- a/Documentation/driver-api/driver-model/devres.rst
+++ b/Documentation/driver-api/driver-model/devres.rst
@@ -249,7 +249,7 @@ CLOCK
devm_clk_bulk_get()
devm_clk_bulk_get_all()
devm_clk_bulk_get_optional()
- devm_get_clk_from_childl()
+ devm_get_clk_from_child()
devm_clk_hw_register()
devm_of_clk_add_hw_provider()
devm_clk_hw_register_clkdev()
@@ -277,9 +277,9 @@ GPIO
devm_gpiochip_add_data()
devm_gpio_request()
devm_gpio_request_one()
- devm_gpio_free()
I2C
+ devm_i2c_add_adapter()
devm_i2c_new_dummy_device()
IIO
@@ -302,6 +302,7 @@ IO region
devm_release_region()
devm_release_resource()
devm_request_mem_region()
+ devm_request_free_mem_region()
devm_request_region()
devm_request_resource()
@@ -311,7 +312,6 @@ IOMAP
devm_ioremap()
devm_ioremap_uc()
devm_ioremap_wc()
- devm_ioremap_np()
devm_ioremap_resource() : checks resource, requests memory region, ioremaps
devm_ioremap_resource_wc()
devm_platform_ioremap_resource() : calls devm_ioremap_resource() for platform device
@@ -335,7 +335,7 @@ IRQ
devm_irq_alloc_descs_from()
devm_irq_alloc_generic_chip()
devm_irq_setup_generic_chip()
- devm_irq_sim_init()
+ devm_irq_domain_create_sim()
LED
devm_led_classdev_register()
@@ -368,6 +368,7 @@ MUX
devm_mux_chip_alloc()
devm_mux_chip_register()
devm_mux_control_get()
+ devm_mux_state_get()
NET
devm_alloc_etherdev()
@@ -392,7 +393,9 @@ PHY
PINCTRL
devm_pinctrl_get()
devm_pinctrl_put()
+ devm_pinctrl_get_select()
devm_pinctrl_register()
+ devm_pinctrl_register_and_init()
devm_pinctrl_unregister()
POWER
@@ -401,14 +404,24 @@ POWER
PWM
devm_pwm_get()
- devm_of_pwm_get()
devm_fwnode_pwm_get()
REGULATOR
+ devm_regulator_bulk_register_supply_alias()
devm_regulator_bulk_get()
+ devm_regulator_bulk_get_enable()
+ devm_regulator_bulk_put()
devm_regulator_get()
+ devm_regulator_get_enable()
+ devm_regulator_get_enable_optional()
+ devm_regulator_get_exclusive()
+ devm_regulator_get_optional()
+ devm_regulator_irq_helper()
devm_regulator_put()
devm_regulator_register()
+ devm_regulator_register_notifier()
+ devm_regulator_register_supply_alias()
+ devm_regulator_unregister_notifier()
RESET
devm_reset_control_get()
@@ -427,6 +440,8 @@ SLAVE DMA ENGINE
devm_acpi_dma_controller_register()
SPI
+ devm_spi_alloc_master()
+ devm_spi_alloc_slave()
devm_spi_register_master()
WATCHDOG
diff --git a/Documentation/driver-api/firewire.rst b/Documentation/driver-api/firewire.rst
index 94a2d7f01d99..d3cfa73cbb2b 100644
--- a/Documentation/driver-api/firewire.rst
+++ b/Documentation/driver-api/firewire.rst
@@ -19,7 +19,7 @@ of kernel interfaces is available via exported symbols in `firewire-core` module
Firewire char device data structures
====================================
-.. include:: /ABI/stable/firewire-cdev
+.. include:: ../ABI/stable/firewire-cdev
:literal:
.. kernel-doc:: include/uapi/linux/firewire-cdev.h
@@ -28,7 +28,7 @@ Firewire char device data structures
Firewire device probing and sysfs interfaces
============================================
-.. include:: /ABI/stable/sysfs-bus-firewire
+.. include:: ../ABI/stable/sysfs-bus-firewire
:literal:
.. kernel-doc:: drivers/firewire/core-device.c
diff --git a/Documentation/driver-api/firmware/core.rst b/Documentation/driver-api/firmware/core.rst
index 1d1688cbc078..803cd574bbd7 100644
--- a/Documentation/driver-api/firmware/core.rst
+++ b/Documentation/driver-api/firmware/core.rst
@@ -13,4 +13,5 @@ documents these features.
direct-fs-lookup
fallback-mechanisms
lookup-order
+ firmware-usage-guidelines
diff --git a/Documentation/driver-api/firmware/firmware-usage-guidelines.rst b/Documentation/driver-api/firmware/firmware-usage-guidelines.rst
new file mode 100644
index 000000000000..fdcfce42c6d2
--- /dev/null
+++ b/Documentation/driver-api/firmware/firmware-usage-guidelines.rst
@@ -0,0 +1,44 @@
+===================
+Firmware Guidelines
+===================
+
+Users switching to a newer kernel should *not* have to install newer
+firmware files to keep their hardware working. At the same time updated
+firmware files must not cause any regressions for users of older kernel
+releases.
+
+Drivers that use firmware from linux-firmware should follow the rules in
+this guide. (Where there is limited control of the firmware,
+i.e. company doesn't support Linux, firmwares sourced from misc places,
+then of course these rules will not apply strictly.)
+
+* Firmware files shall be designed in a way that it allows checking for
+ firmware ABI version changes. It is recommended that firmware files be
+ versioned with at least a major/minor version. It is suggested that
+ the firmware files in linux-firmware be named with some device
+ specific name, and just the major version. The firmware version should
+ be stored in the firmware header, or as an exception, as part of the
+ firmware file name, in order to let the driver detact any non-ABI
+ fixes/changes. The firmware files in linux-firmware should be
+ overwritten with the newest compatible major version. Newer major
+ version firmware shall remain compatible with all kernels that load
+ that major number.
+
+* If the kernel support for the hardware is normally inactive, or the
+ hardware isn't available for public consumption, this can
+ be ignored, until the first kernel release that enables that hardware.
+ This means no major version bumps without the kernel retaining
+ backwards compatibility for the older major versions. Minor version
+ bumps should not introduce new features that newer kernels depend on
+ non-optionally.
+
+* If a security fix needs lockstep firmware and kernel fixes in order to
+ be successful, then all supported major versions in the linux-firmware
+ repo that are required by currently supported stable/LTS kernels,
+ should be updated with the security fix. The kernel patches should
+ detect if the firmware is new enough to declare if the security issue
+ is fixed. All communications around security fixes should point at
+ both the firmware and kernel fixes. If a security fix requires
+ deprecating old major versions, then this should only be done as a
+ last option, and be stated clearly in all communications.
+
diff --git a/Documentation/driver-api/firmware/fw_upload.rst b/Documentation/driver-api/firmware/fw_upload.rst
new file mode 100644
index 000000000000..76922591e446
--- /dev/null
+++ b/Documentation/driver-api/firmware/fw_upload.rst
@@ -0,0 +1,126 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+===================
+Firmware Upload API
+===================
+
+A device driver that registers with the firmware loader will expose
+persistent sysfs nodes to enable users to initiate firmware updates for
+that device. It is the responsibility of the device driver and/or the
+device itself to perform any validation on the data received. Firmware
+upload uses the same *loading* and *data* sysfs files described in the
+documentation for firmware fallback. It also adds additional sysfs files
+to provide status on the transfer of the firmware image to the device.
+
+Register for firmware upload
+============================
+
+A device driver registers for firmware upload by calling
+firmware_upload_register(). Among the parameter list is a name to
+identify the device under /sys/class/firmware. A user may initiate a
+firmware upload by echoing a 1 to the *loading* sysfs file for the target
+device. Next, the user writes the firmware image to the *data* sysfs
+file. After writing the firmware data, the user echos 0 to the *loading*
+sysfs file to signal completion. Echoing 0 to *loading* also triggers the
+transfer of the firmware to the lower-lever device driver in the context
+of a kernel worker thread.
+
+To use the firmware upload API, write a driver that implements a set of
+ops. The probe function calls firmware_upload_register() and the remove
+function calls firmware_upload_unregister() such as::
+
+ static const struct fw_upload_ops m10bmc_ops = {
+ .prepare = m10bmc_sec_prepare,
+ .write = m10bmc_sec_write,
+ .poll_complete = m10bmc_sec_poll_complete,
+ .cancel = m10bmc_sec_cancel,
+ .cleanup = m10bmc_sec_cleanup,
+ };
+
+ static int m10bmc_sec_probe(struct platform_device *pdev)
+ {
+ const char *fw_name, *truncate;
+ struct m10bmc_sec *sec;
+ struct fw_upload *fwl;
+ unsigned int len;
+
+ sec = devm_kzalloc(&pdev->dev, sizeof(*sec), GFP_KERNEL);
+ if (!sec)
+ return -ENOMEM;
+
+ sec->dev = &pdev->dev;
+ sec->m10bmc = dev_get_drvdata(pdev->dev.parent);
+ dev_set_drvdata(&pdev->dev, sec);
+
+ fw_name = dev_name(sec->dev);
+ truncate = strstr(fw_name, ".auto");
+ len = (truncate) ? truncate - fw_name : strlen(fw_name);
+ sec->fw_name = kmemdup_nul(fw_name, len, GFP_KERNEL);
+
+ fwl = firmware_upload_register(sec->dev, sec->fw_name, &m10bmc_ops, sec);
+ if (IS_ERR(fwl)) {
+ dev_err(sec->dev, "Firmware Upload driver failed to start\n");
+ kfree(sec->fw_name);
+ return PTR_ERR(fwl);
+ }
+
+ sec->fwl = fwl;
+ return 0;
+ }
+
+ static int m10bmc_sec_remove(struct platform_device *pdev)
+ {
+ struct m10bmc_sec *sec = dev_get_drvdata(&pdev->dev);
+
+ firmware_upload_unregister(sec->fwl);
+ kfree(sec->fw_name);
+ return 0;
+ }
+
+firmware_upload_register
+------------------------
+.. kernel-doc:: drivers/base/firmware_loader/sysfs_upload.c
+ :identifiers: firmware_upload_register
+
+firmware_upload_unregister
+--------------------------
+.. kernel-doc:: drivers/base/firmware_loader/sysfs_upload.c
+ :identifiers: firmware_upload_unregister
+
+Firmware Upload Ops
+-------------------
+.. kernel-doc:: include/linux/firmware.h
+ :identifiers: fw_upload_ops
+
+Firmware Upload Progress Codes
+------------------------------
+The following progress codes are used internally by the firmware loader.
+Corresponding strings are reported through the status sysfs node that
+is described below and are documented in the ABI documentation.
+
+.. kernel-doc:: drivers/base/firmware_loader/sysfs_upload.h
+ :identifiers: fw_upload_prog
+
+Firmware Upload Error Codes
+---------------------------
+The following error codes may be returned by the driver ops in case of
+failure:
+
+.. kernel-doc:: include/linux/firmware.h
+ :identifiers: fw_upload_err
+
+Sysfs Attributes
+================
+
+In addition to the *loading* and *data* sysfs files, there are additional
+sysfs files to monitor the status of the data transfer to the target
+device and to determine the final pass/fail status of the transfer.
+Depending on the device and the size of the firmware image, a firmware
+update could take milliseconds or minutes.
+
+The additional sysfs files are:
+
+* status - provides an indication of the progress of a firmware update
+* error - provides error information for a failed firmware update
+* remaining_size - tracks the data transfer portion of an update
+* cancel - echo 1 to this file to cancel the update
diff --git a/Documentation/driver-api/firmware/index.rst b/Documentation/driver-api/firmware/index.rst
index 57415d657173..9d2c19dc8e36 100644
--- a/Documentation/driver-api/firmware/index.rst
+++ b/Documentation/driver-api/firmware/index.rst
@@ -8,6 +8,7 @@ Linux Firmware API
core
efi/index
request_firmware
+ fw_upload
other_interfaces
.. only:: subproject and html
diff --git a/Documentation/driver-api/firmware/other_interfaces.rst b/Documentation/driver-api/firmware/other_interfaces.rst
index b81794e0cfbb..06ac89adaafb 100644
--- a/Documentation/driver-api/firmware/other_interfaces.rst
+++ b/Documentation/driver-api/firmware/other_interfaces.rst
@@ -13,6 +13,12 @@ EDD Interfaces
.. kernel-doc:: drivers/firmware/edd.c
:internal:
+Generic System Framebuffers Interface
+-------------------------------------
+
+.. kernel-doc:: drivers/firmware/sysfb.c
+ :export:
+
Intel Stratix10 SoC Service Layer
---------------------------------
Some features of the Intel Stratix10 SoC require a level of privilege
diff --git a/Documentation/driver-api/fpga/fpga-bridge.rst b/Documentation/driver-api/fpga/fpga-bridge.rst
index 8d650b4e2ce6..604208534095 100644
--- a/Documentation/driver-api/fpga/fpga-bridge.rst
+++ b/Documentation/driver-api/fpga/fpga-bridge.rst
@@ -6,8 +6,7 @@ API to implement a new FPGA bridge
* struct fpga_bridge - The FPGA Bridge structure
* struct fpga_bridge_ops - Low level Bridge driver ops
-* devm_fpga_bridge_create() - Allocate and init a bridge struct
-* fpga_bridge_register() - Register a bridge
+* fpga_bridge_register() - Create and register a bridge
* fpga_bridge_unregister() - Unregister a bridge
.. kernel-doc:: include/linux/fpga/fpga-bridge.h
@@ -17,9 +16,6 @@ API to implement a new FPGA bridge
:functions: fpga_bridge_ops
.. kernel-doc:: drivers/fpga/fpga-bridge.c
- :functions: devm_fpga_bridge_create
-
-.. kernel-doc:: drivers/fpga/fpga-bridge.c
:functions: fpga_bridge_register
.. kernel-doc:: drivers/fpga/fpga-bridge.c
diff --git a/Documentation/driver-api/fpga/fpga-mgr.rst b/Documentation/driver-api/fpga/fpga-mgr.rst
index 4d926b452cb3..49c0a9512653 100644
--- a/Documentation/driver-api/fpga/fpga-mgr.rst
+++ b/Documentation/driver-api/fpga/fpga-mgr.rst
@@ -24,7 +24,7 @@ How to support a new FPGA device
--------------------------------
To add another FPGA manager, write a driver that implements a set of ops. The
-probe function calls fpga_mgr_register(), such as::
+probe function calls fpga_mgr_register() or fpga_mgr_register_full(), such as::
static const struct fpga_manager_ops socfpga_fpga_ops = {
.write_init = socfpga_fpga_ops_configure_init,
@@ -49,14 +49,14 @@ probe function calls fpga_mgr_register(), such as::
* them in priv
*/
- mgr = devm_fpga_mgr_create(dev, "Altera SOCFPGA FPGA Manager",
- &socfpga_fpga_ops, priv);
- if (!mgr)
- return -ENOMEM;
+ mgr = fpga_mgr_register(dev, "Altera SOCFPGA FPGA Manager",
+ &socfpga_fpga_ops, priv);
+ if (IS_ERR(mgr))
+ return PTR_ERR(mgr);
platform_set_drvdata(pdev, mgr);
- return fpga_mgr_register(mgr);
+ return 0;
}
static int socfpga_fpga_remove(struct platform_device *pdev)
@@ -68,18 +68,38 @@ probe function calls fpga_mgr_register(), such as::
return 0;
}
+Alternatively, the probe function could call one of the resource managed
+register functions, devm_fpga_mgr_register() or devm_fpga_mgr_register_full().
+When these functions are used, the parameter syntax is the same, but the call
+to fpga_mgr_unregister() should be removed. In the above example, the
+socfpga_fpga_remove() function would not be required.
The ops will implement whatever device specific register writes are needed to
do the programming sequence for this particular FPGA. These ops return 0 for
success or negative error codes otherwise.
The programming sequence is::
- 1. .write_init
- 2. .write or .write_sg (may be called once or multiple times)
- 3. .write_complete
-
-The .write_init function will prepare the FPGA to receive the image data. The
-buffer passed into .write_init will be at most .initial_header_size bytes long;
+ 1. .parse_header (optional, may be called once or multiple times)
+ 2. .write_init
+ 3. .write or .write_sg (may be called once or multiple times)
+ 4. .write_complete
+
+The .parse_header function will set header_size and data_size to
+struct fpga_image_info. Before parse_header call, header_size is initialized
+with initial_header_size. If flag skip_header of fpga_manager_ops is true,
+.write function will get image buffer starting at header_size offset from the
+beginning. If data_size is set, .write function will get data_size bytes of
+the image buffer, otherwise .write will get data up to the end of image buffer.
+This will not affect .write_sg, .write_sg will still get whole image in
+sg_table form. If FPGA image is already mapped as a single contiguous buffer,
+whole buffer will be passed into .parse_header. If image is in scatter-gather
+form, core code will buffer up at least .initial_header_size before the first
+call of .parse_header, if it is not enough, .parse_header should set desired
+size into info->header_size and return -EAGAIN, then it will be called again
+with greater part of image buffer on the input.
+
+The .write_init function will prepare the FPGA to receive the image data. The
+buffer passed into .write_init will be at least info->header_size bytes long;
if the whole bitstream is not immediately available then the core code will
buffer up at least this much before starting.
@@ -104,8 +124,14 @@ API for implementing a new FPGA Manager driver
* ``fpga_mgr_states`` - Values for :c:expr:`fpga_manager->state`.
* struct fpga_manager - the FPGA manager struct
* struct fpga_manager_ops - Low level FPGA manager driver ops
-* devm_fpga_mgr_create() - Allocate and init a manager struct
-* fpga_mgr_register() - Register an FPGA manager
+* struct fpga_manager_info - Parameter structure for fpga_mgr_register_full()
+* fpga_mgr_register_full() - Create and register an FPGA manager using the
+ fpga_mgr_info structure to provide the full flexibility of options
+* fpga_mgr_register() - Create and register an FPGA manager using standard
+ arguments
+* devm_fpga_mgr_register_full() - Resource managed version of
+ fpga_mgr_register_full()
+* devm_fpga_mgr_register() - Resource managed version of fpga_mgr_register()
* fpga_mgr_unregister() - Unregister an FPGA manager
.. kernel-doc:: include/linux/fpga/fpga-mgr.h
@@ -117,11 +143,20 @@ API for implementing a new FPGA Manager driver
.. kernel-doc:: include/linux/fpga/fpga-mgr.h
:functions: fpga_manager_ops
+.. kernel-doc:: include/linux/fpga/fpga-mgr.h
+ :functions: fpga_manager_info
+
.. kernel-doc:: drivers/fpga/fpga-mgr.c
- :functions: devm_fpga_mgr_create
+ :functions: fpga_mgr_register_full
.. kernel-doc:: drivers/fpga/fpga-mgr.c
:functions: fpga_mgr_register
.. kernel-doc:: drivers/fpga/fpga-mgr.c
+ :functions: devm_fpga_mgr_register_full
+
+.. kernel-doc:: drivers/fpga/fpga-mgr.c
+ :functions: devm_fpga_mgr_register
+
+.. kernel-doc:: drivers/fpga/fpga-mgr.c
:functions: fpga_mgr_unregister
diff --git a/Documentation/driver-api/fpga/fpga-region.rst b/Documentation/driver-api/fpga/fpga-region.rst
index 2636a27c11b2..dc55d60a0b4a 100644
--- a/Documentation/driver-api/fpga/fpga-region.rst
+++ b/Documentation/driver-api/fpga/fpga-region.rst
@@ -46,8 +46,11 @@ API to add a new FPGA region
----------------------------
* struct fpga_region - The FPGA region struct
-* devm_fpga_region_create() - Allocate and init a region struct
-* fpga_region_register() - Register an FPGA region
+* struct fpga_region_info - Parameter structure for fpga_region_register_full()
+* fpga_region_register_full() - Create and register an FPGA region using the
+ fpga_region_info structure to provide the full flexibility of options
+* fpga_region_register() - Create and register an FPGA region using standard
+ arguments
* fpga_region_unregister() - Unregister an FPGA region
The FPGA region's probe function will need to get a reference to the FPGA
@@ -75,8 +78,11 @@ following APIs to handle building or tearing down that list.
.. kernel-doc:: include/linux/fpga/fpga-region.h
:functions: fpga_region
+.. kernel-doc:: include/linux/fpga/fpga-region.h
+ :functions: fpga_region_info
+
.. kernel-doc:: drivers/fpga/fpga-region.c
- :functions: devm_fpga_region_create
+ :functions: fpga_region_register_full
.. kernel-doc:: drivers/fpga/fpga-region.c
:functions: fpga_region_register
diff --git a/Documentation/driver-api/generic-counter.rst b/Documentation/driver-api/generic-counter.rst
index 1b487a331467..71ccc30e586b 100644
--- a/Documentation/driver-api/generic-counter.rst
+++ b/Documentation/driver-api/generic-counter.rst
@@ -262,11 +262,11 @@ order to communicate with the device: to read and write various Signals
and Counts, and to set and get the "action mode" and "function mode" for
various Synapses and Counts respectively.
-A defined counter_device structure may be registered to the system by
-passing it to the counter_register function, and unregistered by passing
-it to the counter_unregister function. Similarly, the
-devm_counter_register function may be used if device memory-managed
-registration is desired.
+A counter_device structure is allocated using counter_alloc() and then
+registered to the system by passing it to the counter_add() function, and
+unregistered by passing it to the counter_unregister function. There are
+device managed variants of these functions: devm_counter_alloc() and
+devm_counter_add().
The struct counter_comp structure is used to define counter extensions
for Signals, Synapses, and Counts.
diff --git a/Documentation/driver-api/gpio/board.rst b/Documentation/driver-api/gpio/board.rst
index 191fa867826a..b33aa04f213f 100644
--- a/Documentation/driver-api/gpio/board.rst
+++ b/Documentation/driver-api/gpio/board.rst
@@ -6,7 +6,7 @@ This document explains how GPIOs can be assigned to given devices and functions.
Note that it only applies to the new descriptor-based interface. For a
description of the deprecated integer-based GPIO interface please refer to
-gpio-legacy.txt (actually, there is no real mapping possible with the old
+legacy.rst (actually, there is no real mapping possible with the old
interface; you just fetch an integer from somewhere and request the
corresponding GPIO).
@@ -71,14 +71,14 @@ with the help of _DSD (Device Specific Data), introduced in ACPI 5.1::
Device (FOO) {
Name (_CRS, ResourceTemplate () {
- GpioIo (Exclusive, ..., IoRestrictionOutputOnly,
- "\\_SB.GPI0") {15} // red
- GpioIo (Exclusive, ..., IoRestrictionOutputOnly,
- "\\_SB.GPI0") {16} // green
- GpioIo (Exclusive, ..., IoRestrictionOutputOnly,
- "\\_SB.GPI0") {17} // blue
- GpioIo (Exclusive, ..., IoRestrictionOutputOnly,
- "\\_SB.GPI0") {1} // power
+ GpioIo (Exclusive, PullUp, 0, 0, IoRestrictionOutputOnly,
+ "\\_SB.GPI0", 0, ResourceConsumer) { 15 } // red
+ GpioIo (Exclusive, PullUp, 0, 0, IoRestrictionOutputOnly,
+ "\\_SB.GPI0", 0, ResourceConsumer) { 16 } // green
+ GpioIo (Exclusive, PullUp, 0, 0, IoRestrictionOutputOnly,
+ "\\_SB.GPI0", 0, ResourceConsumer) { 17 } // blue
+ GpioIo (Exclusive, PullNone, 0, 0, IoRestrictionOutputOnly,
+ "\\_SB.GPI0", 0, ResourceConsumer) { 1 } // power
})
Name (_DSD, Package () {
@@ -92,10 +92,7 @@ with the help of _DSD (Device Specific Data), introduced in ACPI 5.1::
^FOO, 2, 0, 1,
}
},
- Package () {
- "power-gpios",
- Package () {^FOO, 3, 0, 0},
- },
+ Package () { "power-gpios", Package () { ^FOO, 3, 0, 0 } },
}
})
}
diff --git a/Documentation/driver-api/gpio/consumer.rst b/Documentation/driver-api/gpio/consumer.rst
index 47869ca8ccf0..de6fc79ad6f0 100644
--- a/Documentation/driver-api/gpio/consumer.rst
+++ b/Documentation/driver-api/gpio/consumer.rst
@@ -4,7 +4,7 @@ GPIO Descriptor Consumer Interface
This document describes the consumer interface of the GPIO framework. Note that
it describes the new descriptor-based interface. For a description of the
-deprecated integer-based GPIO interface please refer to gpio-legacy.txt.
+deprecated integer-based GPIO interface please refer to legacy.rst.
Guidelines for GPIOs consumers
@@ -78,7 +78,7 @@ whether the line is configured active high or active low (see
The two last flags are used for use cases where open drain is mandatory, such
as I2C: if the line is not already configured as open drain in the mappings
-(see board.txt), then open drain will be enforced anyway and a warning will be
+(see board.rst), then open drain will be enforced anyway and a warning will be
printed that the board configuration needs to be updated to match the use case.
Both functions return either a valid GPIO descriptor, or an error code checkable
@@ -114,7 +114,7 @@ For a function using multiple GPIOs all of those can be obtained with one call::
This function returns a struct gpio_descs which contains an array of
descriptors. It also contains a pointer to a gpiolib private structure which,
-if passed back to get/set array functions, may speed up I/O proocessing::
+if passed back to get/set array functions, may speed up I/O processing::
struct gpio_descs {
struct gpio_array *info;
@@ -270,7 +270,7 @@ driven.
The same is applicable for open drain or open source output lines: those do not
actively drive their output high (open drain) or low (open source), they just
switch their output to a high impedance value. The consumer should not need to
-care. (For details read about open drain in driver.txt.)
+care. (For details read about open drain in driver.rst.)
With this, all the gpiod_set_(array)_value_xxx() functions interpret the
parameter "value" as "asserted" ("1") or "de-asserted" ("0"). The physical line
diff --git a/Documentation/driver-api/gpio/driver.rst b/Documentation/driver-api/gpio/driver.rst
index bbc53920d4dd..6baaeab79534 100644
--- a/Documentation/driver-api/gpio/driver.rst
+++ b/Documentation/driver-api/gpio/driver.rst
@@ -119,7 +119,7 @@ GPIO lines with debounce support
Debouncing is a configuration set to a pin indicating that it is connected to
a mechanical switch or button, or similar that may bounce. Bouncing means the
line is pulled high/low quickly at very short intervals for mechanical
-reasons. This can result in the value being unstable or irqs fireing repeatedly
+reasons. This can result in the value being unstable or irqs firing repeatedly
unless the line is debounced.
Debouncing in practice involves setting up a timer when something happens on
@@ -219,7 +219,7 @@ use a trick: when a line is set as output, if the line is flagged as open
drain, and the IN output value is low, it will be driven low as usual. But
if the IN output value is set to high, it will instead *NOT* be driven high,
instead it will be switched to input, as input mode is high impedance, thus
-achieveing an "open drain emulation" of sorts: electrically the behaviour will
+achieving an "open drain emulation" of sorts: electrically the behaviour will
be identical, with the exception of possible hardware glitches when switching
the mode of the line.
@@ -417,30 +417,68 @@ struct gpio_irq_chip inside struct gpio_chip before adding the gpio_chip.
If you do this, the additional irq_chip will be set up by gpiolib at the
same time as setting up the rest of the GPIO functionality. The following
is a typical example of a chained cascaded interrupt handler using
-the gpio_irq_chip:
+the gpio_irq_chip. Note how the mask/unmask (or disable/enable) functions
+call into the core gpiolib code:
.. code-block:: c
- /* Typical state container with dynamic irqchip */
+ /* Typical state container */
struct my_gpio {
struct gpio_chip gc;
- struct irq_chip irq;
+ };
+
+ static void my_gpio_mask_irq(struct irq_data *d)
+ {
+ struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+ irq_hw_number_t hwirq = irqd_to_hwirq(d);
+
+ /*
+ * Perform any necessary action to mask the interrupt,
+ * and then call into the core code to synchronise the
+ * state.
+ */
+
+ gpiochip_disable_irq(gc, hwirq);
+ }
+
+ static void my_gpio_unmask_irq(struct irq_data *d)
+ {
+ struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+ irq_hw_number_t hwirq = irqd_to_hwirq(d);
+
+ gpiochip_enable_irq(gc, hwirq);
+
+ /*
+ * Perform any necessary action to unmask the interrupt,
+ * after having called into the core code to synchronise
+ * the state.
+ */
+ }
+
+ /*
+ * Statically populate the irqchip. Note that it is made const
+ * (further indicated by the IRQCHIP_IMMUTABLE flag), and that
+ * the GPIOCHIP_IRQ_RESOURCE_HELPER macro adds some extra
+ * callbacks to the structure.
+ */
+ static const struct irq_chip my_gpio_irq_chip = {
+ .name = "my_gpio_irq",
+ .irq_ack = my_gpio_ack_irq,
+ .irq_mask = my_gpio_mask_irq,
+ .irq_unmask = my_gpio_unmask_irq,
+ .irq_set_type = my_gpio_set_irq_type,
+ .flags = IRQCHIP_IMMUTABLE,
+ /* Provide the gpio resource callbacks */
+ GPIOCHIP_IRQ_RESOURCE_HELPERS,
};
int irq; /* from platform etc */
struct my_gpio *g;
struct gpio_irq_chip *girq;
- /* Set up the irqchip dynamically */
- g->irq.name = "my_gpio_irq";
- g->irq.irq_ack = my_gpio_ack_irq;
- g->irq.irq_mask = my_gpio_mask_irq;
- g->irq.irq_unmask = my_gpio_unmask_irq;
- g->irq.irq_set_type = my_gpio_set_irq_type;
-
/* Get a pointer to the gpio_irq_chip */
girq = &g->gc.irq;
- girq->chip = &g->irq;
+ gpio_irq_chip_set_chip(girq, &my_gpio_irq_chip);
girq->parent_handler = ftgpio_gpio_irq_handler;
girq->num_parents = 1;
girq->parents = devm_kcalloc(dev, 1, sizeof(*girq->parents),
@@ -458,23 +496,60 @@ the interrupt separately and go with it:
.. code-block:: c
- /* Typical state container with dynamic irqchip */
+ /* Typical state container */
struct my_gpio {
struct gpio_chip gc;
- struct irq_chip irq;
+ };
+
+ static void my_gpio_mask_irq(struct irq_data *d)
+ {
+ struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+ irq_hw_number_t hwirq = irqd_to_hwirq(d);
+
+ /*
+ * Perform any necessary action to mask the interrupt,
+ * and then call into the core code to synchronise the
+ * state.
+ */
+
+ gpiochip_disable_irq(gc, hwirq);
+ }
+
+ static void my_gpio_unmask_irq(struct irq_data *d)
+ {
+ struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+ irq_hw_number_t hwirq = irqd_to_hwirq(d);
+
+ gpiochip_enable_irq(gc, hwirq);
+
+ /*
+ * Perform any necessary action to unmask the interrupt,
+ * after having called into the core code to synchronise
+ * the state.
+ */
+ }
+
+ /*
+ * Statically populate the irqchip. Note that it is made const
+ * (further indicated by the IRQCHIP_IMMUTABLE flag), and that
+ * the GPIOCHIP_IRQ_RESOURCE_HELPER macro adds some extra
+ * callbacks to the structure.
+ */
+ static const struct irq_chip my_gpio_irq_chip = {
+ .name = "my_gpio_irq",
+ .irq_ack = my_gpio_ack_irq,
+ .irq_mask = my_gpio_mask_irq,
+ .irq_unmask = my_gpio_unmask_irq,
+ .irq_set_type = my_gpio_set_irq_type,
+ .flags = IRQCHIP_IMMUTABLE,
+ /* Provide the gpio resource callbacks */
+ GPIOCHIP_IRQ_RESOURCE_HELPERS,
};
int irq; /* from platform etc */
struct my_gpio *g;
struct gpio_irq_chip *girq;
- /* Set up the irqchip dynamically */
- g->irq.name = "my_gpio_irq";
- g->irq.irq_ack = my_gpio_ack_irq;
- g->irq.irq_mask = my_gpio_mask_irq;
- g->irq.irq_unmask = my_gpio_unmask_irq;
- g->irq.irq_set_type = my_gpio_set_irq_type;
-
ret = devm_request_threaded_irq(dev, irq, NULL,
irq_thread_fn, IRQF_ONESHOT, "my-chip", g);
if (ret < 0)
@@ -482,7 +557,7 @@ the interrupt separately and go with it:
/* Get a pointer to the gpio_irq_chip */
girq = &g->gc.irq;
- girq->chip = &g->irq;
+ gpio_irq_chip_set_chip(girq, &my_gpio_irq_chip);
/* This will let us handle the parent IRQ in the driver */
girq->parent_handler = NULL;
girq->num_parents = 0;
@@ -500,24 +575,63 @@ In this case the typical set-up will look like this:
/* Typical state container with dynamic irqchip */
struct my_gpio {
struct gpio_chip gc;
- struct irq_chip irq;
struct fwnode_handle *fwnode;
};
- int irq; /* from platform etc */
+ static void my_gpio_mask_irq(struct irq_data *d)
+ {
+ struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+ irq_hw_number_t hwirq = irqd_to_hwirq(d);
+
+ /*
+ * Perform any necessary action to mask the interrupt,
+ * and then call into the core code to synchronise the
+ * state.
+ */
+
+ gpiochip_disable_irq(gc, hwirq);
+ irq_mask_mask_parent(d);
+ }
+
+ static void my_gpio_unmask_irq(struct irq_data *d)
+ {
+ struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+ irq_hw_number_t hwirq = irqd_to_hwirq(d);
+
+ gpiochip_enable_irq(gc, hwirq);
+
+ /*
+ * Perform any necessary action to unmask the interrupt,
+ * after having called into the core code to synchronise
+ * the state.
+ */
+
+ irq_mask_unmask_parent(d);
+ }
+
+ /*
+ * Statically populate the irqchip. Note that it is made const
+ * (further indicated by the IRQCHIP_IMMUTABLE flag), and that
+ * the GPIOCHIP_IRQ_RESOURCE_HELPER macro adds some extra
+ * callbacks to the structure.
+ */
+ static const struct irq_chip my_gpio_irq_chip = {
+ .name = "my_gpio_irq",
+ .irq_ack = my_gpio_ack_irq,
+ .irq_mask = my_gpio_mask_irq,
+ .irq_unmask = my_gpio_unmask_irq,
+ .irq_set_type = my_gpio_set_irq_type,
+ .flags = IRQCHIP_IMMUTABLE,
+ /* Provide the gpio resource callbacks */
+ GPIOCHIP_IRQ_RESOURCE_HELPERS,
+ };
+
struct my_gpio *g;
struct gpio_irq_chip *girq;
- /* Set up the irqchip dynamically */
- g->irq.name = "my_gpio_irq";
- g->irq.irq_ack = my_gpio_ack_irq;
- g->irq.irq_mask = my_gpio_mask_irq;
- g->irq.irq_unmask = my_gpio_unmask_irq;
- g->irq.irq_set_type = my_gpio_set_irq_type;
-
/* Get a pointer to the gpio_irq_chip */
girq = &g->gc.irq;
- girq->chip = &g->irq;
+ gpio_irq_chip_set_chip(girq, &my_gpio_irq_chip);
girq->default_type = IRQ_TYPE_NONE;
girq->handler = handle_bad_irq;
girq->fwnode = g->fwnode;
@@ -528,7 +642,7 @@ In this case the typical set-up will look like this:
As you can see pretty similar, but you do not supply a parent handler for
the IRQ, instead a parent irqdomain, an fwnode for the hardware and
-a funcion .child_to_parent_hwirq() that has the purpose of looking up
+a function .child_to_parent_hwirq() that has the purpose of looking up
the parent hardware irq from a child (i.e. this gpio chip) hardware irq.
As always it is good to look at examples in the kernel tree for advice
on how to find the required pieces.
@@ -605,8 +719,9 @@ When implementing an irqchip inside a GPIO driver, these two functions should
typically be called in the .irq_disable() and .irq_enable() callbacks from the
irqchip.
-When using the gpiolib irqchip helpers, these callbacks are automatically
-assigned.
+When IRQCHIP_IMMUTABLE is not advertised by the irqchip, these callbacks
+are automatically assigned. This behaviour is deprecated and on its way
+to be removed from the kernel.
Real-Time compliance for GPIO IRQ chips
diff --git a/Documentation/driver-api/gpio/intro.rst b/Documentation/driver-api/gpio/intro.rst
index 2e924fb5b3d5..c9c19243b97f 100644
--- a/Documentation/driver-api/gpio/intro.rst
+++ b/Documentation/driver-api/gpio/intro.rst
@@ -14,12 +14,12 @@ Due to the history of GPIO interfaces in the kernel, there are two different
ways to obtain and use GPIOs:
- The descriptor-based interface is the preferred way to manipulate GPIOs,
- and is described by all the files in this directory excepted gpio-legacy.txt.
+ and is described by all the files in this directory excepted legacy.rst.
- The legacy integer-based interface which is considered deprecated (but still
- usable for compatibility reasons) is documented in gpio-legacy.txt.
+ usable for compatibility reasons) is documented in legacy.rst.
The remainder of this document applies to the new descriptor-based interface.
-gpio-legacy.txt contains the same information applied to the legacy
+legacy.rst contains the same information applied to the legacy
integer-based interface.
diff --git a/Documentation/driver-api/gpio/using-gpio.rst b/Documentation/driver-api/gpio/using-gpio.rst
index 64c8d3f76c3a..894d88855d73 100644
--- a/Documentation/driver-api/gpio/using-gpio.rst
+++ b/Documentation/driver-api/gpio/using-gpio.rst
@@ -44,7 +44,7 @@ These devices will appear on the system as ``/dev/gpiochip0`` thru
found in the kernel tree ``tools/gpio`` subdirectory.
For structured and managed applications, we recommend that you make use of the
-libgpiod_ library. This provides helper abstractions, command line utlities
+libgpiod_ library. This provides helper abstractions, command line utilities
and arbitration for multiple simultaneous consumers on the same GPIO chip.
.. _libgpiod: https://git.kernel.org/pub/scm/libs/libgpiod/libgpiod.git/
diff --git a/Documentation/driver-api/hte/hte.rst b/Documentation/driver-api/hte/hte.rst
new file mode 100644
index 000000000000..153f3233c100
--- /dev/null
+++ b/Documentation/driver-api/hte/hte.rst
@@ -0,0 +1,79 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+============================================
+The Linux Hardware Timestamping Engine (HTE)
+============================================
+
+:Author: Dipen Patel
+
+Introduction
+------------
+
+Certain devices have built in hardware timestamping engines which can
+monitor sets of system signals, lines, buses etc... in realtime for state
+change; upon detecting the change they can automatically store the timestamp at
+the moment of occurrence. Such functionality may help achieve better accuracy
+in obtaining timestamps than using software counterparts i.e. ktime and
+friends.
+
+This document describes the API that can be used by hardware timestamping
+engine provider and consumer drivers that want to use the hardware timestamping
+engine (HTE) framework. Both consumers and providers must include
+``#include <linux/hte.h>``.
+
+The HTE framework APIs for the providers
+----------------------------------------
+
+.. kernel-doc:: drivers/hte/hte.c
+ :functions: devm_hte_register_chip hte_push_ts_ns
+
+The HTE framework APIs for the consumers
+----------------------------------------
+
+.. kernel-doc:: drivers/hte/hte.c
+ :functions: hte_init_line_attr hte_ts_get hte_ts_put devm_hte_request_ts_ns hte_request_ts_ns hte_enable_ts hte_disable_ts of_hte_req_count hte_get_clk_src_info
+
+The HTE framework public structures
+-----------------------------------
+.. kernel-doc:: include/linux/hte.h
+
+More on the HTE timestamp data
+------------------------------
+The ``struct hte_ts_data`` is used to pass timestamp details between the
+consumers and the providers. It expresses timestamp data in nanoseconds in
+u64. An example of the typical timestamp data life cycle, for the GPIO line is
+as follows::
+
+ - Monitors GPIO line change.
+ - Detects the state change on GPIO line.
+ - Converts timestamps in nanoseconds.
+ - Stores GPIO raw level in raw_level variable if the provider has that
+ hardware capability.
+ - Pushes this hte_ts_data object to HTE subsystem.
+ - HTE subsystem increments seq counter and invokes consumer provided callback.
+ Based on callback return value, the HTE core invokes secondary callback in
+ the thread context.
+
+HTE subsystem debugfs attributes
+--------------------------------
+HTE subsystem creates debugfs attributes at ``/sys/kernel/debug/hte/``.
+It also creates line/signal-related debugfs attributes at
+``/sys/kernel/debug/hte/<provider>/<label or line id>/``. Note that these
+attributes are read-only.
+
+`ts_requested`
+ The total number of entities requested from the given provider,
+ where entity is specified by the provider and could represent
+ lines, GPIO, chip signals, buses etc...
+ The attribute will be available at
+ ``/sys/kernel/debug/hte/<provider>/``.
+
+`total_ts`
+ The total number of entities supported by the provider.
+ The attribute will be available at
+ ``/sys/kernel/debug/hte/<provider>/``.
+
+`dropped_timestamps`
+ The dropped timestamps for a given line.
+ The attribute will be available at
+ ``/sys/kernel/debug/hte/<provider>/<label or line id>/``.
diff --git a/Documentation/driver-api/hte/index.rst b/Documentation/driver-api/hte/index.rst
new file mode 100644
index 000000000000..9f43301c05dc
--- /dev/null
+++ b/Documentation/driver-api/hte/index.rst
@@ -0,0 +1,22 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+============================================
+The Linux Hardware Timestamping Engine (HTE)
+============================================
+
+The HTE Subsystem
+=================
+
+.. toctree::
+ :maxdepth: 1
+
+ hte
+
+HTE Tegra Provider
+==================
+
+.. toctree::
+ :maxdepth: 1
+
+ tegra194-hte
+
diff --git a/Documentation/driver-api/hte/tegra194-hte.rst b/Documentation/driver-api/hte/tegra194-hte.rst
new file mode 100644
index 000000000000..f2d617265546
--- /dev/null
+++ b/Documentation/driver-api/hte/tegra194-hte.rst
@@ -0,0 +1,48 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+HTE Kernel provider driver
+==========================
+
+Description
+-----------
+The Nvidia tegra194 HTE provider driver implements two GTE
+(Generic Timestamping Engine) instances: 1) GPIO GTE and 2) LIC
+(Legacy Interrupt Controller) IRQ GTE. Both GTE instances get the
+timestamp from the system counter TSC which has 31.25MHz clock rate, and the
+driver converts clock tick rate to nanoseconds before storing it as timestamp
+value.
+
+GPIO GTE
+--------
+
+This GTE instance timestamps GPIO in real time. For that to happen GPIO
+needs to be configured as input. The always on (AON) GPIO controller instance
+supports timestamping GPIOs in real time and it has 39 GPIO lines. The GPIO GTE
+and AON GPIO controller are tightly coupled as it requires very specific bits
+to be set in GPIO config register before GPIO GTE can be used, for that GPIOLIB
+adds two optional APIs as below. The GPIO GTE code supports both kernel
+and userspace consumers. The kernel space consumers can directly talk to HTE
+subsystem while userspace consumers timestamp requests go through GPIOLIB CDEV
+framework to HTE subsystem.
+
+See gpiod_enable_hw_timestamp_ns() and gpiod_disable_hw_timestamp_ns().
+
+For userspace consumers, GPIO_V2_LINE_FLAG_EVENT_CLOCK_HTE flag must be
+specified during IOCTL calls. Refer to ``tools/gpio/gpio-event-mon.c``, which
+returns the timestamp in nanoseconds.
+
+LIC (Legacy Interrupt Controller) IRQ GTE
+-----------------------------------------
+
+This GTE instance timestamps LIC IRQ lines in real time. There are 352 IRQ
+lines which this instance can add timestamps to in real time. The hte
+devicetree binding described at ``Documentation/devicetree/bindings/timestamp``
+provides an example of how a consumer can request an IRQ line. Since it is a
+one-to-one mapping with IRQ GTE provider, consumers can simply specify the IRQ
+number that they are interested in. There is no userspace consumer support for
+this GTE instance in the HTE framework.
+
+The provider source code of both IRQ and GPIO GTE instances is located at
+``drivers/hte/hte-tegra194.c``. The test driver
+``drivers/hte/hte-tegra194-test.c`` demonstrates HTE API usage for both IRQ
+and GPIO GTE.
diff --git a/Documentation/driver-api/index.rst b/Documentation/driver-api/index.rst
index c57c609ad2eb..d3a58f77328e 100644
--- a/Documentation/driver-api/index.rst
+++ b/Documentation/driver-api/index.rst
@@ -27,6 +27,7 @@ available subsections can be seen below.
component
message-based
infiniband
+ aperture
frame-buffer
regulator
reset
@@ -101,11 +102,14 @@ available subsections can be seen below.
surface_aggregator/index
switchtec
sync_file
+ tty/index
vfio-mediated-device
vfio
+ vfio-pci-device-specific-driver-acceptance
xilinx/index
xillybus
zorro
+ hte/index
.. only:: subproject and html
diff --git a/Documentation/driver-api/isa.rst b/Documentation/driver-api/isa.rst
index def4a7b690b5..3df1b1696524 100644
--- a/Documentation/driver-api/isa.rst
+++ b/Documentation/driver-api/isa.rst
@@ -100,7 +100,7 @@ I believe platform_data is available for this, but if rather not, moving
the isa_driver pointer to the private struct isa_dev is ofcourse fine as
well.
-Then, if the the driver did not provide a .match, it matches. If it did,
+Then, if the driver did not provide a .match, it matches. If it did,
the driver match() method is called to determine a match.
If it did **not** match, dev->platform_data is reset to indicate this to
diff --git a/Documentation/driver-api/libata.rst b/Documentation/driver-api/libata.rst
index d477e296bda5..311af516a3fd 100644
--- a/Documentation/driver-api/libata.rst
+++ b/Documentation/driver-api/libata.rst
@@ -424,12 +424,6 @@ How commands are issued
-----------------------
Internal commands
- First, qc is allocated and initialized using :c:func:`ata_qc_new_init`.
- Although :c:func:`ata_qc_new_init` doesn't implement any wait or retry
- mechanism when qc is not available, internal commands are currently
- issued only during initialization and error recovery, so no other
- command is active and allocation is guaranteed to succeed.
-
Once allocated qc's taskfile is initialized for the command to be
executed. qc currently has two mechanisms to notify completion. One
is via ``qc->complete_fn()`` callback and the other is completion
@@ -447,11 +441,6 @@ SCSI commands
translated. No qc is involved in processing a simulated scmd. The
result is computed right away and the scmd is completed.
- For a translated scmd, :c:func:`ata_qc_new_init` is invoked to allocate a
- qc and the scmd is translated into the qc. SCSI midlayer's
- completion notification function pointer is stored into
- ``qc->scsidone``.
-
``qc->complete_fn()`` callback is used for completion notification. ATA
commands use :c:func:`ata_scsi_qc_complete` while ATAPI commands use
:c:func:`atapi_qc_complete`. Both functions end up calling ``qc->scsidone``
diff --git a/Documentation/driver-api/media/cec-core.rst b/Documentation/driver-api/media/cec-core.rst
index c6194ee81c41..ae0d20798edc 100644
--- a/Documentation/driver-api/media/cec-core.rst
+++ b/Documentation/driver-api/media/cec-core.rst
@@ -109,6 +109,7 @@ your driver:
int (*adap_monitor_all_enable)(struct cec_adapter *adap, bool enable);
int (*adap_monitor_pin_enable)(struct cec_adapter *adap, bool enable);
int (*adap_log_addr)(struct cec_adapter *adap, u8 logical_addr);
+ void (*adap_configured)(struct cec_adapter *adap, bool configured);
int (*adap_transmit)(struct cec_adapter *adap, u8 attempts,
u32 signal_free_time, struct cec_msg *msg);
void (*adap_status)(struct cec_adapter *adap, struct seq_file *file);
@@ -117,7 +118,7 @@ your driver:
/* Error injection callbacks */
...
- /* High-level callbacks */
+ /* High-level callback */
...
};
@@ -178,6 +179,16 @@ can receive directed messages to that address.
Note that adap_log_addr must return 0 if logical_addr is CEC_LOG_ADDR_INVALID.
+Called when the adapter is fully configured or unconfigured::
+
+ void (*adap_configured)(struct cec_adapter *adap, bool configured);
+
+If configured == true, then the adapter is fully configured, i.e. all logical
+addresses have been successfully claimed. If configured == false, then the
+adapter is unconfigured. If the driver has to take specific actions after
+(un)configuration, then that can be done through this optional callback.
+
+
To transmit a new message::
int (*adap_transmit)(struct cec_adapter *adap, u8 attempts,
diff --git a/Documentation/driver-api/media/drivers/davinci-vpbe-devel.rst b/Documentation/driver-api/media/drivers/davinci-vpbe-devel.rst
index f0961672e6a3..4e87bdbc7ae4 100644
--- a/Documentation/driver-api/media/drivers/davinci-vpbe-devel.rst
+++ b/Documentation/driver-api/media/drivers/davinci-vpbe-devel.rst
@@ -7,22 +7,22 @@ File partitioning
-----------------
V4L2 display device driver
- drivers/media/platform/davinci/vpbe_display.c
- drivers/media/platform/davinci/vpbe_display.h
+ drivers/media/platform/ti/davinci/vpbe_display.c
+ drivers/media/platform/ti/davinci/vpbe_display.h
VPBE display controller
- drivers/media/platform/davinci/vpbe.c
- drivers/media/platform/davinci/vpbe.h
+ drivers/media/platform/ti/davinci/vpbe.c
+ drivers/media/platform/ti/davinci/vpbe.h
VPBE venc sub device driver
- drivers/media/platform/davinci/vpbe_venc.c
- drivers/media/platform/davinci/vpbe_venc.h
- drivers/media/platform/davinci/vpbe_venc_regs.h
+ drivers/media/platform/ti/davinci/vpbe_venc.c
+ drivers/media/platform/ti/davinci/vpbe_venc.h
+ drivers/media/platform/ti/davinci/vpbe_venc_regs.h
VPBE osd driver
- drivers/media/platform/davinci/vpbe_osd.c
- drivers/media/platform/davinci/vpbe_osd.h
- drivers/media/platform/davinci/vpbe_osd_regs.h
+ drivers/media/platform/ti/davinci/vpbe_osd.c
+ drivers/media/platform/ti/davinci/vpbe_osd.h
+ drivers/media/platform/ti/davinci/vpbe_osd_regs.h
To be done
----------
diff --git a/Documentation/driver-api/media/drivers/fimc-devel.rst b/Documentation/driver-api/media/drivers/fimc-devel.rst
index 956e3a9901f8..4c6b7c8be19f 100644
--- a/Documentation/driver-api/media/drivers/fimc-devel.rst
+++ b/Documentation/driver-api/media/drivers/fimc-devel.rst
@@ -12,22 +12,22 @@ Files partitioning
- media device driver
- drivers/media/platform/exynos4-is/media-dev.[ch]
+ drivers/media/platform/samsung/exynos4-is/media-dev.[ch]
- camera capture video device driver
- drivers/media/platform/exynos4-is/fimc-capture.c
+ drivers/media/platform/samsung/exynos4-is/fimc-capture.c
- MIPI-CSI2 receiver subdev
- drivers/media/platform/exynos4-is/mipi-csis.[ch]
+ drivers/media/platform/samsung/exynos4-is/mipi-csis.[ch]
- video post-processor (mem-to-mem)
- drivers/media/platform/exynos4-is/fimc-core.c
+ drivers/media/platform/samsung/exynos4-is/fimc-core.c
- common files
- drivers/media/platform/exynos4-is/fimc-core.h
- drivers/media/platform/exynos4-is/fimc-reg.h
- drivers/media/platform/exynos4-is/regs-fimc.h
+ drivers/media/platform/samsung/exynos4-is/fimc-core.h
+ drivers/media/platform/samsung/exynos4-is/fimc-reg.h
+ drivers/media/platform/samsung/exynos4-is/regs-fimc.h
diff --git a/Documentation/driver-api/media/drivers/index.rst b/Documentation/driver-api/media/drivers/index.rst
index 426cda633bf0..32406490557c 100644
--- a/Documentation/driver-api/media/drivers/index.rst
+++ b/Documentation/driver-api/media/drivers/index.rst
@@ -21,6 +21,7 @@ Video4Linux (V4L) drivers
pvrusb2
pxa_camera
radiotrack
+ rkisp1
saa7134-devel
sh_mobile_ceu_camera
tuners
diff --git a/Documentation/driver-api/media/drivers/pxa_camera.rst b/Documentation/driver-api/media/drivers/pxa_camera.rst
index ee1bd96b66dd..46919919baac 100644
--- a/Documentation/driver-api/media/drivers/pxa_camera.rst
+++ b/Documentation/driver-api/media/drivers/pxa_camera.rst
@@ -19,7 +19,7 @@ Global video workflow
a) QCI stopped
Initially, the QCI interface is stopped.
- When a buffer is queued (pxa_videobuf_ops->buf_queue), the QCI starts.
+ When a buffer is queued, start_streaming is called and the QCI starts.
b) QCI started
More buffers can be queued while the QCI is started without halting the
diff --git a/Documentation/driver-api/media/mc-core.rst b/Documentation/driver-api/media/mc-core.rst
index 57b5bbba944e..400b8ca29367 100644
--- a/Documentation/driver-api/media/mc-core.rst
+++ b/Documentation/driver-api/media/mc-core.rst
@@ -42,9 +42,16 @@ Allocation of the structure is handled by the media device driver, usually by
embedding the :c:type:`media_device` instance in a larger driver-specific
structure.
-Drivers register media device instances by calling
-:c:func:`__media_device_register()` via the macro ``media_device_register()``
-and unregistered by calling :c:func:`media_device_unregister()`.
+Drivers initialise media device instances by calling
+:c:func:`media_device_init()`. After initialising a media device instance, it is
+registered by calling :c:func:`__media_device_register()` via the macro
+``media_device_register()`` and unregistered by calling
+:c:func:`media_device_unregister()`. An initialised media device must be
+eventually cleaned up by calling :c:func:`media_device_cleanup()`.
+
+Note that it is not allowed to unregister a media device instance that was not
+previously registered, or clean up a media device instance that was not
+previously initialised.
Entities
^^^^^^^^
@@ -179,8 +186,9 @@ is required and the graph structure can be freed normally.
Helper functions can be used to find a link between two given pads, or a pad
connected to another pad through an enabled link
-:c:func:`media_entity_find_link()` and
-:c:func:`media_entity_remote_pad()`.
+(:c:func:`media_entity_find_link()`, :c:func:`media_pad_remote_pad_first()`,
+:c:func:`media_entity_remote_source_pad_unique()` and
+:c:func:`media_pad_remote_pad_unique()`).
Use count and power handling
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -206,18 +214,29 @@ Link properties can be modified at runtime by calling
Pipelines and media streams
^^^^^^^^^^^^^^^^^^^^^^^^^^^
+A media stream is a stream of pixels or metadata originating from one or more
+source devices (such as a sensors) and flowing through media entity pads
+towards the final sinks. The stream can be modified on the route by the
+devices (e.g. scaling or pixel format conversions), or it can be split into
+multiple branches, or multiple branches can be merged.
+
+A media pipeline is a set of media streams which are interdependent. This
+interdependency can be caused by the hardware (e.g. configuration of a second
+stream cannot be changed if the first stream has been enabled) or by the driver
+due to the software design. Most commonly a media pipeline consists of a single
+stream which does not branch.
+
When starting streaming, drivers must notify all entities in the pipeline to
prevent link states from being modified during streaming by calling
:c:func:`media_pipeline_start()`.
-The function will mark all entities connected to the given entity through
-enabled links, either directly or indirectly, as streaming.
+The function will mark all the pads which are part of the pipeline as streaming.
The struct media_pipeline instance pointed to by
-the pipe argument will be stored in every entity in the pipeline.
+the pipe argument will be stored in every pad in the pipeline.
Drivers should embed the struct media_pipeline
in higher-level pipeline structures and can then access the
-pipeline through the struct media_entity
+pipeline through the struct media_pad
pipe field.
Calls to :c:func:`media_pipeline_start()` can be nested.
diff --git a/Documentation/driver-api/media/v4l2-event.rst b/Documentation/driver-api/media/v4l2-event.rst
index 5b8254eba7da..52d4fbc5d819 100644
--- a/Documentation/driver-api/media/v4l2-event.rst
+++ b/Documentation/driver-api/media/v4l2-event.rst
@@ -167,7 +167,7 @@ The first event type in the class is reserved for future use, so the first
available event type is 'class base + 1'.
An example on how the V4L2 events may be used can be found in the OMAP
-3 ISP driver (``drivers/media/platform/omap3isp``).
+3 ISP driver (``drivers/media/platform/ti/omap3isp``).
A subdev can directly send an event to the :c:type:`v4l2_device` notify
function with ``V4L2_DEVICE_NOTIFY_EVENT``. This allows the bridge to map
diff --git a/Documentation/driver-api/media/v4l2-subdev.rst b/Documentation/driver-api/media/v4l2-subdev.rst
index 08ea2673b19e..6f8d79926aa5 100644
--- a/Documentation/driver-api/media/v4l2-subdev.rst
+++ b/Documentation/driver-api/media/v4l2-subdev.rst
@@ -243,6 +243,12 @@ notifier callback is called. After all subdevices have been located the
.complete() callback is called. When a subdevice is removed from the
system the .unbind() method is called. All three callbacks are optional.
+Drivers can store any type of custom data in their driver-specific
+:c:type:`v4l2_async_subdev` wrapper. If any of that data requires special
+handling when the structure is freed, drivers must implement the ``.destroy()``
+notifier callback. The framework will call it right before freeing the
+:c:type:`v4l2_async_subdev`.
+
Calling subdev operations
~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -518,6 +524,75 @@ The :c:func:`v4l2_i2c_new_subdev` function will call
:c:type:`i2c_board_info` structure using the ``client_type`` and the
``addr`` to fill it.
+Centrally managed subdev active state
+-------------------------------------
+
+Traditionally V4L2 subdev drivers maintained internal state for the active
+device configuration. This is often implemented as e.g. an array of struct
+v4l2_mbus_framefmt, one entry for each pad, and similarly for crop and compose
+rectangles.
+
+In addition to the active configuration, each subdev file handle has an array of
+struct v4l2_subdev_pad_config, managed by the V4L2 core, which contains the try
+configuration.
+
+To simplify the subdev drivers the V4L2 subdev API now optionally supports a
+centrally managed active configuration represented by
+:c:type:`v4l2_subdev_state`. One instance of state, which contains the active
+device configuration, is stored in the sub-device itself as part of
+the :c:type:`v4l2_subdev` structure, while the core associates a try state to
+each open file handle, to store the try configuration related to that file
+handle.
+
+Sub-device drivers can opt-in and use state to manage their active configuration
+by initializing the subdevice state with a call to v4l2_subdev_init_finalize()
+before registering the sub-device. They must also call v4l2_subdev_cleanup()
+to release all the allocated resources before unregistering the sub-device.
+The core automatically allocates and initializes a state for each open file
+handle to store the try configurations and frees it when closing the file
+handle.
+
+V4L2 sub-device operations that use both the :ref:`ACTIVE and TRY formats
+<v4l2-subdev-format-whence>` receive the correct state to operate on through
+the 'state' parameter. The state must be locked and unlocked by the
+caller by calling :c:func:`v4l2_subdev_lock_state()` and
+:c:func:`v4l2_subdev_unlock_state()`. The caller can do so by calling the subdev
+operation through the :c:func:`v4l2_subdev_call_state_active()` macro.
+
+Operations that do not receive a state parameter implicitly operate on the
+subdevice active state, which drivers can exclusively access by
+calling :c:func:`v4l2_subdev_lock_and_get_active_state()`. The sub-device active
+state must equally be released by calling :c:func:`v4l2_subdev_unlock_state()`.
+
+Drivers must never manually access the state stored in the :c:type:`v4l2_subdev`
+or in the file handle without going through the designated helpers.
+
+While the V4L2 core passes the correct try or active state to the subdevice
+operations, many existing device drivers pass a NULL state when calling
+operations with :c:func:`v4l2_subdev_call()`. This legacy construct causes
+issues with subdevice drivers that let the V4L2 core manage the active state,
+as they expect to receive the appropriate state as a parameter. To help the
+conversion of subdevice drivers to a managed active state without having to
+convert all callers at the same time, an additional wrapper layer has been
+added to v4l2_subdev_call(), which handles the NULL case by geting and locking
+the callee's active state with :c:func:`v4l2_subdev_lock_and_get_active_state()`,
+and unlocking the state after the call.
+
+The whole subdev state is in reality split into three parts: the
+v4l2_subdev_state, subdev controls and subdev driver's internal state. In the
+future these parts should be combined into a single state. For the time being
+we need a way to handle the locking for these parts. This can be accomplished
+by sharing a lock. The v4l2_ctrl_handler already supports this via its 'lock'
+pointer and the same model is used with states. The driver can do the following
+before calling v4l2_subdev_init_finalize():
+
+.. code-block:: c
+
+ sd->ctrl_handler->lock = &priv->mutex;
+ sd->state_lock = &priv->mutex;
+
+This shares the driver's private mutex between the controls and the states.
+
V4L2 sub-device functions and data structures
---------------------------------------------
diff --git a/Documentation/driver-api/mtd/index.rst b/Documentation/driver-api/mtd/index.rst
index 436ba5a851d7..6a4278f409d7 100644
--- a/Documentation/driver-api/mtd/index.rst
+++ b/Documentation/driver-api/mtd/index.rst
@@ -7,6 +7,6 @@ Memory Technology Device (MTD)
.. toctree::
:maxdepth: 1
- intel-spi
+ spi-intel
nand_ecc
spi-nor
diff --git a/Documentation/driver-api/mtd/intel-spi.rst b/Documentation/driver-api/mtd/spi-intel.rst
index 0465f6879262..df854f20ead1 100644
--- a/Documentation/driver-api/mtd/intel-spi.rst
+++ b/Documentation/driver-api/mtd/spi-intel.rst
@@ -1,5 +1,5 @@
==============================
-Upgrading BIOS using intel-spi
+Upgrading BIOS using spi-intel
==============================
Many Intel CPUs like Baytrail and Braswell include SPI serial flash host
@@ -11,12 +11,12 @@ avoid accidental (or on purpose) overwrite of the content.
Not all manufacturers protect the SPI serial flash, mainly because it
allows upgrading the BIOS image directly from an OS.
-The intel-spi driver makes it possible to read and write the SPI serial
+The spi-intel driver makes it possible to read and write the SPI serial
flash, if certain protection bits are not set and locked. If it finds
any of them set, the whole MTD device is made read-only to prevent
partial overwrites. By default the driver exposes SPI serial flash
contents as read-only but it can be changed from kernel command line,
-passing "intel-spi.writeable=1".
+passing "spi_intel.writeable=1".
Please keep in mind that overwriting the BIOS image on SPI serial flash
might render the machine unbootable and requires special equipment like
@@ -32,7 +32,7 @@ Linux.
serial flash. Distros like Debian and Fedora have this prepackaged with
name "mtd-utils".
- 3) Add "intel-spi.writeable=1" to the kernel command line and reboot
+ 3) Add "spi_intel.writeable=1" to the kernel command line and reboot
the board (you can also reload the driver passing "writeable=1" as
module parameter to modprobe).
diff --git a/Documentation/driver-api/nvdimm/nvdimm.rst b/Documentation/driver-api/nvdimm/nvdimm.rst
index 1d8302b89bd4..be8587a558e1 100644
--- a/Documentation/driver-api/nvdimm/nvdimm.rst
+++ b/Documentation/driver-api/nvdimm/nvdimm.rst
@@ -14,10 +14,8 @@ Version 13
Overview
Supporting Documents
Git Trees
- LIBNVDIMM PMEM and BLK
- Why BLK?
- PMEM vs BLK
- BLK-REGIONs, PMEM-REGIONs, Atomic Sectors, and DAX
+ LIBNVDIMM PMEM
+ PMEM-REGIONs, Atomic Sectors, and DAX
Example NVDIMM Platform
LIBNVDIMM Kernel Device Model and LIBNDCTL Userspace API
LIBNDCTL: Context
@@ -53,19 +51,12 @@ PMEM:
block device composed of PMEM is capable of DAX. A PMEM address range
may span an interleave of several DIMMs.
-BLK:
- A set of one or more programmable memory mapped apertures provided
- by a DIMM to access its media. This indirection precludes the
- performance benefit of interleaving, but enables DIMM-bounded failure
- modes.
-
DPA:
DIMM Physical Address, is a DIMM-relative offset. With one DIMM in
the system there would be a 1:1 system-physical-address:DPA association.
Once more DIMMs are added a memory controller interleave must be
decoded to determine the DPA associated with a given
- system-physical-address. BLK capacity always has a 1:1 relationship
- with a single-DIMM's DPA range.
+ system-physical-address.
DAX:
File system extensions to bypass the page cache and block layer to
@@ -84,30 +75,30 @@ BTT:
Block Translation Table: Persistent memory is byte addressable.
Existing software may have an expectation that the power-fail-atomicity
of writes is at least one sector, 512 bytes. The BTT is an indirection
- table with atomic update semantics to front a PMEM/BLK block device
+ table with atomic update semantics to front a PMEM block device
driver and present arbitrary atomic sector sizes.
LABEL:
Metadata stored on a DIMM device that partitions and identifies
- (persistently names) storage between PMEM and BLK. It also partitions
- BLK storage to host BTTs with different parameters per BLK-partition.
- Note that traditional partition tables, GPT/MBR, are layered on top of a
- BLK or PMEM device.
+ (persistently names) capacity allocated to different PMEM namespaces. It
+ also indicates whether an address abstraction like a BTT is applied to
+ the namepsace. Note that traditional partition tables, GPT/MBR, are
+ layered on top of a PMEM namespace, or an address abstraction like BTT
+ if present, but partition support is deprecated going forward.
Overview
========
-The LIBNVDIMM subsystem provides support for three types of NVDIMMs, namely,
-PMEM, BLK, and NVDIMM devices that can simultaneously support both PMEM
-and BLK mode access. These three modes of operation are described by
-the "NVDIMM Firmware Interface Table" (NFIT) in ACPI 6. While the LIBNVDIMM
-implementation is generic and supports pre-NFIT platforms, it was guided
-by the superset of capabilities need to support this ACPI 6 definition
-for NVDIMM resources. The bulk of the kernel implementation is in place
-to handle the case where DPA accessible via PMEM is aliased with DPA
-accessible via BLK. When that occurs a LABEL is needed to reserve DPA
-for exclusive access via one mode a time.
+The LIBNVDIMM subsystem provides support for PMEM described by platform
+firmware or a device driver. On ACPI based systems the platform firmware
+conveys persistent memory resource via the ACPI NFIT "NVDIMM Firmware
+Interface Table" in ACPI 6. While the LIBNVDIMM subsystem implementation
+is generic and supports pre-NFIT platforms, it was guided by the
+superset of capabilities need to support this ACPI 6 definition for
+NVDIMM resources. The original implementation supported the
+block-window-aperture capability described in the NFIT, but that support
+has since been abandoned and never shipped in a product.
Supporting Documents
--------------------
@@ -125,107 +116,38 @@ Git Trees
---------
LIBNVDIMM:
- https://git.kernel.org/cgit/linux/kernel/git/djbw/nvdimm.git
+ https://git.kernel.org/cgit/linux/kernel/git/nvdimm/nvdimm.git
LIBNDCTL:
https://github.com/pmem/ndctl.git
-PMEM:
- https://github.com/01org/prd
-LIBNVDIMM PMEM and BLK
-======================
+LIBNVDIMM PMEM
+==============
Prior to the arrival of the NFIT, non-volatile memory was described to a
system in various ad-hoc ways. Usually only the bare minimum was
provided, namely, a single system-physical-address range where writes
are expected to be durable after a system power loss. Now, the NFIT
specification standardizes not only the description of PMEM, but also
-BLK and platform message-passing entry points for control and
-configuration.
-
-For each NVDIMM access method (PMEM, BLK), LIBNVDIMM provides a block
-device driver:
-
- 1. PMEM (nd_pmem.ko): Drives a system-physical-address range. This
- range is contiguous in system memory and may be interleaved (hardware
- memory controller striped) across multiple DIMMs. When interleaved the
- platform may optionally provide details of which DIMMs are participating
- in the interleave.
-
- Note that while LIBNVDIMM describes system-physical-address ranges that may
- alias with BLK access as ND_NAMESPACE_PMEM ranges and those without
- alias as ND_NAMESPACE_IO ranges, to the nd_pmem driver there is no
- distinction. The different device-types are an implementation detail
- that userspace can exploit to implement policies like "only interface
- with address ranges from certain DIMMs". It is worth noting that when
- aliasing is present and a DIMM lacks a label, then no block device can
- be created by default as userspace needs to do at least one allocation
- of DPA to the PMEM range. In contrast ND_NAMESPACE_IO ranges, once
- registered, can be immediately attached to nd_pmem.
-
- 2. BLK (nd_blk.ko): This driver performs I/O using a set of platform
- defined apertures. A set of apertures will access just one DIMM.
- Multiple windows (apertures) allow multiple concurrent accesses, much like
- tagged-command-queuing, and would likely be used by different threads or
- different CPUs.
-
- The NFIT specification defines a standard format for a BLK-aperture, but
- the spec also allows for vendor specific layouts, and non-NFIT BLK
- implementations may have other designs for BLK I/O. For this reason
- "nd_blk" calls back into platform-specific code to perform the I/O.
-
- One such implementation is defined in the "Driver Writer's Guide" and "DSM
- Interface Example".
-
-
-Why BLK?
-========
+platform message-passing entry points for control and configuration.
+
+PMEM (nd_pmem.ko): Drives a system-physical-address range. This range is
+contiguous in system memory and may be interleaved (hardware memory controller
+striped) across multiple DIMMs. When interleaved the platform may optionally
+provide details of which DIMMs are participating in the interleave.
+
+It is worth noting that when the labeling capability is detected (a EFI
+namespace label index block is found), then no block device is created
+by default as userspace needs to do at least one allocation of DPA to
+the PMEM range. In contrast ND_NAMESPACE_IO ranges, once registered,
+can be immediately attached to nd_pmem. This latter mode is called
+label-less or "legacy".
+
+PMEM-REGIONs, Atomic Sectors, and DAX
+-------------------------------------
-While PMEM provides direct byte-addressable CPU-load/store access to
-NVDIMM storage, it does not provide the best system RAS (recovery,
-availability, and serviceability) model. An access to a corrupted
-system-physical-address address causes a CPU exception while an access
-to a corrupted address through an BLK-aperture causes that block window
-to raise an error status in a register. The latter is more aligned with
-the standard error model that host-bus-adapter attached disks present.
-
-Also, if an administrator ever wants to replace a memory it is easier to
-service a system at DIMM module boundaries. Compare this to PMEM where
-data could be interleaved in an opaque hardware specific manner across
-several DIMMs.
-
-PMEM vs BLK
------------
-
-BLK-apertures solve these RAS problems, but their presence is also the
-major contributing factor to the complexity of the ND subsystem. They
-complicate the implementation because PMEM and BLK alias in DPA space.
-Any given DIMM's DPA-range may contribute to one or more
-system-physical-address sets of interleaved DIMMs, *and* may also be
-accessed in its entirety through its BLK-aperture. Accessing a DPA
-through a system-physical-address while simultaneously accessing the
-same DPA through a BLK-aperture has undefined results. For this reason,
-DIMMs with this dual interface configuration include a DSM function to
-store/retrieve a LABEL. The LABEL effectively partitions the DPA-space
-into exclusive system-physical-address and BLK-aperture accessible
-regions. For simplicity a DIMM is allowed a PMEM "region" per each
-interleave set in which it is a member. The remaining DPA space can be
-carved into an arbitrary number of BLK devices with discontiguous
-extents.
-
-BLK-REGIONs, PMEM-REGIONs, Atomic Sectors, and DAX
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-One of the few
-reasons to allow multiple BLK namespaces per REGION is so that each
-BLK-namespace can be configured with a BTT with unique atomic sector
-sizes. While a PMEM device can host a BTT the LABEL specification does
-not provide for a sector size to be specified for a PMEM namespace.
-
-This is due to the expectation that the primary usage model for PMEM is
-via DAX, and the BTT is incompatible with DAX. However, for the cases
-where an application or filesystem still needs atomic sector update
-guarantees it can register a BTT on a PMEM device or partition. See
+For the cases where an application or filesystem still needs atomic sector
+update guarantees it can register a BTT on a PMEM device or partition. See
LIBNVDIMM/NDCTL: Block Translation Table "btt"
@@ -236,51 +158,40 @@ For the remainder of this document the following diagram will be
referenced for any example sysfs layouts::
- (a) (b) DIMM BLK-REGION
+ (a) (b) DIMM
+-------------------+--------+--------+--------+
- +------+ | pm0.0 | blk2.0 | pm1.0 | blk2.1 | 0 region2
+ +------+ | pm0.0 | free | pm1.0 | free | 0
| imc0 +--+- - - region0- - - +--------+ +--------+
- +--+---+ | pm0.0 | blk3.0 | pm1.0 | blk3.1 | 1 region3
+ +--+---+ | pm0.0 | free | pm1.0 | free | 1
| +-------------------+--------v v--------+
+--+---+ | |
| cpu0 | region1
+--+---+ | |
| +----------------------------^ ^--------+
- +--+---+ | blk4.0 | pm1.0 | blk4.0 | 2 region4
+ +--+---+ | free | pm1.0 | free | 2
| imc1 +--+----------------------------| +--------+
- +------+ | blk5.0 | pm1.0 | blk5.0 | 3 region5
+ +------+ | free | pm1.0 | free | 3
+----------------------------+--------+--------+
In this platform we have four DIMMs and two memory controllers in one
-socket. Each unique interface (BLK or PMEM) to DPA space is identified
-by a region device with a dynamically assigned id (REGION0 - REGION5).
+socket. Each PMEM interleave set is identified by a region device with
+a dynamically assigned id.
1. The first portion of DIMM0 and DIMM1 are interleaved as REGION0. A
single PMEM namespace is created in the REGION0-SPA-range that spans most
of DIMM0 and DIMM1 with a user-specified name of "pm0.0". Some of that
- interleaved system-physical-address range is reclaimed as BLK-aperture
- accessed space starting at DPA-offset (a) into each DIMM. In that
- reclaimed space we create two BLK-aperture "namespaces" from REGION2 and
- REGION3 where "blk2.0" and "blk3.0" are just human readable names that
- could be set to any user-desired name in the LABEL.
+ interleaved system-physical-address range is left free for
+ another PMEM namespace to be defined.
2. In the last portion of DIMM0 and DIMM1 we have an interleaved
system-physical-address range, REGION1, that spans those two DIMMs as
well as DIMM2 and DIMM3. Some of REGION1 is allocated to a PMEM namespace
- named "pm1.0", the rest is reclaimed in 4 BLK-aperture namespaces (for
- each DIMM in the interleave set), "blk2.1", "blk3.1", "blk4.0", and
- "blk5.0".
-
- 3. The portion of DIMM2 and DIMM3 that do not participate in the REGION1
- interleaved system-physical-address range (i.e. the DPA address past
- offset (b) are also included in the "blk4.0" and "blk5.0" namespaces.
- Note, that this example shows that BLK-aperture namespaces don't need to
- be contiguous in DPA-space.
+ named "pm1.0".
This bus is provided by the kernel under the device
/sys/devices/platform/nfit_test.0 when the nfit_test.ko module from
- tools/testing/nvdimm is loaded. This not only test LIBNVDIMM but the
- acpi_nfit.ko driver as well.
+ tools/testing/nvdimm is loaded. This module is a unit test for
+ LIBNVDIMM and the acpi_nfit.ko driver.
LIBNVDIMM Kernel Device Model and LIBNDCTL Userspace API
@@ -469,17 +380,14 @@ identified by an "nfit_handle" a 32-bit value where:
LIBNVDIMM/LIBNDCTL: Region
--------------------------
-A generic REGION device is registered for each PMEM range or BLK-aperture
-set. Per the example there are 6 regions: 2 PMEM and 4 BLK-aperture
-sets on the "nfit_test.0" bus. The primary role of regions are to be a
-container of "mappings". A mapping is a tuple of <DIMM,
-DPA-start-offset, length>.
+A generic REGION device is registered for each PMEM interleave-set /
+range. Per the example there are 2 PMEM regions on the "nfit_test.0"
+bus. The primary role of regions are to be a container of "mappings". A
+mapping is a tuple of <DIMM, DPA-start-offset, length>.
-LIBNVDIMM provides a built-in driver for these REGION devices. This driver
-is responsible for reconciling the aliased DPA mappings across all
-regions, parsing the LABEL, if present, and then emitting NAMESPACE
-devices with the resolved/exclusive DPA-boundaries for the nd_pmem or
-nd_blk device driver to consume.
+LIBNVDIMM provides a built-in driver for REGION devices. This driver
+is responsible for all parsing LABELs, if present, and then emitting NAMESPACE
+devices for the nd_pmem driver to consume.
In addition to the generic attributes of "mapping"s, "interleave_ways"
and "size" the REGION device also exports some convenience attributes.
@@ -493,8 +401,6 @@ LIBNVDIMM: region::
struct nd_region *nvdimm_pmem_region_create(struct nvdimm_bus *nvdimm_bus,
struct nd_region_desc *ndr_desc);
- struct nd_region *nvdimm_blk_region_create(struct nvdimm_bus *nvdimm_bus,
- struct nd_region_desc *ndr_desc);
::
@@ -527,8 +433,9 @@ LIBNDCTL: region enumeration example
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Sample region retrieval routines based on NFIT-unique data like
-"spa_index" (interleave set id) for PMEM and "nfit_handle" (dimm id) for
-BLK::
+"spa_index" (interleave set id).
+
+::
static struct ndctl_region *get_pmem_region_by_spa_index(struct ndctl_bus *bus,
unsigned int spa_index)
@@ -544,139 +451,23 @@ BLK::
return NULL;
}
- static struct ndctl_region *get_blk_region_by_dimm_handle(struct ndctl_bus *bus,
- unsigned int handle)
- {
- struct ndctl_region *region;
-
- ndctl_region_foreach(bus, region) {
- struct ndctl_mapping *map;
-
- if (ndctl_region_get_type(region) != ND_DEVICE_REGION_BLOCK)
- continue;
- ndctl_mapping_foreach(region, map) {
- struct ndctl_dimm *dimm = ndctl_mapping_get_dimm(map);
-
- if (ndctl_dimm_get_handle(dimm) == handle)
- return region;
- }
- }
- return NULL;
- }
-
-
-Why Not Encode the Region Type into the Region Name?
-----------------------------------------------------
-
-At first glance it seems since NFIT defines just PMEM and BLK interface
-types that we should simply name REGION devices with something derived
-from those type names. However, the ND subsystem explicitly keeps the
-REGION name generic and expects userspace to always consider the
-region-attributes for four reasons:
-
- 1. There are already more than two REGION and "namespace" types. For
- PMEM there are two subtypes. As mentioned previously we have PMEM where
- the constituent DIMM devices are known and anonymous PMEM. For BLK
- regions the NFIT specification already anticipates vendor specific
- implementations. The exact distinction of what a region contains is in
- the region-attributes not the region-name or the region-devtype.
-
- 2. A region with zero child-namespaces is a possible configuration. For
- example, the NFIT allows for a DCR to be published without a
- corresponding BLK-aperture. This equates to a DIMM that can only accept
- control/configuration messages, but no i/o through a descendant block
- device. Again, this "type" is advertised in the attributes ('mappings'
- == 0) and the name does not tell you much.
-
- 3. What if a third major interface type arises in the future? Outside
- of vendor specific implementations, it's not difficult to envision a
- third class of interface type beyond BLK and PMEM. With a generic name
- for the REGION level of the device-hierarchy old userspace
- implementations can still make sense of new kernel advertised
- region-types. Userspace can always rely on the generic region
- attributes like "mappings", "size", etc and the expected child devices
- named "namespace". This generic format of the device-model hierarchy
- allows the LIBNVDIMM and LIBNDCTL implementations to be more uniform and
- future-proof.
-
- 4. There are more robust mechanisms for determining the major type of a
- region than a device name. See the next section, How Do I Determine the
- Major Type of a Region?
-
-How Do I Determine the Major Type of a Region?
-----------------------------------------------
-
-Outside of the blanket recommendation of "use libndctl", or simply
-looking at the kernel header (/usr/include/linux/ndctl.h) to decode the
-"nstype" integer attribute, here are some other options.
-
-1. module alias lookup
-^^^^^^^^^^^^^^^^^^^^^^
-
- The whole point of region/namespace device type differentiation is to
- decide which block-device driver will attach to a given LIBNVDIMM namespace.
- One can simply use the modalias to lookup the resulting module. It's
- important to note that this method is robust in the presence of a
- vendor-specific driver down the road. If a vendor-specific
- implementation wants to supplant the standard nd_blk driver it can with
- minimal impact to the rest of LIBNVDIMM.
-
- In fact, a vendor may also want to have a vendor-specific region-driver
- (outside of nd_region). For example, if a vendor defined its own LABEL
- format it would need its own region driver to parse that LABEL and emit
- the resulting namespaces. The output from module resolution is more
- accurate than a region-name or region-devtype.
-
-2. udev
-^^^^^^^
-
- The kernel "devtype" is registered in the udev database::
-
- # udevadm info --path=/devices/platform/nfit_test.0/ndbus0/region0
- P: /devices/platform/nfit_test.0/ndbus0/region0
- E: DEVPATH=/devices/platform/nfit_test.0/ndbus0/region0
- E: DEVTYPE=nd_pmem
- E: MODALIAS=nd:t2
- E: SUBSYSTEM=nd
-
- # udevadm info --path=/devices/platform/nfit_test.0/ndbus0/region4
- P: /devices/platform/nfit_test.0/ndbus0/region4
- E: DEVPATH=/devices/platform/nfit_test.0/ndbus0/region4
- E: DEVTYPE=nd_blk
- E: MODALIAS=nd:t3
- E: SUBSYSTEM=nd
-
- ...and is available as a region attribute, but keep in mind that the
- "devtype" does not indicate sub-type variations and scripts should
- really be understanding the other attributes.
-
-3. type specific attributes
-^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
- As it currently stands a BLK-aperture region will never have a
- "nfit/spa_index" attribute, but neither will a non-NFIT PMEM region. A
- BLK region with a "mappings" value of 0 is, as mentioned above, a DIMM
- that does not allow I/O. A PMEM region with a "mappings" value of zero
- is a simple system-physical-address range.
-
LIBNVDIMM/LIBNDCTL: Namespace
-----------------------------
-A REGION, after resolving DPA aliasing and LABEL specified boundaries,
-surfaces one or more "namespace" devices. The arrival of a "namespace"
-device currently triggers either the nd_blk or nd_pmem driver to load
-and register a disk/block device.
+A REGION, after resolving DPA aliasing and LABEL specified boundaries, surfaces
+one or more "namespace" devices. The arrival of a "namespace" device currently
+triggers the nd_pmem driver to load and register a disk/block device.
LIBNVDIMM: namespace
^^^^^^^^^^^^^^^^^^^^
-Here is a sample layout from the three major types of NAMESPACE where
-namespace0.0 represents DIMM-info-backed PMEM (note that it has a 'uuid'
-attribute), namespace2.0 represents a BLK namespace (note it has a
-'sector_size' attribute) that, and namespace6.0 represents an anonymous
-PMEM namespace (note that has no 'uuid' attribute due to not support a
-LABEL)::
+Here is a sample layout from the 2 major types of NAMESPACE where namespace0.0
+represents DIMM-info-backed PMEM (note that it has a 'uuid' attribute), and
+namespace1.0 represents an anonymous PMEM namespace (note that has no 'uuid'
+attribute due to not support a LABEL)
+
+::
/sys/devices/platform/nfit_test.0/ndbus0/region0/namespace0.0
|-- alt_name
@@ -691,20 +482,7 @@ LABEL)::
|-- type
|-- uevent
`-- uuid
- /sys/devices/platform/nfit_test.0/ndbus0/region2/namespace2.0
- |-- alt_name
- |-- devtype
- |-- dpa_extents
- |-- force_raw
- |-- modalias
- |-- numa_node
- |-- sector_size
- |-- size
- |-- subsystem -> ../../../../../../bus/nd
- |-- type
- |-- uevent
- `-- uuid
- /sys/devices/platform/nfit_test.1/ndbus1/region6/namespace6.0
+ /sys/devices/platform/nfit_test.1/ndbus1/region1/namespace1.0
|-- block
| `-- pmem0
|-- devtype
@@ -786,9 +564,9 @@ Why the Term "namespace"?
LIBNVDIMM/LIBNDCTL: Block Translation Table "btt"
-------------------------------------------------
-A BTT (design document: https://pmem.io/2014/09/23/btt.html) is a stacked
-block device driver that fronts either the whole block device or a
-partition of a block device emitted by either a PMEM or BLK NAMESPACE.
+A BTT (design document: https://pmem.io/2014/09/23/btt.html) is a
+personality driver for a namespace that fronts entire namespace as an
+'address abstraction'.
LIBNVDIMM: btt layout
^^^^^^^^^^^^^^^^^^^^^
@@ -815,7 +593,9 @@ LIBNDCTL: btt creation example
Similar to namespaces an idle BTT device is automatically created per
region. Each time this "seed" btt device is configured and enabled a new
seed is created. Creating a BTT configuration involves two steps of
-finding and idle BTT and assigning it to consume a PMEM or BLK namespace::
+finding and idle BTT and assigning it to consume a namespace.
+
+::
static struct ndctl_btt *get_idle_btt(struct ndctl_region *region)
{
@@ -863,25 +643,15 @@ For the given example above, here is the view of the objects as seen by the
LIBNDCTL API::
+---+
- |CTX| +---------+ +--------------+ +---------------+
- +-+-+ +-> REGION0 +---> NAMESPACE0.0 +--> PMEM8 "pm0.0" |
- | | +---------+ +--------------+ +---------------+
- +-------+ | | +---------+ +--------------+ +---------------+
- | DIMM0 <-+ | +-> REGION1 +---> NAMESPACE1.0 +--> PMEM6 "pm1.0" |
- +-------+ | | | +---------+ +--------------+ +---------------+
+ |CTX|
+ +-+-+
+ |
+ +-------+ |
+ | DIMM0 <-+ | +---------+ +--------------+ +---------------+
+ +-------+ | | +-> REGION0 +---> NAMESPACE0.0 +--> PMEM8 "pm0.0" |
| DIMM1 <-+ +-v--+ | +---------+ +--------------+ +---------------+
- +-------+ +-+BUS0+---> REGION2 +-+-> NAMESPACE2.0 +--> ND6 "blk2.0" |
- | DIMM2 <-+ +----+ | +---------+ | +--------------+ +----------------------+
- +-------+ | | +-> NAMESPACE2.1 +--> ND5 "blk2.1" | BTT2 |
- | DIMM3 <-+ | +--------------+ +----------------------+
- +-------+ | +---------+ +--------------+ +---------------+
- +-> REGION3 +-+-> NAMESPACE3.0 +--> ND4 "blk3.0" |
- | +---------+ | +--------------+ +----------------------+
- | +-> NAMESPACE3.1 +--> ND3 "blk3.1" | BTT1 |
- | +--------------+ +----------------------+
- | +---------+ +--------------+ +---------------+
- +-> REGION4 +---> NAMESPACE4.0 +--> ND2 "blk4.0" |
- | +---------+ +--------------+ +---------------+
- | +---------+ +--------------+ +----------------------+
- +-> REGION5 +---> NAMESPACE5.0 +--> ND1 "blk5.0" | BTT0 |
- +---------+ +--------------+ +---------------+------+
+ +-------+ +-+BUS0+-| +---------+ +--------------+ +----------------------+
+ | DIMM2 <-+ +----+ +-> REGION1 +---> NAMESPACE1.0 +--> PMEM6 "pm1.0" | BTT1 |
+ +-------+ | | +---------+ +--------------+ +---------------+------+
+ | DIMM3 <-+
+ +-------+
diff --git a/Documentation/driver-api/nvmem.rst b/Documentation/driver-api/nvmem.rst
index 287e86819640..e3366322d46c 100644
--- a/Documentation/driver-api/nvmem.rst
+++ b/Documentation/driver-api/nvmem.rst
@@ -26,9 +26,7 @@ was a rather big abstraction leak.
This framework aims at solve these problems. It also introduces DT
representation for consumer devices to go get the data they require (MAC
-Addresses, SoC/Revision ID, part numbers, and so on) from the NVMEMs. This
-framework is based on regmap, so that most of the abstraction available in
-regmap can be reused, across multiple types of buses.
+Addresses, SoC/Revision ID, part numbers, and so on) from the NVMEMs.
NVMEM Providers
+++++++++++++++
@@ -45,23 +43,21 @@ nvmem_device pointer.
nvmem_unregister(nvmem) is used to unregister a previously registered provider.
-For example, a simple qfprom case::
+For example, a simple nvram case::
- static struct nvmem_config econfig = {
- .name = "qfprom",
- .owner = THIS_MODULE,
- };
-
- static int qfprom_probe(struct platform_device *pdev)
+ static int brcm_nvram_probe(struct platform_device *pdev)
{
+ struct nvmem_config config = {
+ .name = "brcm-nvram",
+ .reg_read = brcm_nvram_read,
+ };
...
- econfig.dev = &pdev->dev;
- nvmem = nvmem_register(&econfig);
- ...
- }
+ config.dev = &pdev->dev;
+ config.priv = priv;
+ config.size = resource_size(res);
-It is mandatory that the NVMEM provider has a regmap associated with its
-struct device. Failure to do would return error code from nvmem_register().
+ devm_nvmem_register(&config);
+ }
Users of board files can define and register nvmem cells using the
nvmem_cell_table struct::
diff --git a/Documentation/driver-api/pci/pci.rst b/Documentation/driver-api/pci/pci.rst
index ca85e5e78b2c..4843cfad4f60 100644
--- a/Documentation/driver-api/pci/pci.rst
+++ b/Documentation/driver-api/pci/pci.rst
@@ -13,7 +13,7 @@ PCI Support Library
.. kernel-doc:: drivers/pci/search.c
:export:
-.. kernel-doc:: drivers/pci/msi.c
+.. kernel-doc:: drivers/pci/msi/msi.c
:export:
.. kernel-doc:: drivers/pci/bus.c
diff --git a/Documentation/driver-api/pwm.rst b/Documentation/driver-api/pwm.rst
index ccb06e485756..8c71a2055d27 100644
--- a/Documentation/driver-api/pwm.rst
+++ b/Documentation/driver-api/pwm.rst
@@ -40,8 +40,7 @@ after usage with pwm_free().
New users should use the pwm_get() function and pass to it the consumer
device or a consumer name. pwm_put() is used to free the PWM device. Managed
-variants of the getter, devm_pwm_get(), devm_of_pwm_get(),
-devm_fwnode_pwm_get(), also exist.
+variants of the getter, devm_pwm_get() and devm_fwnode_pwm_get(), also exist.
After being requested, a PWM has to be configured using::
@@ -49,6 +48,12 @@ After being requested, a PWM has to be configured using::
This API controls both the PWM period/duty_cycle config and the
enable/disable state.
+
+As a consumer, don't rely on the output's state for a disabled PWM. If it's
+easily possible, drivers are supposed to emit the inactive state, but some
+drivers cannot. If you rely on getting the inactive state, use .duty_cycle=0,
+.enabled=true.
+
There is also a usage_power setting: If set, the PWM driver is only required to
maintain the power output but has more freedom regarding signal form.
If supported by the driver, the signal can be optimized, for example to improve
diff --git a/Documentation/driver-api/serial/driver.rst b/Documentation/driver-api/serial/driver.rst
index 31bd4e16fb1f..23c6b956cd90 100644
--- a/Documentation/driver-api/serial/driver.rst
+++ b/Documentation/driver-api/serial/driver.rst
@@ -25,10 +25,10 @@ Console Support
---------------
The serial core provides a few helper functions. This includes identifing
-the correct port structure (via uart_get_console) and decoding command line
-arguments (uart_parse_options).
+the correct port structure (via uart_get_console()) and decoding command line
+arguments (uart_parse_options()).
-There is also a helper function (uart_console_write) which performs a
+There is also a helper function (uart_console_write()) which performs a
character by character write, translating newlines to CRLF sequences.
Driver writers are recommended to use this function rather than implementing
their own version.
@@ -39,7 +39,7 @@ Locking
It is the responsibility of the low level hardware driver to perform the
necessary locking using port->lock. There are some exceptions (which
-are described in the uart_ops listing below.)
+are described in the struct uart_ops listing below.)
There are two locks. A per-port spinlock, and an overall semaphore.
@@ -63,442 +63,20 @@ commonly referred to as the port mutex.
uart_ops
--------
-The uart_ops structure is the main interface between serial_core and the
-hardware specific driver. It contains all the methods to control the
-hardware.
-
- tx_empty(port)
- This function tests whether the transmitter fifo and shifter
- for the port described by 'port' is empty. If it is empty,
- this function should return TIOCSER_TEMT, otherwise return 0.
- If the port does not support this operation, then it should
- return TIOCSER_TEMT.
-
- Locking: none.
-
- Interrupts: caller dependent.
-
- This call must not sleep
-
- set_mctrl(port, mctrl)
- This function sets the modem control lines for port described
- by 'port' to the state described by mctrl. The relevant bits
- of mctrl are:
-
- - TIOCM_RTS RTS signal.
- - TIOCM_DTR DTR signal.
- - TIOCM_OUT1 OUT1 signal.
- - TIOCM_OUT2 OUT2 signal.
- - TIOCM_LOOP Set the port into loopback mode.
-
- If the appropriate bit is set, the signal should be driven
- active. If the bit is clear, the signal should be driven
- inactive.
-
- Locking: port->lock taken.
-
- Interrupts: locally disabled.
-
- This call must not sleep
-
- get_mctrl(port)
- Returns the current state of modem control inputs. The state
- of the outputs should not be returned, since the core keeps
- track of their state. The state information should include:
-
- - TIOCM_CAR state of DCD signal
- - TIOCM_CTS state of CTS signal
- - TIOCM_DSR state of DSR signal
- - TIOCM_RI state of RI signal
-
- The bit is set if the signal is currently driven active. If
- the port does not support CTS, DCD or DSR, the driver should
- indicate that the signal is permanently active. If RI is
- not available, the signal should not be indicated as active.
-
- Locking: port->lock taken.
-
- Interrupts: locally disabled.
-
- This call must not sleep
-
- stop_tx(port)
- Stop transmitting characters. This might be due to the CTS
- line becoming inactive or the tty layer indicating we want
- to stop transmission due to an XOFF character.
-
- The driver should stop transmitting characters as soon as
- possible.
-
- Locking: port->lock taken.
-
- Interrupts: locally disabled.
-
- This call must not sleep
-
- start_tx(port)
- Start transmitting characters.
-
- Locking: port->lock taken.
-
- Interrupts: locally disabled.
-
- This call must not sleep
-
- throttle(port)
- Notify the serial driver that input buffers for the line discipline are
- close to full, and it should somehow signal that no more characters
- should be sent to the serial port.
- This will be called only if hardware assisted flow control is enabled.
-
- Locking: serialized with .unthrottle() and termios modification by the
- tty layer.
-
- unthrottle(port)
- Notify the serial driver that characters can now be sent to the serial
- port without fear of overrunning the input buffers of the line
- disciplines.
-
- This will be called only if hardware assisted flow control is enabled.
-
- Locking: serialized with .throttle() and termios modification by the
- tty layer.
-
- send_xchar(port,ch)
- Transmit a high priority character, even if the port is stopped.
- This is used to implement XON/XOFF flow control and tcflow(). If
- the serial driver does not implement this function, the tty core
- will append the character to the circular buffer and then call
- start_tx() / stop_tx() to flush the data out.
-
- Do not transmit if ch == '\0' (__DISABLED_CHAR).
-
- Locking: none.
-
- Interrupts: caller dependent.
-
- stop_rx(port)
- Stop receiving characters; the port is in the process of
- being closed.
-
- Locking: port->lock taken.
-
- Interrupts: locally disabled.
-
- This call must not sleep
-
- enable_ms(port)
- Enable the modem status interrupts.
-
- This method may be called multiple times. Modem status
- interrupts should be disabled when the shutdown method is
- called.
-
- Locking: port->lock taken.
-
- Interrupts: locally disabled.
-
- This call must not sleep
-
- break_ctl(port,ctl)
- Control the transmission of a break signal. If ctl is
- nonzero, the break signal should be transmitted. The signal
- should be terminated when another call is made with a zero
- ctl.
-
- Locking: caller holds tty_port->mutex
-
- startup(port)
- Grab any interrupt resources and initialise any low level driver
- state. Enable the port for reception. It should not activate
- RTS nor DTR; this will be done via a separate call to set_mctrl.
-
- This method will only be called when the port is initially opened.
-
- Locking: port_sem taken.
-
- Interrupts: globally disabled.
-
- shutdown(port)
- Disable the port, disable any break condition that may be in
- effect, and free any interrupt resources. It should not disable
- RTS nor DTR; this will have already been done via a separate
- call to set_mctrl.
-
- Drivers must not access port->state once this call has completed.
-
- This method will only be called when there are no more users of
- this port.
-
- Locking: port_sem taken.
-
- Interrupts: caller dependent.
-
- flush_buffer(port)
- Flush any write buffers, reset any DMA state and stop any
- ongoing DMA transfers.
-
- This will be called whenever the port->state->xmit circular
- buffer is cleared.
-
- Locking: port->lock taken.
-
- Interrupts: locally disabled.
-
- This call must not sleep
-
- set_termios(port,termios,oldtermios)
- Change the port parameters, including word length, parity, stop
- bits. Update read_status_mask and ignore_status_mask to indicate
- the types of events we are interested in receiving. Relevant
- termios->c_cflag bits are:
-
- CSIZE
- - word size
- CSTOPB
- - 2 stop bits
- PARENB
- - parity enable
- PARODD
- - odd parity (when PARENB is in force)
- CREAD
- - enable reception of characters (if not set,
- still receive characters from the port, but
- throw them away.
- CRTSCTS
- - if set, enable CTS status change reporting
- CLOCAL
- - if not set, enable modem status change
- reporting.
-
- Relevant termios->c_iflag bits are:
-
- INPCK
- - enable frame and parity error events to be
- passed to the TTY layer.
- BRKINT / PARMRK
- - both of these enable break events to be
- passed to the TTY layer.
-
- IGNPAR
- - ignore parity and framing errors
- IGNBRK
- - ignore break errors, If IGNPAR is also
- set, ignore overrun errors as well.
-
- The interaction of the iflag bits is as follows (parity error
- given as an example):
-
- =============== ======= ====== =============================
- Parity error INPCK IGNPAR
- =============== ======= ====== =============================
- n/a 0 n/a character received, marked as
- TTY_NORMAL
- None 1 n/a character received, marked as
- TTY_NORMAL
- Yes 1 0 character received, marked as
- TTY_PARITY
- Yes 1 1 character discarded
- =============== ======= ====== =============================
-
- Other flags may be used (eg, xon/xoff characters) if your
- hardware supports hardware "soft" flow control.
-
- Locking: caller holds tty_port->mutex
-
- Interrupts: caller dependent.
-
- This call must not sleep
-
- set_ldisc(port,termios)
- Notifier for discipline change. See Documentation/driver-api/serial/tty.rst.
-
- Locking: caller holds tty_port->mutex
-
- pm(port,state,oldstate)
- Perform any power management related activities on the specified
- port. State indicates the new state (defined by
- enum uart_pm_state), oldstate indicates the previous state.
-
- This function should not be used to grab any resources.
-
- This will be called when the port is initially opened and finally
- closed, except when the port is also the system console. This
- will occur even if CONFIG_PM is not set.
-
- Locking: none.
-
- Interrupts: caller dependent.
-
- type(port)
- Return a pointer to a string constant describing the specified
- port, or return NULL, in which case the string 'unknown' is
- substituted.
-
- Locking: none.
-
- Interrupts: caller dependent.
-
- release_port(port)
- Release any memory and IO region resources currently in use by
- the port.
-
- Locking: none.
-
- Interrupts: caller dependent.
-
- request_port(port)
- Request any memory and IO region resources required by the port.
- If any fail, no resources should be registered when this function
- returns, and it should return -EBUSY on failure.
-
- Locking: none.
-
- Interrupts: caller dependent.
-
- config_port(port,type)
- Perform any autoconfiguration steps required for the port. `type`
- contains a bit mask of the required configuration. UART_CONFIG_TYPE
- indicates that the port requires detection and identification.
- port->type should be set to the type found, or PORT_UNKNOWN if
- no port was detected.
-
- UART_CONFIG_IRQ indicates autoconfiguration of the interrupt signal,
- which should be probed using standard kernel autoprobing techniques.
- This is not necessary on platforms where ports have interrupts
- internally hard wired (eg, system on a chip implementations).
-
- Locking: none.
-
- Interrupts: caller dependent.
-
- verify_port(port,serinfo)
- Verify the new serial port information contained within serinfo is
- suitable for this port type.
-
- Locking: none.
-
- Interrupts: caller dependent.
-
- ioctl(port,cmd,arg)
- Perform any port specific IOCTLs. IOCTL commands must be defined
- using the standard numbering system found in <asm/ioctl.h>
-
- Locking: none.
-
- Interrupts: caller dependent.
-
- poll_init(port)
- Called by kgdb to perform the minimal hardware initialization needed
- to support poll_put_char() and poll_get_char(). Unlike ->startup()
- this should not request interrupts.
-
- Locking: tty_mutex and tty_port->mutex taken.
-
- Interrupts: n/a.
-
- poll_put_char(port,ch)
- Called by kgdb to write a single character directly to the serial
- port. It can and should block until there is space in the TX FIFO.
-
- Locking: none.
-
- Interrupts: caller dependent.
-
- This call must not sleep
-
- poll_get_char(port)
- Called by kgdb to read a single character directly from the serial
- port. If data is available, it should be returned; otherwise
- the function should return NO_POLL_CHAR immediately.
-
- Locking: none.
-
- Interrupts: caller dependent.
-
- This call must not sleep
+.. kernel-doc:: include/linux/serial_core.h
+ :identifiers: uart_ops
Other functions
---------------
-uart_update_timeout(port,cflag,baud)
- Update the FIFO drain timeout, port->timeout, according to the
- number of bits, parity, stop bits and baud rate.
-
- Locking: caller is expected to take port->lock
-
- Interrupts: n/a
-
-uart_get_baud_rate(port,termios,old,min,max)
- Return the numeric baud rate for the specified termios, taking
- account of the special 38400 baud "kludge". The B0 baud rate
- is mapped to 9600 baud.
-
- If the baud rate is not within min..max, then if old is non-NULL,
- the original baud rate will be tried. If that exceeds the
- min..max constraint, 9600 baud will be returned. termios will
- be updated to the baud rate in use.
-
- Note: min..max must always allow 9600 baud to be selected.
-
- Locking: caller dependent.
-
- Interrupts: n/a
-
-uart_get_divisor(port,baud)
- Return the divisor (baud_base / baud) for the specified baud
- rate, appropriately rounded.
-
- If 38400 baud and custom divisor is selected, return the
- custom divisor instead.
-
- Locking: caller dependent.
-
- Interrupts: n/a
-
-uart_match_port(port1,port2)
- This utility function can be used to determine whether two
- uart_port structures describe the same port.
-
- Locking: n/a
-
- Interrupts: n/a
-
-uart_write_wakeup(port)
- A driver is expected to call this function when the number of
- characters in the transmit buffer have dropped below a threshold.
-
- Locking: port->lock should be held.
-
- Interrupts: n/a
-
-uart_register_driver(drv)
- Register a uart driver with the core driver. We in turn register
- with the tty layer, and initialise the core driver per-port state.
-
- drv->port should be NULL, and the per-port structures should be
- registered using uart_add_one_port after this call has succeeded.
-
- Locking: none
-
- Interrupts: enabled
-
-uart_unregister_driver()
- Remove all references to a driver from the core driver. The low
- level driver must have removed all its ports via the
- uart_remove_one_port() if it registered them with uart_add_one_port().
-
- Locking: none
-
- Interrupts: enabled
-
-**uart_suspend_port()**
-
-**uart_resume_port()**
-
-**uart_add_one_port()**
-
-**uart_remove_one_port()**
+.. kernel-doc:: drivers/tty/serial/serial_core.c
+ :identifiers: uart_update_timeout uart_get_baud_rate uart_get_divisor
+ uart_match_port uart_write_wakeup uart_register_driver
+ uart_unregister_driver uart_suspend_port uart_resume_port
+ uart_add_one_port uart_remove_one_port uart_console_write
+ uart_parse_earlycon uart_parse_options uart_set_options
+ uart_get_lsr_info uart_handle_dcd_change uart_handle_cts_change
+ uart_try_toggle_sysrq uart_get_console
Other notes
-----------
@@ -519,31 +97,7 @@ Modem control lines via GPIO
Some helpers are provided in order to set/get modem control lines via GPIO.
-mctrl_gpio_init(port, idx):
- This will get the {cts,rts,...}-gpios from device tree if they are
- present and request them, set direction etc, and return an
- allocated structure. `devm_*` functions are used, so there's no need
- to call mctrl_gpio_free().
- As this sets up the irq handling make sure to not handle changes to the
- gpio input lines in your driver, too.
-
-mctrl_gpio_free(dev, gpios):
- This will free the requested gpios in mctrl_gpio_init().
- As `devm_*` functions are used, there's generally no need to call
- this function.
-
-mctrl_gpio_to_gpiod(gpios, gidx)
- This returns the gpio_desc structure associated to the modem line
- index.
-
-mctrl_gpio_set(gpios, mctrl):
- This will sets the gpios according to the mctrl state.
-
-mctrl_gpio_get(gpios, mctrl):
- This will update mctrl with the gpios values.
-
-mctrl_gpio_enable_ms(gpios):
- Enables irqs and handling of changes to the ms lines.
-
-mctrl_gpio_disable_ms(gpios):
- Disables irqs and handling of changes to the ms lines.
+.. kernel-doc:: drivers/tty/serial/serial_mctrl_gpio.c
+ :identifiers: mctrl_gpio_init mctrl_gpio_free mctrl_gpio_to_gpiod
+ mctrl_gpio_set mctrl_gpio_get mctrl_gpio_enable_ms
+ mctrl_gpio_disable_ms
diff --git a/Documentation/driver-api/serial/index.rst b/Documentation/driver-api/serial/index.rst
index 8f7d7af3b90b..03a55b987a1d 100644
--- a/Documentation/driver-api/serial/index.rst
+++ b/Documentation/driver-api/serial/index.rst
@@ -9,7 +9,6 @@ Support for Serial devices
driver
- tty
Serial drivers
==============
@@ -17,8 +16,6 @@ Serial drivers
.. toctree::
:maxdepth: 1
- moxa-smartio
- n_gsm
serial-iso7816
serial-rs485
diff --git a/Documentation/driver-api/serial/n_gsm.rst b/Documentation/driver-api/serial/n_gsm.rst
deleted file mode 100644
index 8fe723ab9c67..000000000000
--- a/Documentation/driver-api/serial/n_gsm.rst
+++ /dev/null
@@ -1,153 +0,0 @@
-==============================
-GSM 0710 tty multiplexor HOWTO
-==============================
-
-This line discipline implements the GSM 07.10 multiplexing protocol
-detailed in the following 3GPP document:
-
- https://www.3gpp.org/ftp/Specs/archive/07_series/07.10/0710-720.zip
-
-This document give some hints on how to use this driver with GPRS and 3G
-modems connected to a physical serial port.
-
-How to use it
--------------
-1. config initiator
-^^^^^^^^^^^^^^^^^^^^^
-
-1.1 initialize the modem in 0710 mux mode (usually AT+CMUX= command) through
- its serial port. Depending on the modem used, you can pass more or less
- parameters to this command.
-1.2 switch the serial line to using the n_gsm line discipline by using
- TIOCSETD ioctl.
-1.3 configure the mux using GSMIOC_GETCONF / GSMIOC_SETCONF ioctl.
-1.4 obtain base gsmtty number for the used serial port.
-
-Major parts of the initialization program :
-(a good starting point is util-linux-ng/sys-utils/ldattach.c)::
-
- #include <stdio.h>
- #include <stdint.h>
- #include <linux/gsmmux.h>
- #include <linux/tty.h>
- #define DEFAULT_SPEED B115200
- #define SERIAL_PORT /dev/ttyS0
-
- int ldisc = N_GSM0710;
- struct gsm_config c;
- struct termios configuration;
- uint32_t first;
-
- /* open the serial port connected to the modem */
- fd = open(SERIAL_PORT, O_RDWR | O_NOCTTY | O_NDELAY);
-
- /* configure the serial port : speed, flow control ... */
-
- /* send the AT commands to switch the modem to CMUX mode
- and check that it's successful (should return OK) */
- write(fd, "AT+CMUX=0\r", 10);
-
- /* experience showed that some modems need some time before
- being able to answer to the first MUX packet so a delay
- may be needed here in some case */
- sleep(3);
-
- /* use n_gsm line discipline */
- ioctl(fd, TIOCSETD, &ldisc);
-
- /* get n_gsm configuration */
- ioctl(fd, GSMIOC_GETCONF, &c);
- /* we are initiator and need encoding 0 (basic) */
- c.initiator = 1;
- c.encapsulation = 0;
- /* our modem defaults to a maximum size of 127 bytes */
- c.mru = 127;
- c.mtu = 127;
- /* set the new configuration */
- ioctl(fd, GSMIOC_SETCONF, &c);
- /* get first gsmtty device node */
- ioctl(fd, GSMIOC_GETFIRST, &first);
- printf("first muxed line: /dev/gsmtty%i\n", first);
-
- /* and wait for ever to keep the line discipline enabled */
- daemon(0,0);
- pause();
-
-1.5 use these devices as plain serial ports.
-
- for example, it's possible:
-
- - and to use gnokii to send / receive SMS on ttygsm1
- - to use ppp to establish a datalink on ttygsm2
-
-1.6 first close all virtual ports before closing the physical port.
-
- Note that after closing the physical port the modem is still in multiplexing
- mode. This may prevent a successful re-opening of the port later. To avoid
- this situation either reset the modem if your hardware allows that or send
- a disconnect command frame manually before initializing the multiplexing mode
- for the second time. The byte sequence for the disconnect command frame is::
-
- 0xf9, 0x03, 0xef, 0x03, 0xc3, 0x16, 0xf9.
-
-2. config requester
-^^^^^^^^^^^^^^^^^^^^^
-
-2.1 receive string "AT+CMUX= command" through its serial port,initialize
- mux mode config
-2.2 switch the serial line to using the n_gsm line discipline by using
- TIOCSETD ioctl.
-2.3 configure the mux using GSMIOC_GETCONF / GSMIOC_SETCONF ioctl.
-2.4 obtain base gsmtty number for the used serial port,
-
- #include <stdio.h>
- #include <stdint.h>
- #include <linux/gsmmux.h>
- #include <linux/tty.h>
- #define DEFAULT_SPEED B115200
- #define SERIAL_PORT /dev/ttyS0
-
- int ldisc = N_GSM0710;
- struct gsm_config c;
- struct termios configuration;
- uint32_t first;
-
- /* open the serial port */
- fd = open(SERIAL_PORT, O_RDWR | O_NOCTTY | O_NDELAY);
-
- /* configure the serial port : speed, flow control ... */
-
- /* get serial data and check "AT+CMUX=command" parameter ... */
-
- /* use n_gsm line discipline */
- ioctl(fd, TIOCSETD, &ldisc);
-
- /* get n_gsm configuration */
- ioctl(fd, GSMIOC_GETCONF, &c);
- /* we are requester and need encoding 0 (basic) */
- c.initiator = 0;
- c.encapsulation = 0;
- /* our modem defaults to a maximum size of 127 bytes */
- c.mru = 127;
- c.mtu = 127;
- /* set the new configuration */
- ioctl(fd, GSMIOC_SETCONF, &c);
- /* get first gsmtty device node */
- ioctl(fd, GSMIOC_GETFIRST, &first);
- printf("first muxed line: /dev/gsmtty%i\n", first);
-
- /* and wait for ever to keep the line discipline enabled */
- daemon(0,0);
- pause();
-
-Additional Documentation
-------------------------
-More practical details on the protocol and how it's supported by industrial
-modems can be found in the following documents :
-
-- http://www.telit.com/module/infopool/download.php?id=616
-- http://www.u-blox.com/images/downloads/Product_Docs/LEON-G100-G200-MuxImplementation_ApplicationNote_%28GSM%20G1-CS-10002%29.pdf
-- http://www.sierrawireless.com/Support/Downloads/AirPrime/WMP_Series/~/media/Support_Downloads/AirPrime/Application_notes/CMUX_Feature_Application_Note-Rev004.ashx
-- http://wm.sim.com/sim/News/photo/2010721161442.pdf
-
-11-03-08 - Eric Bénard - <eric@eukrea.com>
diff --git a/Documentation/driver-api/serial/serial-rs485.rst b/Documentation/driver-api/serial/serial-rs485.rst
index 6bc824f948f9..6ebad75c74ed 100644
--- a/Documentation/driver-api/serial/serial-rs485.rst
+++ b/Documentation/driver-api/serial/serial-rs485.rst
@@ -38,10 +38,14 @@ RS485 Serial Communications
the values given by the device tree.
Any driver for devices capable of working both as RS232 and RS485 should
- implement the rs485_config callback in the uart_port structure. The
- serial_core calls rs485_config to do the device specific part in response
- to TIOCSRS485 and TIOCGRS485 ioctls (see below). The rs485_config callback
- receives a pointer to struct serial_rs485.
+ implement the rs485_config callback and provide rs485_supported in the
+ uart_port structure. The serial core calls rs485_config to do the device
+ specific part in response to TIOCSRS485 ioctl (see below). The rs485_config
+ callback receives a pointer to a sanitizated serial_rs485 structure. The
+ serial_rs485 userspace provides is sanitized before calling rs485_config
+ using rs485_supported that indicates what RS485 features the driver supports
+ for the uart_port. TIOCGRS485 ioctl can be used to read back the
+ serial_rs485 structure matching to the current configuration.
4. Usage from user-level
========================
@@ -95,7 +99,31 @@ RS485 Serial Communications
/* Error handling. See errno. */
}
-5. References
+5. Multipoint Addressing
+========================
+
+ The Linux kernel provides addressing mode for multipoint RS-485 serial
+ communications line. The addressing mode is enabled with SER_RS485_ADDRB
+ flag in serial_rs485. Struct serial_rs485 has two additional flags and
+ fields for enabling receive and destination addresses.
+
+ Address mode flags:
+ - SER_RS485_ADDRB: Enabled addressing mode (sets also ADDRB in termios).
+ - SER_RS485_ADDR_RECV: Receive (filter) address enabled.
+ - SER_RS485_ADDR_DEST: Set destination address.
+
+ Address fields (enabled with corresponding SER_RS485_ADDR_* flag):
+ - addr_recv: Receive address.
+ - addr_dest: Destination address.
+
+ Once a receive address is set, the communication can occur only with the
+ particular device and other peers are filtered out. It is left up to the
+ receiver side to enforce the filtering. Receive address will be cleared
+ if SER_RS485_ADDR_RECV is not set.
+
+ Note: not all devices supporting RS485 support multipoint addressing.
+
+6. References
=============
[1] include/uapi/linux/serial.h
diff --git a/Documentation/driver-api/serial/tty.rst b/Documentation/driver-api/serial/tty.rst
deleted file mode 100644
index 4b709f392713..000000000000
--- a/Documentation/driver-api/serial/tty.rst
+++ /dev/null
@@ -1,328 +0,0 @@
-=================
-The Lockronomicon
-=================
-
-Your guide to the ancient and twisted locking policies of the tty layer and
-the warped logic behind them. Beware all ye who read on.
-
-
-Line Discipline
----------------
-
-Line disciplines are registered with tty_register_ldisc() passing the
-discipline number and the ldisc structure. At the point of registration the
-discipline must be ready to use and it is possible it will get used before
-the call returns success. If the call returns an error then it won't get
-called. Do not re-use ldisc numbers as they are part of the userspace ABI
-and writing over an existing ldisc will cause demons to eat your computer.
-After the return the ldisc data has been copied so you may free your own
-copy of the structure. You must not re-register over the top of the line
-discipline even with the same data or your computer again will be eaten by
-demons.
-
-In order to remove a line discipline call tty_unregister_ldisc().
-In ancient times this always worked. In modern times the function will
-return -EBUSY if the ldisc is currently in use. Since the ldisc referencing
-code manages the module counts this should not usually be a concern.
-
-Heed this warning: the reference count field of the registered copies of the
-tty_ldisc structure in the ldisc table counts the number of lines using this
-discipline. The reference count of the tty_ldisc structure within a tty
-counts the number of active users of the ldisc at this instant. In effect it
-counts the number of threads of execution within an ldisc method (plus those
-about to enter and exit although this detail matters not).
-
-Line Discipline Methods
------------------------
-
-TTY side interfaces
-^^^^^^^^^^^^^^^^^^^
-
-======================= =======================================================
-open() Called when the line discipline is attached to
- the terminal. No other call into the line
- discipline for this tty will occur until it
- completes successfully. Should initialize any
- state needed by the ldisc, and set receive_room
- in the tty_struct to the maximum amount of data
- the line discipline is willing to accept from the
- driver with a single call to receive_buf().
- Returning an error will prevent the ldisc from
- being attached. Can sleep.
-
-close() This is called on a terminal when the line
- discipline is being unplugged. At the point of
- execution no further users will enter the
- ldisc code for this tty. Can sleep.
-
-hangup() Called when the tty line is hung up.
- The line discipline should cease I/O to the tty.
- No further calls into the ldisc code will occur.
- Can sleep.
-
-read() (optional) A process requests reading data from
- the line. Multiple read calls may occur in parallel
- and the ldisc must deal with serialization issues.
- If not defined, the process will receive an EIO
- error. May sleep.
-
-write() (optional) A process requests writing data to the
- line. Multiple write calls are serialized by the
- tty layer for the ldisc. If not defined, the
- process will receive an EIO error. May sleep.
-
-flush_buffer() (optional) May be called at any point between
- open and close, and instructs the line discipline
- to empty its input buffer.
-
-set_termios() (optional) Called on termios structure changes.
- The caller passes the old termios data and the
- current data is in the tty. Called under the
- termios semaphore so allowed to sleep. Serialized
- against itself only.
-
-poll() (optional) Check the status for the poll/select
- calls. Multiple poll calls may occur in parallel.
- May sleep.
-
-ioctl() (optional) Called when an ioctl is handed to the
- tty layer that might be for the ldisc. Multiple
- ioctl calls may occur in parallel. May sleep.
-
-compat_ioctl() (optional) Called when a 32 bit ioctl is handed
- to the tty layer that might be for the ldisc.
- Multiple ioctl calls may occur in parallel.
- May sleep.
-======================= =======================================================
-
-Driver Side Interfaces
-^^^^^^^^^^^^^^^^^^^^^^
-
-======================= =======================================================
-receive_buf() (optional) Called by the low-level driver to hand
- a buffer of received bytes to the ldisc for
- processing. The number of bytes is guaranteed not
- to exceed the current value of tty->receive_room.
- All bytes must be processed.
-
-receive_buf2() (optional) Called by the low-level driver to hand
- a buffer of received bytes to the ldisc for
- processing. Returns the number of bytes processed.
-
- If both receive_buf() and receive_buf2() are
- defined, receive_buf2() should be preferred.
-
-write_wakeup() May be called at any point between open and close.
- The TTY_DO_WRITE_WAKEUP flag indicates if a call
- is needed but always races versus calls. Thus the
- ldisc must be careful about setting order and to
- handle unexpected calls. Must not sleep.
-
- The driver is forbidden from calling this directly
- from the ->write call from the ldisc as the ldisc
- is permitted to call the driver write method from
- this function. In such a situation defer it.
-
-dcd_change() Report to the tty line the current DCD pin status
- changes and the relative timestamp. The timestamp
- cannot be NULL.
-======================= =======================================================
-
-
-Driver Access
-^^^^^^^^^^^^^
-
-Line discipline methods can call the following methods of the underlying
-hardware driver through the function pointers within the tty->driver
-structure:
-
-======================= =======================================================
-write() Write a block of characters to the tty device.
- Returns the number of characters accepted. The
- character buffer passed to this method is already
- in kernel space.
-
-put_char() Queues a character for writing to the tty device.
- If there is no room in the queue, the character is
- ignored.
-
-flush_chars() (Optional) If defined, must be called after
- queueing characters with put_char() in order to
- start transmission.
-
-write_room() Returns the numbers of characters the tty driver
- will accept for queueing to be written.
-
-ioctl() Invoke device specific ioctl.
- Expects data pointers to refer to userspace.
- Returns ENOIOCTLCMD for unrecognized ioctl numbers.
-
-set_termios() Notify the tty driver that the device's termios
- settings have changed. New settings are in
- tty->termios. Previous settings should be passed in
- the "old" argument.
-
- The API is defined such that the driver should return
- the actual modes selected. This means that the
- driver function is responsible for modifying any
- bits in the request it cannot fulfill to indicate
- the actual modes being used. A device with no
- hardware capability for change (e.g. a USB dongle or
- virtual port) can provide NULL for this method.
-
-throttle() Notify the tty driver that input buffers for the
- line discipline are close to full, and it should
- somehow signal that no more characters should be
- sent to the tty.
-
-unthrottle() Notify the tty driver that characters can now be
- sent to the tty without fear of overrunning the
- input buffers of the line disciplines.
-
-stop() Ask the tty driver to stop outputting characters
- to the tty device.
-
-start() Ask the tty driver to resume sending characters
- to the tty device.
-
-hangup() Ask the tty driver to hang up the tty device.
-
-break_ctl() (Optional) Ask the tty driver to turn on or off
- BREAK status on the RS-232 port. If state is -1,
- then the BREAK status should be turned on; if
- state is 0, then BREAK should be turned off.
- If this routine is not implemented, use ioctls
- TIOCSBRK / TIOCCBRK instead.
-
-wait_until_sent() Waits until the device has written out all of the
- characters in its transmitter FIFO.
-
-send_xchar() Send a high-priority XON/XOFF character to the device.
-======================= =======================================================
-
-
-Flags
-^^^^^
-
-Line discipline methods have access to tty->flags field containing the
-following interesting flags:
-
-======================= =======================================================
-TTY_THROTTLED Driver input is throttled. The ldisc should call
- tty->driver->unthrottle() in order to resume
- reception when it is ready to process more data.
-
-TTY_DO_WRITE_WAKEUP If set, causes the driver to call the ldisc's
- write_wakeup() method in order to resume
- transmission when it can accept more data
- to transmit.
-
-TTY_IO_ERROR If set, causes all subsequent userspace read/write
- calls on the tty to fail, returning -EIO.
-
-TTY_OTHER_CLOSED Device is a pty and the other side has closed.
-
-TTY_NO_WRITE_SPLIT Prevent driver from splitting up writes into
- smaller chunks.
-======================= =======================================================
-
-
-Locking
-^^^^^^^
-
-Callers to the line discipline functions from the tty layer are required to
-take line discipline locks. The same is true of calls from the driver side
-but not yet enforced.
-
-Three calls are now provided::
-
- ldisc = tty_ldisc_ref(tty);
-
-takes a handle to the line discipline in the tty and returns it. If no ldisc
-is currently attached or the ldisc is being closed and re-opened at this
-point then NULL is returned. While this handle is held the ldisc will not
-change or go away::
-
- tty_ldisc_deref(ldisc)
-
-Returns the ldisc reference and allows the ldisc to be closed. Returning the
-reference takes away your right to call the ldisc functions until you take
-a new reference::
-
- ldisc = tty_ldisc_ref_wait(tty);
-
-Performs the same function as tty_ldisc_ref except that it will wait for an
-ldisc change to complete and then return a reference to the new ldisc.
-
-While these functions are slightly slower than the old code they should have
-minimal impact as most receive logic uses the flip buffers and they only
-need to take a reference when they push bits up through the driver.
-
-A caution: The ldisc->open(), ldisc->close() and driver->set_ldisc
-functions are called with the ldisc unavailable. Thus tty_ldisc_ref will
-fail in this situation if used within these functions. Ldisc and driver
-code calling its own functions must be careful in this case.
-
-
-Driver Interface
-----------------
-
-======================= =======================================================
-open() Called when a device is opened. May sleep
-
-close() Called when a device is closed. At the point of
- return from this call the driver must make no
- further ldisc calls of any kind. May sleep
-
-write() Called to write bytes to the device. May not
- sleep. May occur in parallel in special cases.
- Because this includes panic paths drivers generally
- shouldn't try and do clever locking here.
-
-put_char() Stuff a single character onto the queue. The
- driver is guaranteed following up calls to
- flush_chars.
-
-flush_chars() Ask the kernel to write put_char queue
-
-write_room() Return the number of characters that can be stuffed
- into the port buffers without overflow (or less).
- The ldisc is responsible for being intelligent
- about multi-threading of write_room/write calls
-
-ioctl() Called when an ioctl may be for the driver
-
-set_termios() Called on termios change, serialized against
- itself by a semaphore. May sleep.
-
-set_ldisc() Notifier for discipline change. At the point this
- is done the discipline is not yet usable. Can now
- sleep (I think)
-
-throttle() Called by the ldisc to ask the driver to do flow
- control. Serialization including with unthrottle
- is the job of the ldisc layer.
-
-unthrottle() Called by the ldisc to ask the driver to stop flow
- control.
-
-stop() Ldisc notifier to the driver to stop output. As with
- throttle the serializations with start() are down
- to the ldisc layer.
-
-start() Ldisc notifier to the driver to start output.
-
-hangup() Ask the tty driver to cause a hangup initiated
- from the host side. [Can sleep ??]
-
-break_ctl() Send RS232 break. Can sleep. Can get called in
- parallel, driver must serialize (for now), and
- with write calls.
-
-wait_until_sent() Wait for characters to exit the hardware queue
- of the driver. Can sleep
-
-send_xchar() Send XON/XOFF and if possible jump the queue with
- it in order to get fast flow control responses.
- Cannot sleep ??
-======================= =======================================================
diff --git a/Documentation/driver-api/surface_aggregator/client.rst b/Documentation/driver-api/surface_aggregator/client.rst
index e519d374c378..27f95abdbe99 100644
--- a/Documentation/driver-api/surface_aggregator/client.rst
+++ b/Documentation/driver-api/surface_aggregator/client.rst
@@ -17,6 +17,8 @@
.. |SSAM_DEVICE| replace:: :c:func:`SSAM_DEVICE`
.. |ssam_notifier_register| replace:: :c:func:`ssam_notifier_register`
.. |ssam_notifier_unregister| replace:: :c:func:`ssam_notifier_unregister`
+.. |ssam_device_notifier_register| replace:: :c:func:`ssam_device_notifier_register`
+.. |ssam_device_notifier_unregister| replace:: :c:func:`ssam_device_notifier_unregister`
.. |ssam_request_sync| replace:: :c:func:`ssam_request_sync`
.. |ssam_event_mask| replace:: :c:type:`enum ssam_event_mask <ssam_event_mask>`
@@ -312,7 +314,9 @@ Handling Events
To receive events from the SAM EC, an event notifier must be registered for
the desired event via |ssam_notifier_register|. The notifier must be
unregistered via |ssam_notifier_unregister| once it is not required any
-more.
+more. For |ssam_device| type clients, the |ssam_device_notifier_register| and
+|ssam_device_notifier_unregister| wrappers should be preferred as they properly
+handle hot-removal of client devices.
Event notifiers are registered by providing (at minimum) a callback to call
in case an event has been received, the registry specifying how the event
diff --git a/Documentation/driver-api/thermal/index.rst b/Documentation/driver-api/thermal/index.rst
index 4cb0b9b6bfb8..030306ffa408 100644
--- a/Documentation/driver-api/thermal/index.rst
+++ b/Documentation/driver-api/thermal/index.rst
@@ -17,3 +17,4 @@ Thermal
intel_powerclamp
nouveau_thermal
x86_pkg_temperature_thermal
+ intel_dptf
diff --git a/Documentation/driver-api/thermal/intel_dptf.rst b/Documentation/driver-api/thermal/intel_dptf.rst
new file mode 100644
index 000000000000..372bdb4d04c6
--- /dev/null
+++ b/Documentation/driver-api/thermal/intel_dptf.rst
@@ -0,0 +1,272 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+===============================================================
+Intel(R) Dynamic Platform and Thermal Framework Sysfs Interface
+===============================================================
+
+:Copyright: © 2022 Intel Corporation
+
+:Author: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
+
+Introduction
+------------
+
+Intel(R) Dynamic Platform and Thermal Framework (DPTF) is a platform
+level hardware/software solution for power and thermal management.
+
+As a container for multiple power/thermal technologies, DPTF provides
+a coordinated approach for different policies to effect the hardware
+state of a system.
+
+Since it is a platform level framework, this has several components.
+Some parts of the technology is implemented in the firmware and uses
+ACPI and PCI devices to expose various features for monitoring and
+control. Linux has a set of kernel drivers exposing hardware interface
+to user space. This allows user space thermal solutions like
+"Linux Thermal Daemon" to read platform specific thermal and power
+tables to deliver adequate performance while keeping the system under
+thermal limits.
+
+DPTF ACPI Drivers interface
+----------------------------
+
+:file:`/sys/bus/platform/devices/<N>/uuids`, where <N>
+=INT3400|INTC1040|INTC1041|INTC10A0
+
+``available_uuids`` (RO)
+ A set of UUIDs strings presenting available policies
+ which should be notified to the firmware when the
+ user space can support those policies.
+
+ UUID strings:
+
+ "42A441D6-AE6A-462b-A84B-4A8CE79027D3" : Passive 1
+
+ "3A95C389-E4B8-4629-A526-C52C88626BAE" : Active
+
+ "97C68AE7-15FA-499c-B8C9-5DA81D606E0A" : Critical
+
+ "63BE270F-1C11-48FD-A6F7-3AF253FF3E2D" : Adaptive performance
+
+ "5349962F-71E6-431D-9AE8-0A635B710AEE" : Emergency call
+
+ "9E04115A-AE87-4D1C-9500-0F3E340BFE75" : Passive 2
+
+ "F5A35014-C209-46A4-993A-EB56DE7530A1" : Power Boss
+
+ "6ED722A7-9240-48A5-B479-31EEF723D7CF" : Virtual Sensor
+
+ "16CAF1B7-DD38-40ED-B1C1-1B8A1913D531" : Cooling mode
+
+ "BE84BABF-C4D4-403D-B495-3128FD44dAC1" : HDC
+
+``current_uuid`` (RW)
+ User space can write strings from available UUIDs, one at a
+ time.
+
+:file:`/sys/bus/platform/devices/<N>/`, where <N>
+=INT3400|INTC1040|INTC1041|INTC10A0
+
+``imok`` (WO)
+ User space daemon write 1 to respond to firmware event
+ for sending keep alive notification. User space receives
+ THERMAL_EVENT_KEEP_ALIVE kobject uevent notification when
+ firmware calls for user space to respond with imok ACPI
+ method.
+
+``odvp*`` (RO)
+ Firmware thermal status variable values. Thermal tables
+ calls for different processing based on these variable
+ values.
+
+``data_vault`` (RO)
+ Binary thermal table. Refer to
+ https:/github.com/intel/thermal_daemon for decoding
+ thermal table.
+
+
+ACPI Thermal Relationship table interface
+------------------------------------------
+
+:file:`/dev/acpi_thermal_rel`
+
+ This device provides IOCTL interface to read standard ACPI
+ thermal relationship tables via ACPI methods _TRT and _ART.
+ These IOCTLs are defined in
+ drivers/thermal/intel/int340x_thermal/acpi_thermal_rel.h
+
+ IOCTLs:
+
+ ACPI_THERMAL_GET_TRT_LEN: Get length of TRT table
+
+ ACPI_THERMAL_GET_ART_LEN: Get length of ART table
+
+ ACPI_THERMAL_GET_TRT_COUNT: Number of records in TRT table
+
+ ACPI_THERMAL_GET_ART_COUNT: Number of records in ART table
+
+ ACPI_THERMAL_GET_TRT: Read binary TRT table, length to read is
+ provided via argument to ioctl().
+
+ ACPI_THERMAL_GET_ART: Read binary ART table, length to read is
+ provided via argument to ioctl().
+
+DPTF ACPI Sensor drivers
+-------------------------
+
+DPTF Sensor drivers are presented as standard thermal sysfs thermal_zone.
+
+
+DPTF ACPI Cooling drivers
+--------------------------
+
+DPTF cooling drivers are presented as standard thermal sysfs cooling_device.
+
+
+DPTF Processor thermal PCI Driver interface
+--------------------------------------------
+
+:file:`/sys/bus/pci/devices/0000\:00\:04.0/power_limits/`
+
+Refer to Documentation/power/powercap/powercap.rst for powercap
+ABI.
+
+``power_limit_0_max_uw`` (RO)
+ Maximum powercap sysfs constraint_0_power_limit_uw for Intel RAPL
+
+``power_limit_0_step_uw`` (RO)
+ Power limit increment/decrements for Intel RAPL constraint 0 power limit
+
+``power_limit_0_min_uw`` (RO)
+ Minimum powercap sysfs constraint_0_power_limit_uw for Intel RAPL
+
+``power_limit_0_tmin_us`` (RO)
+ Minimum powercap sysfs constraint_0_time_window_us for Intel RAPL
+
+``power_limit_0_tmax_us`` (RO)
+ Maximum powercap sysfs constraint_0_time_window_us for Intel RAPL
+
+``power_limit_1_max_uw`` (RO)
+ Maximum powercap sysfs constraint_1_power_limit_uw for Intel RAPL
+
+``power_limit_1_step_uw`` (RO)
+ Power limit increment/decrements for Intel RAPL constraint 1 power limit
+
+``power_limit_1_min_uw`` (RO)
+ Minimum powercap sysfs constraint_1_power_limit_uw for Intel RAPL
+
+``power_limit_1_tmin_us`` (RO)
+ Minimum powercap sysfs constraint_1_time_window_us for Intel RAPL
+
+``power_limit_1_tmax_us`` (RO)
+ Maximum powercap sysfs constraint_1_time_window_us for Intel RAPL
+
+:file:`/sys/bus/pci/devices/0000\:00\:04.0/`
+
+``tcc_offset_degree_celsius`` (RW)
+ TCC offset from the critical temperature where hardware will throttle
+ CPU.
+
+:file:`/sys/bus/pci/devices/0000\:00\:04.0/workload_request`
+
+``workload_available_types`` (RO)
+ Available workload types. User space can specify one of the workload type
+ it is currently executing via workload_type. For example: idle, bursty,
+ sustained etc.
+
+``workload_type`` (RW)
+ User space can specify any one of the available workload type using
+ this interface.
+
+DPTF Processor thermal RFIM interface
+--------------------------------------------
+
+RFIM interface allows adjustment of FIVR (Fully Integrated Voltage Regulator)
+and DDR (Double Data Rate)frequencies to avoid RF interference with WiFi and 5G.
+
+Switching voltage regulators (VR) generate radiated EMI or RFI at the
+fundamental frequency and its harmonics. Some harmonics may interfere
+with very sensitive wireless receivers such as Wi-Fi and cellular that
+are integrated into host systems like notebook PCs. One of mitigation
+methods is requesting SOC integrated VR (IVR) switching frequency to a
+small % and shift away the switching noise harmonic interference from
+radio channels. OEM or ODMs can use the driver to control SOC IVR
+operation within the range where it does not impact IVR performance.
+
+DRAM devices of DDR IO interface and their power plane can generate EMI
+at the data rates. Similar to IVR control mechanism, Intel offers a
+mechanism by which DDR data rates can be changed if several conditions
+are met: there is strong RFI interference because of DDR; CPU power
+management has no other restriction in changing DDR data rates;
+PC ODMs enable this feature (real time DDR RFI Mitigation referred to as
+DDR-RFIM) for Wi-Fi from BIOS.
+
+
+FIVR attributes
+
+:file:`/sys/bus/pci/devices/0000\:00\:04.0/fivr/`
+
+``vco_ref_code_lo`` (RW)
+ The VCO reference code is an 11-bit field and controls the FIVR
+ switching frequency. This is the 3-bit LSB field.
+
+``vco_ref_code_hi`` (RW)
+ The VCO reference code is an 11-bit field and controls the FIVR
+ switching frequency. This is the 8-bit MSB field.
+
+``spread_spectrum_pct`` (RW)
+ Set the FIVR spread spectrum clocking percentage
+
+``spread_spectrum_clk_enable`` (RW)
+ Enable/disable of the FIVR spread spectrum clocking feature
+
+``rfi_vco_ref_code`` (RW)
+ This field is a read only status register which reflects the
+ current FIVR switching frequency
+
+``fivr_fffc_rev`` (RW)
+ This field indicated the revision of the FIVR HW.
+
+
+DVFS attributes
+
+:file:`/sys/bus/pci/devices/0000\:00\:04.0/dvfs/`
+
+``rfi_restriction_run_busy`` (RW)
+ Request the restriction of specific DDR data rate and set this
+ value 1. Self reset to 0 after operation.
+
+``rfi_restriction_err_code`` (RW)
+ 0 :Request is accepted, 1:Feature disabled,
+ 2: the request restricts more points than it is allowed
+
+``rfi_restriction_data_rate_Delta`` (RW)
+ Restricted DDR data rate for RFI protection: Lower Limit
+
+``rfi_restriction_data_rate_Base`` (RW)
+ Restricted DDR data rate for RFI protection: Upper Limit
+
+``ddr_data_rate_point_0`` (RO)
+ DDR data rate selection 1st point
+
+``ddr_data_rate_point_1`` (RO)
+ DDR data rate selection 2nd point
+
+``ddr_data_rate_point_2`` (RO)
+ DDR data rate selection 3rd point
+
+``ddr_data_rate_point_3`` (RO)
+ DDR data rate selection 4th point
+
+``rfi_disable (RW)``
+ Disable DDR rate change feature
+
+DPTF Power supply and Battery Interface
+----------------------------------------
+
+Refer to Documentation/ABI/testing/sysfs-platform-dptf
+
+DPTF Fan Control
+----------------------------------------
+
+Refer to Documentation/admin-guide/acpi/fan_performance_states.rst
diff --git a/Documentation/driver-api/tty/index.rst b/Documentation/driver-api/tty/index.rst
new file mode 100644
index 000000000000..2d32606a4278
--- /dev/null
+++ b/Documentation/driver-api/tty/index.rst
@@ -0,0 +1,73 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+===
+TTY
+===
+
+Teletypewriter (TTY) layer takes care of all those serial devices. Including
+the virtual ones like pseudoterminal (PTY).
+
+TTY structures
+==============
+
+There are several major TTY structures. Every TTY device in a system has a
+corresponding struct tty_port. These devices are maintained by a TTY driver
+which is struct tty_driver. This structure describes the driver but also
+contains a reference to operations which could be performed on the TTYs. It is
+struct tty_operations. Then, upon open, a struct tty_struct is allocated and
+lives until the final close. During this time, several callbacks from struct
+tty_operations are invoked by the TTY layer.
+
+Every character received by the kernel (both from devices and users) is passed
+through a preselected :doc:`tty_ldisc` (in
+short ldisc; in C, struct tty_ldisc_ops). Its task is to transform characters
+as defined by a particular ldisc or by user too. The default one is n_tty,
+implementing echoes, signal handling, jobs control, special characters
+processing, and more. The transformed characters are passed further to
+user/device, depending on the source.
+
+In-detail description of the named TTY structures is in separate documents:
+
+.. toctree::
+ :maxdepth: 2
+
+ tty_driver
+ tty_port
+ tty_struct
+ tty_ldisc
+ tty_buffer
+ tty_internals
+
+Writing TTY Driver
+==================
+
+Before one starts writing a TTY driver, they must consider
+:doc:`Serial <../serial/driver>` and :doc:`USB Serial <../../usb/usb-serial>`
+layers first. Drivers for serial devices can often use one of these specific
+layers to implement a serial driver. Only special devices should be handled
+directly by the TTY Layer. If you are about to write such a driver, read on.
+
+A *typical* sequence a TTY driver performs is as follows:
+
+#. Allocate and register a TTY driver (module init)
+#. Create and register TTY devices as they are probed (probe function)
+#. Handle TTY operations and events like interrupts (TTY core invokes the
+ former, the device the latter)
+#. Remove devices as they are going away (remove function)
+#. Unregister and free the TTY driver (module exit)
+
+Steps regarding driver, i.e. 1., 3., and 5. are described in detail in
+:doc:`tty_driver`. For the other two (devices handling), look into
+:doc:`tty_port`.
+
+Other Documentation
+===================
+
+Miscellaneous documentation can be further found in these documents:
+
+.. toctree::
+ :maxdepth: 2
+
+ moxa-smartio
+ n_gsm
+ n_tty
diff --git a/Documentation/driver-api/serial/moxa-smartio.rst b/Documentation/driver-api/tty/moxa-smartio.rst
index af25bc5cc3e6..af25bc5cc3e6 100644
--- a/Documentation/driver-api/serial/moxa-smartio.rst
+++ b/Documentation/driver-api/tty/moxa-smartio.rst
diff --git a/Documentation/driver-api/tty/n_gsm.rst b/Documentation/driver-api/tty/n_gsm.rst
new file mode 100644
index 000000000000..35d7381515b0
--- /dev/null
+++ b/Documentation/driver-api/tty/n_gsm.rst
@@ -0,0 +1,153 @@
+==============================
+GSM 0710 tty multiplexor HOWTO
+==============================
+
+.. contents:: :local:
+
+This line discipline implements the GSM 07.10 multiplexing protocol
+detailed in the following 3GPP document:
+
+ https://www.3gpp.org/ftp/Specs/archive/07_series/07.10/0710-720.zip
+
+This document give some hints on how to use this driver with GPRS and 3G
+modems connected to a physical serial port.
+
+How to use it
+=============
+
+Config Initiator
+----------------
+
+#. Initialize the modem in 0710 mux mode (usually ``AT+CMUX=`` command) through
+ its serial port. Depending on the modem used, you can pass more or less
+ parameters to this command.
+
+#. Switch the serial line to using the n_gsm line discipline by using
+ ``TIOCSETD`` ioctl.
+
+#. Configure the mux using ``GSMIOC_GETCONF``/``GSMIOC_SETCONF`` ioctl.
+
+#. Obtain base gsmtty number for the used serial port.
+
+ Major parts of the initialization program
+ (a good starting point is util-linux-ng/sys-utils/ldattach.c)::
+
+ #include <stdio.h>
+ #include <stdint.h>
+ #include <linux/gsmmux.h>
+ #include <linux/tty.h>
+
+ #define DEFAULT_SPEED B115200
+ #define SERIAL_PORT /dev/ttyS0
+
+ int ldisc = N_GSM0710;
+ struct gsm_config c;
+ struct termios configuration;
+ uint32_t first;
+
+ /* open the serial port connected to the modem */
+ fd = open(SERIAL_PORT, O_RDWR | O_NOCTTY | O_NDELAY);
+
+ /* configure the serial port : speed, flow control ... */
+
+ /* send the AT commands to switch the modem to CMUX mode
+ and check that it's successful (should return OK) */
+ write(fd, "AT+CMUX=0\r", 10);
+
+ /* experience showed that some modems need some time before
+ being able to answer to the first MUX packet so a delay
+ may be needed here in some case */
+ sleep(3);
+
+ /* use n_gsm line discipline */
+ ioctl(fd, TIOCSETD, &ldisc);
+
+ /* get n_gsm configuration */
+ ioctl(fd, GSMIOC_GETCONF, &c);
+ /* we are initiator and need encoding 0 (basic) */
+ c.initiator = 1;
+ c.encapsulation = 0;
+ /* our modem defaults to a maximum size of 127 bytes */
+ c.mru = 127;
+ c.mtu = 127;
+ /* set the new configuration */
+ ioctl(fd, GSMIOC_SETCONF, &c);
+ /* get first gsmtty device node */
+ ioctl(fd, GSMIOC_GETFIRST, &first);
+ printf("first muxed line: /dev/gsmtty%i\n", first);
+
+ /* and wait for ever to keep the line discipline enabled */
+ daemon(0,0);
+ pause();
+
+#. Use these devices as plain serial ports.
+
+ For example, it's possible:
+
+ - to use *gnokii* to send / receive SMS on ``ttygsm1``
+ - to use *ppp* to establish a datalink on ``ttygsm2``
+
+#. First close all virtual ports before closing the physical port.
+
+ Note that after closing the physical port the modem is still in multiplexing
+ mode. This may prevent a successful re-opening of the port later. To avoid
+ this situation either reset the modem if your hardware allows that or send
+ a disconnect command frame manually before initializing the multiplexing mode
+ for the second time. The byte sequence for the disconnect command frame is::
+
+ 0xf9, 0x03, 0xef, 0x03, 0xc3, 0x16, 0xf9
+
+Config Requester
+----------------
+
+#. Receive ``AT+CMUX=`` command through its serial port, initialize mux mode
+ config.
+
+#. Switch the serial line to using the *n_gsm* line discipline by using
+ ``TIOCSETD`` ioctl.
+
+#. Configure the mux using ``GSMIOC_GETCONF``/``GSMIOC_SETCONF`` ioctl.
+
+#. Obtain base gsmtty number for the used serial port::
+
+ #include <stdio.h>
+ #include <stdint.h>
+ #include <linux/gsmmux.h>
+ #include <linux/tty.h>
+ #define DEFAULT_SPEED B115200
+ #define SERIAL_PORT /dev/ttyS0
+
+ int ldisc = N_GSM0710;
+ struct gsm_config c;
+ struct termios configuration;
+ uint32_t first;
+
+ /* open the serial port */
+ fd = open(SERIAL_PORT, O_RDWR | O_NOCTTY | O_NDELAY);
+
+ /* configure the serial port : speed, flow control ... */
+
+ /* get serial data and check "AT+CMUX=command" parameter ... */
+
+ /* use n_gsm line discipline */
+ ioctl(fd, TIOCSETD, &ldisc);
+
+ /* get n_gsm configuration */
+ ioctl(fd, GSMIOC_GETCONF, &c);
+ /* we are requester and need encoding 0 (basic) */
+ c.initiator = 0;
+ c.encapsulation = 0;
+ /* our modem defaults to a maximum size of 127 bytes */
+ c.mru = 127;
+ c.mtu = 127;
+ /* set the new configuration */
+ ioctl(fd, GSMIOC_SETCONF, &c);
+ /* get first gsmtty device node */
+ ioctl(fd, GSMIOC_GETFIRST, &first);
+ printf("first muxed line: /dev/gsmtty%i\n", first);
+
+ /* and wait for ever to keep the line discipline enabled */
+ daemon(0,0);
+ pause();
+
+11-03-08 - Eric Bénard - <eric@eukrea.com>
diff --git a/Documentation/driver-api/tty/n_tty.rst b/Documentation/driver-api/tty/n_tty.rst
new file mode 100644
index 000000000000..15b70faee72d
--- /dev/null
+++ b/Documentation/driver-api/tty/n_tty.rst
@@ -0,0 +1,22 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+=====
+N_TTY
+=====
+
+.. contents:: :local:
+
+The default (and fallback) :doc:`TTY line discipline <tty_ldisc>`. It tries to
+handle characters as per POSIX.
+
+External Functions
+==================
+
+.. kernel-doc:: drivers/tty/n_tty.c
+ :export:
+
+Internal Functions
+==================
+
+.. kernel-doc:: drivers/tty/n_tty.c
+ :internal:
diff --git a/Documentation/driver-api/tty/tty_buffer.rst b/Documentation/driver-api/tty/tty_buffer.rst
new file mode 100644
index 000000000000..a39d4781e0d2
--- /dev/null
+++ b/Documentation/driver-api/tty/tty_buffer.rst
@@ -0,0 +1,46 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+==========
+TTY Buffer
+==========
+
+.. contents:: :local:
+
+Here, we document functions for taking care of tty buffer and their flipping.
+Drivers are supposed to fill the buffer by one of those functions below and
+then flip the buffer, so that the data are passed to :doc:`line discipline
+<tty_ldisc>` for further processing.
+
+Flip Buffer Management
+======================
+
+.. kernel-doc:: drivers/tty/tty_buffer.c
+ :identifiers: tty_prepare_flip_string tty_insert_flip_string_fixed_flag
+ tty_insert_flip_string_flags __tty_insert_flip_char
+ tty_flip_buffer_push tty_ldisc_receive_buf
+
+----
+
+Other Functions
+===============
+
+.. kernel-doc:: drivers/tty/tty_buffer.c
+ :identifiers: tty_buffer_space_avail tty_buffer_set_limit
+
+----
+
+Buffer Locking
+==============
+
+These are used only in special circumstances. Avoid them.
+
+.. kernel-doc:: drivers/tty/tty_buffer.c
+ :identifiers: tty_buffer_lock_exclusive tty_buffer_unlock_exclusive
+
+----
+
+Internal Functions
+==================
+
+.. kernel-doc:: drivers/tty/tty_buffer.c
+ :internal:
diff --git a/Documentation/driver-api/tty/tty_driver.rst b/Documentation/driver-api/tty/tty_driver.rst
new file mode 100644
index 000000000000..cc529f863406
--- /dev/null
+++ b/Documentation/driver-api/tty/tty_driver.rst
@@ -0,0 +1,128 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+=============================
+TTY Driver and TTY Operations
+=============================
+
+.. contents:: :local:
+
+Allocation
+==========
+
+The first thing a driver needs to do is to allocate a struct tty_driver. This
+is done by tty_alloc_driver() (or __tty_alloc_driver()). Next, the newly
+allocated structure is filled with information. See `TTY Driver Reference`_ at
+the end of this document on what actually shall be filled in.
+
+The allocation routines expect a number of devices the driver can handle at
+most and flags. Flags are those starting ``TTY_DRIVER_`` listed and described
+in `TTY Driver Flags`_ below.
+
+When the driver is about to be freed, tty_driver_kref_put() is called on that.
+It will decrements the reference count and if it reaches zero, the driver is
+freed.
+
+For reference, both allocation and deallocation functions are explained here in
+detail:
+
+.. kernel-doc:: drivers/tty/tty_io.c
+ :identifiers: __tty_alloc_driver tty_driver_kref_put
+
+TTY Driver Flags
+----------------
+
+Here comes the documentation of flags accepted by tty_alloc_driver() (or
+__tty_alloc_driver()):
+
+.. kernel-doc:: include/linux/tty_driver.h
+ :doc: TTY Driver Flags
+
+----
+
+Registration
+============
+
+When a struct tty_driver is allocated and filled in, it can be registered using
+tty_register_driver(). It is recommended to pass ``TTY_DRIVER_DYNAMIC_DEV`` in
+flags of tty_alloc_driver(). If it is not passed, *all* devices are also
+registered during tty_register_driver() and the following paragraph of
+registering devices can be skipped for such drivers. However, the struct
+tty_port part in `Registering Devices`_ is still relevant there.
+
+.. kernel-doc:: drivers/tty/tty_io.c
+ :identifiers: tty_register_driver tty_unregister_driver
+
+Registering Devices
+-------------------
+
+Every TTY device shall be backed by a struct tty_port. Usually, TTY drivers
+embed tty_port into device's private structures. Further details about handling
+tty_port can be found in :doc:`tty_port`. The driver is also recommended to use
+tty_port's reference counting by tty_port_get() and tty_port_put(). The final
+put is supposed to free the tty_port including the device's private struct.
+
+Unless ``TTY_DRIVER_DYNAMIC_DEV`` was passed as flags to tty_alloc_driver(),
+TTY driver is supposed to register every device discovered in the system
+(the latter is preferred). This is performed by tty_register_device(). Or by
+tty_register_device_attr() if the driver wants to expose some information
+through struct attribute_group. Both of them register ``index``'th device and
+upon return, the device can be opened. There are also preferred tty_port
+variants described in `Linking Devices to Ports`_ later. It is up to driver to
+manage free indices and choosing the right one. The TTY layer only refuses to
+register more devices than passed to tty_alloc_driver().
+
+When the device is opened, the TTY layer allocates struct tty_struct and starts
+calling operations from :c:member:`tty_driver.ops`, see `TTY Operations
+Reference`_.
+
+The registration routines are documented as follows:
+
+.. kernel-doc:: drivers/tty/tty_io.c
+ :identifiers: tty_register_device tty_register_device_attr
+ tty_unregister_device
+
+----
+
+Linking Devices to Ports
+------------------------
+As stated earlier, every TTY device shall have a struct tty_port assigned to
+it. It must be known to the TTY layer at :c:member:`tty_driver.ops.install()`
+at latest. There are few helpers to *link* the two. Ideally, the driver uses
+tty_port_register_device() or tty_port_register_device_attr() instead of
+tty_register_device() and tty_register_device_attr() at the registration time.
+This way, the driver needs not care about linking later on.
+
+If that is not possible, the driver still can link the tty_port to a specific
+index *before* the actual registration by tty_port_link_device(). If it still
+does not fit, tty_port_install() can be used from the
+:c:member:`tty_driver.ops.install` hook as a last resort. The last one is
+dedicated mostly for in-memory devices like PTY where tty_ports are allocated
+on demand.
+
+The linking routines are documented here:
+
+.. kernel-doc:: drivers/tty/tty_port.c
+ :identifiers: tty_port_link_device tty_port_register_device
+ tty_port_register_device_attr
+
+----
+
+TTY Driver Reference
+====================
+
+All members of struct tty_driver are documented here. The required members are
+noted at the end. struct tty_operations are documented next.
+
+.. kernel-doc:: include/linux/tty_driver.h
+ :identifiers: tty_driver
+
+----
+
+TTY Operations Reference
+========================
+
+When a TTY is registered, these driver hooks can be invoked by the TTY layer:
+
+.. kernel-doc:: include/linux/tty_driver.h
+ :identifiers: tty_operations
+
diff --git a/Documentation/driver-api/tty/tty_internals.rst b/Documentation/driver-api/tty/tty_internals.rst
new file mode 100644
index 000000000000..d0d415820300
--- /dev/null
+++ b/Documentation/driver-api/tty/tty_internals.rst
@@ -0,0 +1,31 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+=============
+TTY Internals
+=============
+
+.. contents:: :local:
+
+Kopen
+=====
+
+These functions serve for opening a TTY from the kernelspace:
+
+.. kernel-doc:: drivers/tty/tty_io.c
+ :identifiers: tty_kopen_exclusive tty_kopen_shared tty_kclose
+
+----
+
+Exported Internal Functions
+===========================
+
+.. kernel-doc:: drivers/tty/tty_io.c
+ :identifiers: tty_release_struct tty_dev_name_to_number tty_get_icount
+
+----
+
+Internal Functions
+==================
+
+.. kernel-doc:: drivers/tty/tty_io.c
+ :internal:
diff --git a/Documentation/driver-api/tty/tty_ldisc.rst b/Documentation/driver-api/tty/tty_ldisc.rst
new file mode 100644
index 000000000000..5144751be804
--- /dev/null
+++ b/Documentation/driver-api/tty/tty_ldisc.rst
@@ -0,0 +1,85 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+===================
+TTY Line Discipline
+===================
+
+.. contents:: :local:
+
+TTY line discipline process all incoming and outgoing character from/to a tty
+device. The default line discipline is :doc:`N_TTY <n_tty>`. It is also a
+fallback if establishing any other discipline for a tty fails. If even N_TTY
+fails, N_NULL takes over. That never fails, but also does not process any
+characters -- it throws them away.
+
+Registration
+============
+
+Line disciplines are registered with tty_register_ldisc() passing the ldisc
+structure. At the point of registration the discipline must be ready to use and
+it is possible it will get used before the call returns success. If the call
+returns an error then it won’t get called. Do not re-use ldisc numbers as they
+are part of the userspace ABI and writing over an existing ldisc will cause
+demons to eat your computer. You must not re-register over the top of the line
+discipline even with the same data or your computer again will be eaten by
+demons. In order to remove a line discipline call tty_unregister_ldisc().
+
+Heed this warning: the reference count field of the registered copies of the
+tty_ldisc structure in the ldisc table counts the number of lines using this
+discipline. The reference count of the tty_ldisc structure within a tty counts
+the number of active users of the ldisc at this instant. In effect it counts
+the number of threads of execution within an ldisc method (plus those about to
+enter and exit although this detail matters not).
+
+.. kernel-doc:: drivers/tty/tty_ldisc.c
+ :identifiers: tty_register_ldisc tty_unregister_ldisc
+
+Other Functions
+===============
+
+.. kernel-doc:: drivers/tty/tty_ldisc.c
+ :identifiers: tty_set_ldisc tty_ldisc_flush
+
+Line Discipline Operations Reference
+====================================
+
+.. kernel-doc:: include/linux/tty_ldisc.h
+ :identifiers: tty_ldisc_ops
+
+Driver Access
+=============
+
+Line discipline methods can call the methods of the underlying hardware driver.
+These are documented as a part of struct tty_operations.
+
+TTY Flags
+=========
+
+Line discipline methods have access to :c:member:`tty_struct.flags` field. See
+:doc:`tty_struct`.
+
+Locking
+=======
+
+Callers to the line discipline functions from the tty layer are required to
+take line discipline locks. The same is true of calls from the driver side
+but not yet enforced.
+
+.. kernel-doc:: drivers/tty/tty_ldisc.c
+ :identifiers: tty_ldisc_ref_wait tty_ldisc_ref tty_ldisc_deref
+
+While these functions are slightly slower than the old code they should have
+minimal impact as most receive logic uses the flip buffers and they only
+need to take a reference when they push bits up through the driver.
+
+A caution: The :c:member:`tty_ldisc_ops.open()`,
+:c:member:`tty_ldisc_ops.close()` and :c:member:`tty_driver.set_ldisc()`
+functions are called with the ldisc unavailable. Thus tty_ldisc_ref() will fail
+in this situation if used within these functions. Ldisc and driver code
+calling its own functions must be careful in this case.
+
+Internal Functions
+==================
+
+.. kernel-doc:: drivers/tty/tty_ldisc.c
+ :internal:
diff --git a/Documentation/driver-api/tty/tty_port.rst b/Documentation/driver-api/tty/tty_port.rst
new file mode 100644
index 000000000000..5cb90e954fcf
--- /dev/null
+++ b/Documentation/driver-api/tty/tty_port.rst
@@ -0,0 +1,70 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+========
+TTY Port
+========
+
+.. contents:: :local:
+
+The TTY drivers are advised to use struct tty_port helpers as much as possible.
+If the drivers implement :c:member:`tty_port.ops.activate()` and
+:c:member:`tty_port.ops.shutdown()`, they can use tty_port_open(),
+tty_port_close(), and tty_port_hangup() in respective
+:c:member:`tty_struct.ops` hooks.
+
+The reference and details are contained in the `TTY Port Reference`_ and `TTY
+Port Operations Reference`_ sections at the bottom.
+
+TTY Port Functions
+==================
+
+Init & Destroy
+--------------
+
+.. kernel-doc:: drivers/tty/tty_port.c
+ :identifiers: tty_port_init tty_port_destroy
+ tty_port_get tty_port_put
+
+Open/Close/Hangup Helpers
+-------------------------
+
+.. kernel-doc:: drivers/tty/tty_port.c
+ :identifiers: tty_port_install tty_port_open tty_port_block_til_ready
+ tty_port_close tty_port_close_start tty_port_close_end tty_port_hangup
+ tty_port_shutdown
+
+TTY Refcounting
+---------------
+
+.. kernel-doc:: drivers/tty/tty_port.c
+ :identifiers: tty_port_tty_get tty_port_tty_set
+
+TTY Helpers
+-----------
+
+.. kernel-doc:: drivers/tty/tty_port.c
+ :identifiers: tty_port_tty_hangup tty_port_tty_wakeup
+
+
+Modem Signals
+-------------
+
+.. kernel-doc:: drivers/tty/tty_port.c
+ :identifiers: tty_port_carrier_raised tty_port_raise_dtr_rts
+ tty_port_lower_dtr_rts
+
+----
+
+TTY Port Reference
+==================
+
+.. kernel-doc:: include/linux/tty_port.h
+ :identifiers: tty_port
+
+----
+
+TTY Port Operations Reference
+=============================
+
+.. kernel-doc:: include/linux/tty_port.h
+ :identifiers: tty_port_operations
diff --git a/Documentation/driver-api/tty/tty_struct.rst b/Documentation/driver-api/tty/tty_struct.rst
new file mode 100644
index 000000000000..c72f5a4293b2
--- /dev/null
+++ b/Documentation/driver-api/tty/tty_struct.rst
@@ -0,0 +1,81 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+==========
+TTY Struct
+==========
+
+.. contents:: :local:
+
+struct tty_struct is allocated by the TTY layer upon the first open of the TTY
+device and released after the last close. The TTY layer passes this structure
+to most of struct tty_operation's hooks. Members of tty_struct are documented
+in `TTY Struct Reference`_ at the bottom.
+
+Initialization
+==============
+
+.. kernel-doc:: drivers/tty/tty_io.c
+ :identifiers: tty_init_termios
+
+Name
+====
+
+.. kernel-doc:: drivers/tty/tty_io.c
+ :identifiers: tty_name
+
+Reference counting
+==================
+
+.. kernel-doc:: include/linux/tty.h
+ :identifiers: tty_kref_get
+
+.. kernel-doc:: drivers/tty/tty_io.c
+ :identifiers: tty_kref_put
+
+Install
+=======
+
+.. kernel-doc:: drivers/tty/tty_io.c
+ :identifiers: tty_standard_install
+
+Read & Write
+============
+
+.. kernel-doc:: drivers/tty/tty_io.c
+ :identifiers: tty_put_char
+
+Start & Stop
+============
+
+.. kernel-doc:: drivers/tty/tty_io.c
+ :identifiers: start_tty stop_tty
+
+Wakeup
+======
+
+.. kernel-doc:: drivers/tty/tty_io.c
+ :identifiers: tty_wakeup
+
+Hangup
+======
+
+.. kernel-doc:: drivers/tty/tty_io.c
+ :identifiers: tty_hangup tty_vhangup tty_hung_up_p
+
+Misc
+====
+
+.. kernel-doc:: drivers/tty/tty_io.c
+ :identifiers: tty_do_resize
+
+TTY Struct Flags
+================
+
+.. kernel-doc:: include/linux/tty.h
+ :doc: TTY Struct Flags
+
+TTY Struct Reference
+====================
+
+.. kernel-doc:: include/linux/tty.h
+ :identifiers: tty_struct
diff --git a/Documentation/driver-api/usb/writing_usb_driver.rst b/Documentation/driver-api/usb/writing_usb_driver.rst
index b43e1ce49f0e..95c4f5d14052 100644
--- a/Documentation/driver-api/usb/writing_usb_driver.rst
+++ b/Documentation/driver-api/usb/writing_usb_driver.rst
@@ -94,8 +94,8 @@ usually in the driver's init function, as shown here::
/* register this driver with the USB subsystem */
result = usb_register(&skel_driver);
if (result < 0) {
- err("usb_register failed for the "__FILE__ "driver."
- "Error number %d", result);
+ pr_err("usb_register failed for the %s driver. Error number %d\n",
+ skel_driver.name, result);
return -1;
}
@@ -170,8 +170,8 @@ structure. This is done so that future calls to file operations will
enable the driver to determine which device the user is addressing. All
of this is done with the following code::
- /* increment our usage count for the module */
- ++skel->open_count;
+ /* increment our usage count for the device */
+ kref_get(&dev->kref);
/* save our object in the file's private structure */
file->private_data = dev;
@@ -188,24 +188,26 @@ space, points the urb to the data and submits the urb to the USB
subsystem. This can be seen in the following code::
/* we can only write as much as 1 urb will hold */
- bytes_written = (count > skel->bulk_out_size) ? skel->bulk_out_size : count;
+ size_t writesize = min_t(size_t, count, MAX_TRANSFER);
/* copy the data from user space into our urb */
- copy_from_user(skel->write_urb->transfer_buffer, buffer, bytes_written);
+ copy_from_user(buf, user_buffer, writesize);
/* set up our urb */
- usb_fill_bulk_urb(skel->write_urb,
- skel->dev,
- usb_sndbulkpipe(skel->dev, skel->bulk_out_endpointAddr),
- skel->write_urb->transfer_buffer,
- bytes_written,
+ usb_fill_bulk_urb(urb,
+ dev->udev,
+ usb_sndbulkpipe(dev->udev, dev->bulk_out_endpointAddr),
+ buf,
+ writesize,
skel_write_bulk_callback,
- skel);
+ dev);
/* send the data out the bulk port */
- result = usb_submit_urb(skel->write_urb);
- if (result) {
- err("Failed submitting write urb, error %d", result);
+ retval = usb_submit_urb(urb, GFP_KERNEL);
+ if (retval) {
+ dev_err(&dev->interface->dev,
+ "%s - failed submitting write urb, error %d\n",
+ __func__, retval);
}
diff --git a/Documentation/driver-api/vfio-mediated-device.rst b/Documentation/driver-api/vfio-mediated-device.rst
index 9f26079cacae..fdf7d69378ec 100644
--- a/Documentation/driver-api/vfio-mediated-device.rst
+++ b/Documentation/driver-api/vfio-mediated-device.rst
@@ -1,3 +1,4 @@
+.. SPDX-License-Identifier: GPL-2.0-only
.. include:: <isonum.txt>
=====================
@@ -8,9 +9,6 @@ VFIO Mediated devices
:Author: Neo Jia <cjia@nvidia.com>
:Author: Kirti Wankhede <kwankhede@nvidia.com>
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License version 2 as
-published by the Free Software Foundation.
Virtual Function I/O (VFIO) Mediated devices[1]
@@ -60,19 +58,19 @@ devices as examples, as these devices are the first devices to use this module::
| MDEV CORE |
| MODULE |
| mdev.ko |
- | +-----------+ | mdev_register_device() +--------------+
+ | +-----------+ | mdev_register_parent() +--------------+
| | | +<------------------------+ |
| | | | | nvidia.ko |<-> physical
| | | +------------------------>+ | device
| | | | callbacks +--------------+
| | Physical | |
- | | device | | mdev_register_device() +--------------+
+ | | device | | mdev_register_parent() +--------------+
| | interface | |<------------------------+ |
| | | | | i915.ko |<-> physical
| | | +------------------------>+ | device
| | | | callbacks +--------------+
| | | |
- | | | | mdev_register_device() +--------------+
+ | | | | mdev_register_parent() +--------------+
| | | +<------------------------+ |
| | | | | ccw_device.ko|<-> physical
| | | +------------------------>+ | device
@@ -105,6 +103,8 @@ structure to represent a mediated device's driver::
struct mdev_driver {
int (*probe) (struct mdev_device *dev);
void (*remove) (struct mdev_device *dev);
+ unsigned int (*get_available)(struct mdev_type *mtype);
+ ssize_t (*show_description)(struct mdev_type *mtype, char *buf);
struct device_driver driver;
};
@@ -113,39 +113,21 @@ to register and unregister itself with the core driver:
* Register::
- extern int mdev_register_driver(struct mdev_driver *drv);
+ int mdev_register_driver(struct mdev_driver *drv);
* Unregister::
- extern void mdev_unregister_driver(struct mdev_driver *drv);
+ void mdev_unregister_driver(struct mdev_driver *drv);
-The mediated bus driver is responsible for adding mediated devices to the VFIO
-group when devices are bound to the driver and removing mediated devices from
-the VFIO when devices are unbound from the driver.
-
-
-Physical Device Driver Interface
---------------------------------
-
-The physical device driver interface provides the mdev_parent_ops[3] structure
-to define the APIs to manage work in the mediated core driver that is related
-to the physical device.
-
-The structures in the mdev_parent_ops structure are as follows:
-
-* dev_attr_groups: attributes of the parent device
-* mdev_attr_groups: attributes of the mediated device
-* supported_config: attributes to define supported configurations
-* device_driver: device driver to bind for mediated device instances
-
-The mdev_parent_ops also still has various functions pointers. Theses exist
-for historical reasons only and shall not be used for new drivers.
+The mediated bus driver's probe function should create a vfio_device on top of
+the mdev_device and connect it to an appropriate implementation of
+vfio_device_ops.
When a driver wants to add the GUID creation sysfs to an existing device it has
probe'd to then it should call::
- extern int mdev_register_device(struct device *dev,
- const struct mdev_parent_ops *ops);
+ int mdev_register_parent(struct mdev_parent *parent, struct device *dev,
+ struct mdev_driver *mdev_driver);
This will provide the 'mdev_supported_types/XX/create' files which can then be
used to trigger the creation of a mdev_device. The created mdev_device will be
@@ -153,7 +135,7 @@ attached to the specified driver.
When the driver needs to remove itself it calls::
- extern void mdev_unregister_device(struct device *dev);
+ void mdev_unregister_parent(struct mdev_parent *parent);
Which will unbind and destroy all the created mdevs and remove the sysfs files.
@@ -219,17 +201,14 @@ Directories and files under the sysfs for Each Physical Device
sprintf(buf, "%s-%s", dev_driver_string(parent->dev), group->name);
- (or using mdev_parent_dev(mdev) to arrive at the parent device outside
- of the core mdev code)
-
* device_api
- This attribute should show which device API is being created, for example,
+ This attribute shows which device API is being created, for example,
"vfio-pci" for a PCI device.
* available_instances
- This attribute should show the number of devices of type <type-id> that can be
+ This attribute shows the number of devices of type <type-id> that can be
created.
* [device]
@@ -239,11 +218,11 @@ Directories and files under the sysfs for Each Physical Device
* name
- This attribute should show human readable name. This is optional attribute.
+ This attribute shows a human readable name.
* description
- This attribute should show brief features/description of the type. This is
+ This attribute can show brief features/description of the type. This is an
optional attribute.
Directories and Files Under the sysfs for Each mdev Device
@@ -279,10 +258,10 @@ Translation APIs for Mediated Devices
The following APIs are provided for translating user pfn to host pfn in a VFIO
driver::
- extern int vfio_pin_pages(struct device *dev, unsigned long *user_pfn,
- int npage, int prot, unsigned long *phys_pfn);
+ int vfio_pin_pages(struct vfio_device *device, dma_addr_t iova,
+ int npage, int prot, struct page **pages);
- extern int vfio_unpin_pages(struct device *dev, unsigned long *user_pfn,
+ void vfio_unpin_pages(struct vfio_device *device, dma_addr_t iova,
int npage);
These functions call back into the back-end IOMMU module by using the pin_pages
diff --git a/Documentation/driver-api/vfio-pci-device-specific-driver-acceptance.rst b/Documentation/driver-api/vfio-pci-device-specific-driver-acceptance.rst
new file mode 100644
index 000000000000..b7b99b876b50
--- /dev/null
+++ b/Documentation/driver-api/vfio-pci-device-specific-driver-acceptance.rst
@@ -0,0 +1,35 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+Acceptance criteria for vfio-pci device specific driver variants
+================================================================
+
+Overview
+--------
+The vfio-pci driver exists as a device agnostic driver using the
+system IOMMU and relying on the robustness of platform fault
+handling to provide isolated device access to userspace. While the
+vfio-pci driver does include some device specific support, further
+extensions for yet more advanced device specific features are not
+sustainable. The vfio-pci driver has therefore split out
+vfio-pci-core as a library that may be reused to implement features
+requiring device specific knowledge, ex. saving and loading device
+state for the purposes of supporting migration.
+
+In support of such features, it's expected that some device specific
+variants may interact with parent devices (ex. SR-IOV PF in support of
+a user assigned VF) or other extensions that may not be otherwise
+accessible via the vfio-pci base driver. Authors of such drivers
+should be diligent not to create exploitable interfaces via these
+interactions or allow unchecked userspace data to have an effect
+beyond the scope of the assigned device.
+
+New driver submissions are therefore requested to have approval via
+sign-off/ack/review/etc for any interactions with parent drivers.
+Additionally, drivers should make an attempt to provide sufficient
+documentation for reviewers to understand the device specific
+extensions, for example in the case of migration data, how is the
+device state composed and consumed, which portions are not otherwise
+available to the user via vfio-pci, what safeguards exist to validate
+the data, etc. To that extent, authors should additionally expect to
+require reviews from at least one of the listed reviewers, in addition
+to the overall vfio maintainer.
diff --git a/Documentation/driver-api/vme.rst b/Documentation/driver-api/vme.rst
index def139c13410..c0b475369de0 100644
--- a/Documentation/driver-api/vme.rst
+++ b/Documentation/driver-api/vme.rst
@@ -290,8 +290,8 @@ The function :c:func:`vme_bus_num` returns the bus ID of the provided bridge.
VME API
-------
-.. kernel-doc:: include/linux/vme.h
+.. kernel-doc:: drivers/staging/vme_user/vme.h
:internal:
-.. kernel-doc:: drivers/vme/vme.c
+.. kernel-doc:: drivers/staging/vme_user/vme.c
:export: