firmware: add new extensible firmware API - driver_data

The firmware API has evolved over the years slowly, as it
grows we extend it by adding new routines or at times we extend
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 firmware API is also
now being used for things outside of the scope of what typically
would be considered "firmware", an example here is the p54 driver
enables users to provide a custom EEPROM through this interface.
Another example is optional CPU microcode updates. This list is
actually quite endless...

There are other subsystems which would like to make use of the
APIs for similar things and its clearly not firmware, but have different
requirements and criteria which they'd like to be met for the
requested file. If different requirements are needed it would
again mean adding more arguments and making a slew of collateral
evolutions, or adding yet-another-new-API-call (TM).

Another sticking point over the current firmware API is that
some callers may need the firmware fallback mechanism when its
enabled. There are two types of fallback mechanisms and both have
shortcomings. This new API accepts the current status quo and
ignore the fallback mechanism all together. When and if we add
support for it, it will be well though out.

This new extensible firmware API enables new extensions to be added by
avoiding future unnecessary collateral evolutions as this code /
features get added. This new set of APIs leaves the old firmware API
as-is, ignores all firmware fallback mechanism, labels the new
API to reflect its broad use outside of the scope of firmware: driver
data helpers, and builds on top of the original firmware core code.
We purposely try to limit the scope of changes in this new API to
simply enable a flexible API to start off with.

The new extensible "driver data" set of helpers accepts that there
really are only two types of requests for accessing driver data:

a) synchronous requests
b) asynchronous requests

Both of these requests may have a different set of requirements which
must be met. These requirements can simply be passed as a struct
drvdata_req_params to each type of request. This struct can be extended
over time to support different requirements as the kernel evolves.

Using the new driver data helpers is only necessary if you have
requirements outside of what the existing old firmware API accepts
or alternatively if you want to ensure to avoid the old firmware
fallback mechanism at all times, regardless of what kernel your driver
might run in.

Developers with new uses should extend the new new struct drvdata_req_params
and driver data code to provide support for new features.

A *few* simple features added as part of the new set of driver data
request APIs, other than making the new API easily extensible for
the future:

 - The firmware fallback mechanism is currenlty always ignored
 - By default the kernel will free the driver data file for you after
   your callbacks are called, you however are allowed to request that
   you wish to keep the driver data file on the descriptor. The new
   drvdata API is able to free the drvdata file for you by requiring a
   consumer callback for the driver data file.
 - You no longer need to declare and use your own completions, you
   can replace your completions with drvdata_synchronize_request() using
   the async_cookie set for you by drvdata_file_request_async(). When
   drvdata_file_request_async() completes you can rest assured all the
   work for both triggering, and processing the drvdata using any of
   your callbacks has completed.
 - Allow both asynchronous and synchronous request to specify that driver data
   files are optional. With the old APIs we had added one full API call,
   request_firmware_direct() just for this purpose -- although it should be
   noted another one of its goal was to also skip the fallback mechanisms.
   The driver data request APIs allow for you to annotate that a driver
   data file is optional for both synchronous or asynchronous requests
   through the same two basic set of APIs.
 - The driver data request APIs currently match the old synchronous firmware
   API calls to refcounted firmware_class module, but it should be easy
   to add support now to enable also refcounting the caller's module
   should it be be needed. Likewise the driver data request APIs match the
   old asynchronous firmware API call and refcounts the caller's module.

v6 changes:

o Bike shedding:
  o drvdata/driver_data

v5 changes:

o Bike shedding:
  o sysdata/drvdata
  o sysdata_req_desc/drvdata_req_params
o Documentation conversion to Sphinx

v4 changes:

o Add SYSDATA_KEEP_SYNC() and SYSDATA_KEEP_ASYNC() macro helpers,
  drivers that want to keep the firmware are pretty common, however
  note that if we can figure out a way to avoid having drivers
  deal with releasing the firmware we're better off, that however
  can be an additional change to look forward to.

o 0-day-bot make htmldocs warning fixes

o When developing and testing the sysdata test driver I ended up
  running into tons of hairball code just to be able to come up
  with enough code to be able to tweak all possible knobs using
  a userspace test interface. This begged for a cleaner API and
  in testing found that async_schedule_domain() made life so much
  easier. This also added the sysdata_synchronize_request() helper
  which user can use to see if their async request completed. This
  should help users considerably as well. Updated code, commit log
  and documentation to reflect these changes.

o In testing found that to make semantics stronger we should
  require @optional to true on the descriptor if an optional
  callback is to be provided (with SYSDATA_SYNC_OPT_CB() or
  SYSDATA_ASYNC_OPT_CB()). Made notes to ensure to users
  that set @optional to true but are not providing a opt_fail_cb()
  should at the very least seriously consider using the returned
  using async_cookie to sysdata_synchronize_request() to ensure
  no lingering requests are kept out of bounds.

o Updated commit log to reflect how we can compartamentalize
  usermode helper code

o Adds SYSDATA_ASYNC_OPT_CB()

o Forces @optional on SYSDATA_SYNC_OPT_CB() to true

o Ensures sysdata_file_request() and sysdata_file_request_async()
  check for emptry string (name[0] == '\0') as follow up to
  Kees's check for empty string name 471b095dfe0d6 ("firmware_class:
  make sure fw requests contain a name") and later a fix by
  Brian through 715780ae4bb76d ("firmware: actually return NULL on
  failed request_firmware_nowait()).

Signed-off-by: Luis R. Rodriguez <mcgrof@kernel.org>
6 files changed