Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: Lucas Stach <l.stach@pengutronix.de>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Reviewed-by: Luis Chamberlain <mcgrof@kernel.org>
Link: https://lore.kernel.org/r/20240516102532.213874-1-l.stach@pengutronix.de
Signed-off-by: Vinod Koul <vkoul@kernel.org>

authored by

Lucas Stach and committed by
Vinod Koul
11c63e57 45a24e40

+83 -35
+71 -35
drivers/base/firmware_loader/main.c
··· 1172 1172 kfree(fw_work); 1173 1173 } 1174 1174 1175 + 1176 + static int _request_firmware_nowait( 1177 + struct module *module, bool uevent, 1178 + const char *name, struct device *device, gfp_t gfp, void *context, 1179 + void (*cont)(const struct firmware *fw, void *context), bool nowarn) 1180 + { 1181 + struct firmware_work *fw_work; 1182 + 1183 + fw_work = kzalloc(sizeof(struct firmware_work), gfp); 1184 + if (!fw_work) 1185 + return -ENOMEM; 1186 + 1187 + fw_work->module = module; 1188 + fw_work->name = kstrdup_const(name, gfp); 1189 + if (!fw_work->name) { 1190 + kfree(fw_work); 1191 + return -ENOMEM; 1192 + } 1193 + fw_work->device = device; 1194 + fw_work->context = context; 1195 + fw_work->cont = cont; 1196 + fw_work->opt_flags = FW_OPT_NOWAIT | 1197 + (uevent ? FW_OPT_UEVENT : FW_OPT_USERHELPER) | 1198 + (nowarn ? FW_OPT_NO_WARN : 0); 1199 + 1200 + if (!uevent && fw_cache_is_setup(device, name)) { 1201 + kfree_const(fw_work->name); 1202 + kfree(fw_work); 1203 + return -EOPNOTSUPP; 1204 + } 1205 + 1206 + if (!try_module_get(module)) { 1207 + kfree_const(fw_work->name); 1208 + kfree(fw_work); 1209 + return -EFAULT; 1210 + } 1211 + 1212 + get_device(fw_work->device); 1213 + INIT_WORK(&fw_work->work, request_firmware_work_func); 1214 + schedule_work(&fw_work->work); 1215 + return 0; 1216 + } 1217 + 1175 1218 /** 1176 1219 * request_firmware_nowait() - asynchronous version of request_firmware 1177 1220 * @module: module requesting the firmware ··· 1238 1195 * 1239 1196 * - can't sleep at all if @gfp is GFP_ATOMIC. 1240 1197 **/ 1241 - int 1242 - request_firmware_nowait( 1198 + int request_firmware_nowait( 1243 1199 struct module *module, bool uevent, 1244 1200 const char *name, struct device *device, gfp_t gfp, void *context, 1245 1201 void (*cont)(const struct firmware *fw, void *context)) 1246 1202 { 1247 - struct firmware_work *fw_work; 1203 + return _request_firmware_nowait(module, uevent, name, device, gfp, 1204 + context, cont, false); 1248 1205 1249 - fw_work = kzalloc(sizeof(struct firmware_work), gfp); 1250 - if (!fw_work) 1251 - return -ENOMEM; 1252 - 1253 - fw_work->module = module; 1254 - fw_work->name = kstrdup_const(name, gfp); 1255 - if (!fw_work->name) { 1256 - kfree(fw_work); 1257 - return -ENOMEM; 1258 - } 1259 - fw_work->device = device; 1260 - fw_work->context = context; 1261 - fw_work->cont = cont; 1262 - fw_work->opt_flags = FW_OPT_NOWAIT | 1263 - (uevent ? FW_OPT_UEVENT : FW_OPT_USERHELPER); 1264 - 1265 - if (!uevent && fw_cache_is_setup(device, name)) { 1266 - kfree_const(fw_work->name); 1267 - kfree(fw_work); 1268 - return -EOPNOTSUPP; 1269 - } 1270 - 1271 - if (!try_module_get(module)) { 1272 - kfree_const(fw_work->name); 1273 - kfree(fw_work); 1274 - return -EFAULT; 1275 - } 1276 - 1277 - get_device(fw_work->device); 1278 - INIT_WORK(&fw_work->work, request_firmware_work_func); 1279 - schedule_work(&fw_work->work); 1280 - return 0; 1281 1206 } 1282 1207 EXPORT_SYMBOL(request_firmware_nowait); 1208 + 1209 + /** 1210 + * firmware_request_nowait_nowarn() - async version of request_firmware_nowarn 1211 + * @module: module requesting the firmware 1212 + * @name: name of firmware file 1213 + * @device: device for which firmware is being loaded 1214 + * @gfp: allocation flags 1215 + * @context: will be passed over to @cont, and 1216 + * @fw may be %NULL if firmware request fails. 1217 + * @cont: function will be called asynchronously when the firmware 1218 + * request is over. 1219 + * 1220 + * Similar in function to request_firmware_nowait(), but doesn't print a warning 1221 + * when the firmware file could not be found and always sends a uevent to copy 1222 + * the firmware image. 1223 + */ 1224 + int firmware_request_nowait_nowarn( 1225 + struct module *module, const char *name, 1226 + struct device *device, gfp_t gfp, void *context, 1227 + void (*cont)(const struct firmware *fw, void *context)) 1228 + { 1229 + return _request_firmware_nowait(module, FW_ACTION_UEVENT, name, device, 1230 + gfp, context, cont, true); 1231 + } 1232 + EXPORT_SYMBOL_GPL(firmware_request_nowait_nowarn); 1283 1233 1284 1234 #ifdef CONFIG_FW_CACHE 1285 1235 static ASYNC_DOMAIN_EXCLUSIVE(fw_cache_domain);
+12
include/linux/firmware.h
··· 98 98 #if IS_REACHABLE(CONFIG_FW_LOADER) 99 99 int request_firmware(const struct firmware **fw, const char *name, 100 100 struct device *device); 101 + int firmware_request_nowait_nowarn( 102 + struct module *module, const char *name, 103 + struct device *device, gfp_t gfp, void *context, 104 + void (*cont)(const struct firmware *fw, void *context)); 101 105 int firmware_request_nowarn(const struct firmware **fw, const char *name, 102 106 struct device *device); 103 107 int firmware_request_platform(const struct firmware **fw, const char *name, ··· 123 119 static inline int request_firmware(const struct firmware **fw, 124 120 const char *name, 125 121 struct device *device) 122 + { 123 + return -EINVAL; 124 + } 125 + 126 + static inline int firmware_request_nowait_nowarn( 127 + struct module *module, const char *name, 128 + struct device *device, gfp_t gfp, void *context, 129 + void (*cont)(const struct firmware *fw, void *context)) 126 130 { 127 131 return -EINVAL; 128 132 }