[PATCH v7 4/5] firmware: document the extensible driver data API

From: Luis R. Rodriguez
Date: Tue May 02 2017 - 04:50:02 EST

This documents the driver data API.

Signed-off-by: Luis R. Rodriguez <mcgrof@xxxxxxxxxx>
Documentation/driver-api/firmware/driver_data.rst | 167 +++++++++++++++++++++
Documentation/driver-api/firmware/index.rst | 1 +
Documentation/driver-api/firmware/introduction.rst | 16 ++
.../driver-api/firmware/request_firmware.rst | 2 +
4 files changed, 186 insertions(+)
create mode 100644 Documentation/driver-api/firmware/driver_data.rst

diff --git a/Documentation/driver-api/firmware/driver_data.rst b/Documentation/driver-api/firmware/driver_data.rst
new file mode 100644
index 000000000000..be7c7ff99151
--- /dev/null
+++ b/Documentation/driver-api/firmware/driver_data.rst
@@ -0,0 +1,167 @@
+.. _driver_data:
+driver_data API
+The driver data APIs provides a flexible API for general driver data file
+lookups. Its flexibility aims at mitigating collateral evolutions on the kernel
+as new functionality is introduced.
+Driver data modes of operation
+There are two types of modes of operation for driver data requests:
+ * synchronous - driver_data_request_sync()
+ * asynchronous - driver_data_request_async()
+Synchronous requests expect requests to be done immediately, asynchronous
+requests enable requests to be scheduled for a later time.
+Driver data request parameters
+Variations of types of driver data requests are specified by a driver data
+request parameter data structure. The flexibility of the API is provided by
+expanding the request parameters as new functionality is needed, without
+loosely modifying or adding new exported APIs.
+.. kernel-doc:: include/linux/driver_data.h
+ :functions: driver_data_sync_cbs
+.. kernel-doc:: include/linux/driver_data.h
+ :functions: driver_data_async_cbs
+.. kernel-doc:: include/linux/driver_data.h
+ :functions: driver_data_cbs
+.. kernel-doc:: include/linux/driver_data.h
+ :functions: driver_data_reqs
+.. kernel-doc:: include/linux/driver_data.h
+ :functions: driver_data_req_params
+Synchronous driver data requests
+Synchronous driver data requests will wait until the driver data is found or
+until an error is returned.
+.. kernel-doc:: drivers/base/firmware_class.c
+ :functions: driver_data_request_sync
+Asynchronous driver data requests
+Asynchronous driver data requests allow driver code to not have to wait
+until the driver data or an error is returned. Function callbacks are
+required so that when the firmware or an error is found the driver is
+informed through the callbacks. Asynchronous driver data requests cannot
+be called from atomic contexts.
+.. kernel-doc:: drivers/base/firmware_class.c
+ :functions: driver_data_request_async
+Reference counting and releasing the driver data file
+The device and module are bumped with reference counts during the driver data
+requests. This prevents removal of the device and module making the driver data
+request call until the driver data request callbacks have completed, either
+synchronously or asynchronously. When synchronous requests are made the
+firmware_class is refcounted. When asynchronous requests are made the caller's
+module is refcounted. Asynchronous requests do not refcount the firmware_class
+The driver data request API enables callers to provide a callback for both
+synchronous and asynchronous requests and since consumption can be expected
+in these callbacks it frees it for you by default after callback handlers
+are issued. If you wish to keep the driver data around after your callbacks
+you must specify this through the driver data request parameter data structure.
+Driver data private internal functionality
+This section documents functionality not exposed to users, but important in
+understanding how the driver data internals work.
+.. kernel-doc:: drivers/base/firmware_class.c
+ :functions: driver_data_mode
+.. kernel-doc:: drivers/base/firmware_class.c
+ :functions: driver_data_priv_reqs
+.. kernel-doc:: drivers/base/firmware_class.c
+ :functions: driver_data_priv_params
+.. kernel-doc:: drivers/base/firmware_class.c
+ :functions: driver_data_params
+Testing the driver_data API
+The driver data API has a selftest driver: lib/test_driver_data.c. The
+test_driver_data enables you to build your tests in userspace by exposing knobs
+of the exported API in userspace and enabling userspace to configure and
+trigger a kernel call. This lets us build most possible test cases of
+the kernel APIs from userspace.
+The test_driver_data also enables multiple test triggers to be created
+enabling testing to be done in parallel, one test interface per test case.
+To test an async call one could do::
+ echo anything > /lib/firmware/test-driver_data.bin
+ echo -n 1 > /sys/devices/virtual/misc/test_driver_data0/config_async
+ echo -n 1 > /sys/devices/virtual/misc/test_driver_data0/trigger_config
+A series of tests have been written to test the driver data API thoroughly.
+A respective test case is expected to bet written as new features get added.
+For details of existing tests run::
+ tools/testing/selftests/firmware/driver_data.sh -l
+To see all available options::
+ tools/testing/selftests/firmware/driver_data.sh --help
+To run a test 0010 case 40 times::
+ tools/testing/selftests/firmware/driver_data.sh -c 0010 40
+Note that driver_data.sh uses its own temporary custom path for creating and
+looking for driver data files, it does this to not overwrite any production
+files you might have which may share the same names used by the test shell
+script driver_data.sh. If you are not using the driver_data.sh script your
+default path will be used.
+Tracking development enhancements and ideas
+To help track ongoing development for firmware_class and related items to
+firmware_class refer to the kernel newbies wiki page [0].
+[0] http://kernelnewbies.org/KernelProjects/firmware-class-enhancements
diff --git a/Documentation/driver-api/firmware/index.rst b/Documentation/driver-api/firmware/index.rst
index 29da39ec4b8a..70a3dea0c5de 100644
--- a/Documentation/driver-api/firmware/index.rst
+++ b/Documentation/driver-api/firmware/index.rst
@@ -8,6 +8,7 @@ Linux Firmware API
+ driver_data

.. only:: subproject and html

diff --git a/Documentation/driver-api/firmware/introduction.rst b/Documentation/driver-api/firmware/introduction.rst
index 211cb44eb972..c1173bac0dbb 100644
--- a/Documentation/driver-api/firmware/introduction.rst
+++ b/Documentation/driver-api/firmware/introduction.rst
@@ -25,3 +25,19 @@ are already using asynchronous initialization mechanisms which will not
stall or delay boot. Even if loading firmware does not take a lot of time
processing firmware might, and this can still delay boot or initialization,
as such mechanisms such as asynchronous probe can help supplement drivers.
+Two APIs
+Two APIs are provided for firmware:
+* Old firmware API - :ref:`request_firmware`
+* Flexible driver data API - :ref:`driver_data`
+We have historically extended the firmware API by adding new routines or at
+times extending existing routines with more or less arguments. This doesn't
+scale well, when new arguments are added to existing routines it means we need
+to traverse the kernel with a slew of collateral evolutions to adjust old
+driver users. The driver data API is an extensible API enabling extensions to
+be added by avoiding unnecessary collateral evolutions as features get added.
+New features and development should be added through the driver_data API.
diff --git a/Documentation/driver-api/firmware/request_firmware.rst b/Documentation/driver-api/firmware/request_firmware.rst
index 1c2c4967cd43..b31938244b7f 100644
--- a/Documentation/driver-api/firmware/request_firmware.rst
+++ b/Documentation/driver-api/firmware/request_firmware.rst
@@ -1,3 +1,5 @@
+.. _request_firmware:
request_firmware API