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

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.de


Signed-off-by: default avatarVinod Koul <vkoul@kernel.org>
parent 45a24e40
Loading
Loading
Loading
Loading
+63 −27
Original line number Diff line number Diff line
@@ -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);

+12 −0
Original line number Diff line number Diff line
@@ -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)