Commit 11c63e57 authored by Lucas Stach's avatar Lucas Stach Committed by Vinod Koul

firmware: add nowarn variant of request_firmware_nowait()

Device drivers with optional firmware may still want to use the
asynchronous firmware loading interface. To avoid printing a
warning into the kernel log when the optional firmware is
absent, add a nowarn variant of this interface.
Signed-off-by: default avatarLucas Stach <l.stach@pengutronix.de>
Reviewed-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Reviewed-by: default avatarLuis Chamberlain <mcgrof@kernel.org>
Link: https://lore.kernel.org/r/20240516102532.213874-1-l.stach@pengutronix.deSigned-off-by: default avatarVinod Koul <vkoul@kernel.org>
parent 45a24e40
......@@ -1172,34 +1172,11 @@ static void request_firmware_work_func(struct work_struct *work)
kfree(fw_work);
}
/**
* request_firmware_nowait() - asynchronous version of request_firmware
* @module: module requesting the firmware
* @uevent: sends uevent to copy the firmware image if this flag
* is non-zero else the firmware copy must be done manually.
* @name: name of firmware file
* @device: device for which firmware is being loaded
* @gfp: allocation flags
* @context: will be passed over to @cont, and
* @fw may be %NULL if firmware request fails.
* @cont: function will be called asynchronously when the firmware
* request is over.
*
* Caller must hold the reference count of @device.
*
* Asynchronous variant of request_firmware() for user contexts:
* - sleep for as small periods as possible since it may
* increase kernel boot time of built-in device drivers
* requesting firmware in their ->probe() methods, if
* @gfp is GFP_KERNEL.
*
* - can't sleep at all if @gfp is GFP_ATOMIC.
**/
int
request_firmware_nowait(
static int _request_firmware_nowait(
struct module *module, bool uevent,
const char *name, struct device *device, gfp_t gfp, void *context,
void (*cont)(const struct firmware *fw, void *context))
void (*cont)(const struct firmware *fw, void *context), bool nowarn)
{
struct firmware_work *fw_work;
......@@ -1217,7 +1194,8 @@ request_firmware_nowait(
fw_work->context = context;
fw_work->cont = cont;
fw_work->opt_flags = FW_OPT_NOWAIT |
(uevent ? FW_OPT_UEVENT : FW_OPT_USERHELPER);
(uevent ? FW_OPT_UEVENT : FW_OPT_USERHELPER) |
(nowarn ? FW_OPT_NO_WARN : 0);
if (!uevent && fw_cache_is_setup(device, name)) {
kfree_const(fw_work->name);
......@@ -1236,8 +1214,66 @@ request_firmware_nowait(
schedule_work(&fw_work->work);
return 0;
}
/**
* request_firmware_nowait() - asynchronous version of request_firmware
* @module: module requesting the firmware
* @uevent: sends uevent to copy the firmware image if this flag
* is non-zero else the firmware copy must be done manually.
* @name: name of firmware file
* @device: device for which firmware is being loaded
* @gfp: allocation flags
* @context: will be passed over to @cont, and
* @fw may be %NULL if firmware request fails.
* @cont: function will be called asynchronously when the firmware
* request is over.
*
* Caller must hold the reference count of @device.
*
* Asynchronous variant of request_firmware() for user contexts:
* - sleep for as small periods as possible since it may
* increase kernel boot time of built-in device drivers
* requesting firmware in their ->probe() methods, if
* @gfp is GFP_KERNEL.
*
* - can't sleep at all if @gfp is GFP_ATOMIC.
**/
int request_firmware_nowait(
struct module *module, bool uevent,
const char *name, struct device *device, gfp_t gfp, void *context,
void (*cont)(const struct firmware *fw, void *context))
{
return _request_firmware_nowait(module, uevent, name, device, gfp,
context, cont, false);
}
EXPORT_SYMBOL(request_firmware_nowait);
/**
* firmware_request_nowait_nowarn() - async version of request_firmware_nowarn
* @module: module requesting the firmware
* @name: name of firmware file
* @device: device for which firmware is being loaded
* @gfp: allocation flags
* @context: will be passed over to @cont, and
* @fw may be %NULL if firmware request fails.
* @cont: function will be called asynchronously when the firmware
* request is over.
*
* Similar in function to request_firmware_nowait(), but doesn't print a warning
* when the firmware file could not be found and always sends a uevent to copy
* the firmware image.
*/
int firmware_request_nowait_nowarn(
struct module *module, const char *name,
struct device *device, gfp_t gfp, void *context,
void (*cont)(const struct firmware *fw, void *context))
{
return _request_firmware_nowait(module, FW_ACTION_UEVENT, name, device,
gfp, context, cont, true);
}
EXPORT_SYMBOL_GPL(firmware_request_nowait_nowarn);
#ifdef CONFIG_FW_CACHE
static ASYNC_DOMAIN_EXCLUSIVE(fw_cache_domain);
......
......@@ -98,6 +98,10 @@ static inline bool firmware_request_builtin(struct firmware *fw,
#if IS_REACHABLE(CONFIG_FW_LOADER)
int request_firmware(const struct firmware **fw, const char *name,
struct device *device);
int firmware_request_nowait_nowarn(
struct module *module, const char *name,
struct device *device, gfp_t gfp, void *context,
void (*cont)(const struct firmware *fw, void *context));
int firmware_request_nowarn(const struct firmware **fw, const char *name,
struct device *device);
int firmware_request_platform(const struct firmware **fw, const char *name,
......@@ -123,6 +127,14 @@ static inline int request_firmware(const struct firmware **fw,
return -EINVAL;
}
static inline int firmware_request_nowait_nowarn(
struct module *module, const char *name,
struct device *device, gfp_t gfp, void *context,
void (*cont)(const struct firmware *fw, void *context))
{
return -EINVAL;
}
static inline int firmware_request_nowarn(const struct firmware **fw,
const char *name,
struct device *device)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment