Firmware cache¶
When Linux resumes from suspend some device drivers require firmware lookups tore-initialize devices. During resume there may be a period of time during whichfirmware lookups are not possible, during this short period of time firmwarerequests will fail. Time is of essence though, and delaying drivers to wait forthe root filesystem for firmware delays user experience with devicefunctionality. In order to support these requirements the firmwareinfrastructure implements a firmware cache for device drivers for most APIcalls, automatically behind the scenes.
The firmware cache makes using certain firmware API calls safe during a devicedriver’s suspend and resume callback. Users of these API calls needn’t cachethe firmware by themselves for dealing with firmware loss during system resume.
The firmware cache works by requesting for firmware prior to suspend andcaching it in memory. Upon resume device drivers using the firmware API willhave access to the firmware immediately, without having to wait for the rootfilesystem to mount or dealing with possible race issues with lookups as theroot filesystem mounts.
Some implementation details about the firmware cache setup:
The firmware cache is setup by adding a devres entry for each device thatuses all synchronous call except
request_firmware_into_buf().If an asynchronous call is used the firmware cache is only set up for adevice if the second argument (uevent) to
request_firmware_nowait()istrue. When uevent is true it requests that a kobject uevent be sent touserspace for the firmware request through the sysfs fallback mechanismif the firmware file is not found.If the firmware cache is determined to be needed as per the above twocriteria the firmware cache is setup by adding a devres entry for thedevice making the firmware request.
The firmware devres entry is maintained throughout the lifetime of thedevice. This means that even if you
release_firmware()the firmware cachewill still be used on resume from suspend.The timeout for the fallback mechanism is temporarily reduced to 10 secondsas the firmware cache is set up during suspend, the timeout is set back tothe old value you had configured after the cache is set up.
Upon suspend any pending non-uevent firmware requests are killed to avoidstalling the kernel, this is done with
kill_requests_without_uevent(). Kernelcalls requiring the non-uevent therefore need to implement their own firmwarecache mechanism but must not use the firmware API on suspend.