@@ -178,12 +178,11 @@ static size_t sof_ipc4_fw_parse_basefw_ext_man(struct snd_sof_dev *sdev)
178178 return payload_offset ;
179179}
180180
181- static int sof_ipc4_load_library_by_uuid (struct snd_sof_dev * sdev ,
182- unsigned long lib_id , const guid_t * uuid )
181+ static int sof_ipc4_load_library (struct snd_sof_dev * sdev , unsigned long * lib_id ,
182+ const char * lib_filename , bool optional )
183183{
184184 struct sof_ipc4_fw_data * ipc4_data = sdev -> private ;
185185 struct sof_ipc4_fw_library * fw_lib ;
186- const char * fw_filename ;
187186 ssize_t payload_offset ;
188187 int ret , i , err ;
189188
@@ -202,21 +201,28 @@ static int sof_ipc4_load_library_by_uuid(struct snd_sof_dev *sdev,
202201 if (!fw_lib )
203202 return - ENOMEM ;
204203
205- fw_filename = kasprintf (GFP_KERNEL , "%s/%pUL.bin" ,
206- sdev -> pdata -> fw_lib_prefix , uuid );
207- if (!fw_filename ) {
208- ret = - ENOMEM ;
209- goto free_fw_lib ;
210- }
211-
212- ret = request_firmware (& fw_lib -> sof_fw .fw , fw_filename , sdev -> dev );
213- if (ret < 0 ) {
214- dev_err (sdev -> dev , "Library file '%s' is missing\n" , fw_filename );
215- goto free_filename ;
204+ if (optional ) {
205+ ret = firmware_request_nowarn (& fw_lib -> sof_fw .fw , lib_filename ,
206+ sdev -> dev );
207+ if (ret < 0 ) {
208+ dev_dbg (sdev -> dev , "Library file '%s' is not present\n" ,
209+ lib_filename );
210+ /* optional library, override the error */
211+ ret = 0 ;
212+ goto free_fw_lib ;
213+ }
216214 } else {
217- dev_dbg (sdev -> dev , "Library file '%s' loaded\n" , fw_filename );
215+ ret = request_firmware (& fw_lib -> sof_fw .fw , lib_filename ,
216+ sdev -> dev );
217+ if (ret < 0 ) {
218+ dev_err (sdev -> dev , "Library file '%s' is missing\n" ,
219+ lib_filename );
220+ goto free_fw_lib ;
221+ }
218222 }
219223
224+ dev_dbg (sdev -> dev , "Library file '%s' loaded\n" , lib_filename );
225+
220226 payload_offset = sof_ipc4_fw_parse_ext_man (sdev , fw_lib );
221227 if (payload_offset <= 0 ) {
222228 if (!payload_offset )
@@ -228,11 +234,11 @@ static int sof_ipc4_load_library_by_uuid(struct snd_sof_dev *sdev,
228234 }
229235
230236 fw_lib -> sof_fw .payload_offset = payload_offset ;
231- fw_lib -> id = lib_id ;
237+ fw_lib -> id = * lib_id ;
232238
233239 /* Fix up the module ID numbers within the library */
234240 for (i = 0 ; i < fw_lib -> num_modules ; i ++ )
235- fw_lib -> modules [i ].man4_module_entry .id |= (lib_id << SOF_IPC4_MOD_LIB_ID_SHIFT );
241+ fw_lib -> modules [i ].man4_module_entry .id |= (* lib_id << SOF_IPC4_MOD_LIB_ID_SHIFT );
236242
237243 /*
238244 * Make sure that the DSP is booted and stays up while attempting the
@@ -256,26 +262,80 @@ static int sof_ipc4_load_library_by_uuid(struct snd_sof_dev *sdev,
256262 if (ret )
257263 goto release ;
258264
259- ret = xa_insert (& ipc4_data -> fw_lib_xa , lib_id , fw_lib , GFP_KERNEL );
265+ ret = xa_insert (& ipc4_data -> fw_lib_xa , * lib_id , fw_lib , GFP_KERNEL );
260266 if (unlikely (ret ))
261267 goto release ;
262268
263- kfree (fw_filename );
264-
269+ (* lib_id )++ ;
265270 return 0 ;
266271
267272release :
268273 release_firmware (fw_lib -> sof_fw .fw );
269274 /* Allocated within sof_ipc4_fw_parse_ext_man() */
270275 devm_kfree (sdev -> dev , fw_lib -> modules );
271- free_filename :
272- kfree (fw_filename );
273276free_fw_lib :
274277 devm_kfree (sdev -> dev , fw_lib );
275278
276279 return ret ;
277280}
278281
282+ int sof_ipc4_load_library_bundles (struct snd_sof_dev * sdev )
283+ {
284+ static const char * const lib_bundle [] = { "openmodules" , "debug" };
285+ const char * fw_filename = sdev -> pdata -> fw_filename ;
286+ const char * lib_filename , * p ;
287+ unsigned long lib_id = 1 ;
288+ char * lib_name_base ;
289+ int ret , i ;
290+
291+ p = strstr (fw_filename , ".ri" );
292+ if (!p || strlen (p ) != 3 ) {
293+ dev_info (sdev -> dev ,
294+ "%s: Cannot parse firmware name '%s', missing .ri extension\n" ,
295+ __func__ , fw_filename );
296+ return 0 ;
297+ }
298+
299+ lib_name_base = kzalloc (strlen (fw_filename ) - 2 , GFP_KERNEL );
300+ strscpy (lib_name_base , fw_filename , sizeof (lib_name_base ));
301+
302+ for (i = 0 ; i < ARRAY_SIZE (lib_bundle ); i ++ ) {
303+ lib_filename = kasprintf (GFP_KERNEL , "%s/%s-%s.ri" ,
304+ sdev -> pdata -> fw_lib_prefix ,
305+ lib_name_base , lib_bundle [i ]);
306+ if (!lib_filename )
307+ return - ENOMEM ;
308+
309+ ret = sof_ipc4_load_library (sdev , & lib_id , lib_filename , true);
310+
311+ kfree (lib_filename );
312+ if (ret )
313+ break ;
314+ }
315+
316+ kfree (lib_name_base );
317+
318+ return ret ;
319+ }
320+
321+ static int sof_ipc4_load_library_by_uuid (struct snd_sof_dev * sdev ,
322+ unsigned long lib_id , const guid_t * uuid )
323+ {
324+ const char * lib_filename ;
325+ int ret ;
326+
327+ lib_filename = kasprintf (GFP_KERNEL , "%s/%pUL.bin" ,
328+ sdev -> pdata -> fw_lib_prefix , uuid );
329+ if (!lib_filename )
330+ return - ENOMEM ;
331+
332+ ret = sof_ipc4_load_library (sdev , & lib_id , lib_filename , false);
333+
334+ kfree (lib_filename );
335+
336+ return ret ;
337+ }
338+
279339struct sof_ipc4_fw_module * sof_ipc4_find_module_by_uuid (struct snd_sof_dev * sdev ,
280340 const guid_t * uuid )
281341{
0 commit comments