@@ -178,21 +178,14 @@ 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
190- if (!sdev -> pdata -> fw_lib_prefix ) {
191- dev_err (sdev -> dev ,
192- "Library loading is not supported due to not set library path\n" );
193- return - EINVAL ;
194- }
195-
196189 if (!ipc4_data -> load_library ) {
197190 dev_err (sdev -> dev , "Library loading is not supported on this platform\n" );
198191 return - EOPNOTSUPP ;
@@ -202,21 +195,28 @@ static int sof_ipc4_load_library_by_uuid(struct snd_sof_dev *sdev,
202195 if (!fw_lib )
203196 return - ENOMEM ;
204197
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 ;
198+ if (optional ) {
199+ ret = firmware_request_nowarn (& fw_lib -> sof_fw .fw , lib_filename ,
200+ sdev -> dev );
201+ if (ret < 0 ) {
202+ dev_dbg (sdev -> dev , "Library file '%s' is not present\n" ,
203+ lib_filename );
204+ /* optional library, override the error */
205+ ret = 0 ;
206+ goto free_fw_lib ;
207+ }
216208 } else {
217- dev_dbg (sdev -> dev , "Library file '%s' loaded\n" , fw_filename );
209+ ret = request_firmware (& fw_lib -> sof_fw .fw , lib_filename ,
210+ sdev -> dev );
211+ if (ret < 0 ) {
212+ dev_err (sdev -> dev , "Library file '%s' is missing\n" ,
213+ lib_filename );
214+ goto free_fw_lib ;
215+ }
218216 }
219217
218+ dev_dbg (sdev -> dev , "Library file '%s' loaded\n" , lib_filename );
219+
220220 payload_offset = sof_ipc4_fw_parse_ext_man (sdev , fw_lib );
221221 if (payload_offset <= 0 ) {
222222 if (!payload_offset )
@@ -228,11 +228,11 @@ static int sof_ipc4_load_library_by_uuid(struct snd_sof_dev *sdev,
228228 }
229229
230230 fw_lib -> sof_fw .payload_offset = payload_offset ;
231- fw_lib -> id = lib_id ;
231+ fw_lib -> id = * lib_id ;
232232
233233 /* Fix up the module ID numbers within the library */
234234 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 );
235+ fw_lib -> modules [i ].man4_module_entry .id |= (* lib_id << SOF_IPC4_MOD_LIB_ID_SHIFT );
236236
237237 /*
238238 * Make sure that the DSP is booted and stays up while attempting the
@@ -256,26 +256,86 @@ static int sof_ipc4_load_library_by_uuid(struct snd_sof_dev *sdev,
256256 if (ret )
257257 goto release ;
258258
259- ret = xa_insert (& ipc4_data -> fw_lib_xa , lib_id , fw_lib , GFP_KERNEL );
259+ ret = xa_insert (& ipc4_data -> fw_lib_xa , * lib_id , fw_lib , GFP_KERNEL );
260260 if (unlikely (ret ))
261261 goto release ;
262262
263- kfree (fw_filename );
264-
263+ (* lib_id )++ ;
265264 return 0 ;
266265
267266release :
268267 release_firmware (fw_lib -> sof_fw .fw );
269268 /* Allocated within sof_ipc4_fw_parse_ext_man() */
270269 devm_kfree (sdev -> dev , fw_lib -> modules );
271- free_filename :
272- kfree (fw_filename );
273270free_fw_lib :
274271 devm_kfree (sdev -> dev , fw_lib );
275272
276273 return ret ;
277274}
278275
276+ int sof_ipc4_load_library_bundles (struct snd_sof_dev * sdev )
277+ {
278+ static const char * const lib_bundle [] = { "openmodules" , "debug" };
279+ const char * fw_filename = sdev -> pdata -> fw_filename ;
280+ const char * lib_filename , * p ;
281+ unsigned long lib_id = 1 ;
282+ char * lib_name_base ;
283+ int ret , i ;
284+
285+ p = strstr (fw_filename , ".ri" );
286+ if (!p || strlen (p ) != 3 ) {
287+ dev_info (sdev -> dev ,
288+ "%s: Cannot parse firmware name '%s', missing .ri extension\n" ,
289+ __func__ , fw_filename );
290+ return 0 ;
291+ }
292+
293+ lib_name_base = kzalloc (strlen (fw_filename ) - 2 , GFP_KERNEL );
294+ strscpy (lib_name_base , fw_filename , sizeof (lib_name_base ));
295+
296+ for (i = 0 ; i < ARRAY_SIZE (lib_bundle ); i ++ ) {
297+ lib_filename = kasprintf (GFP_KERNEL , "%s/%s-%s.ri" ,
298+ sdev -> pdata -> fw_filename_prefix ,
299+ lib_name_base , lib_bundle [i ]);
300+ if (!lib_filename )
301+ return - ENOMEM ;
302+
303+ ret = sof_ipc4_load_library (sdev , & lib_id , lib_filename , true);
304+
305+ kfree (lib_filename );
306+ if (ret )
307+ break ;
308+ }
309+
310+ kfree (lib_name_base );
311+
312+ return ret ;
313+ }
314+
315+ static int sof_ipc4_load_library_by_uuid (struct snd_sof_dev * sdev ,
316+ unsigned long lib_id , const guid_t * uuid )
317+ {
318+ const char * lib_filename ;
319+ int ret ;
320+
321+ if (!sdev -> pdata -> fw_lib_prefix ) {
322+ dev_err (sdev -> dev ,
323+ "Library loading is not supported due to not set library path\n" );
324+ return - EINVAL ;
325+ }
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