@@ -341,7 +341,6 @@ int sof_widget_list_setup(struct snd_sof_dev *sdev, struct snd_sof_pcm *spcm, in
341341{
342342 struct snd_soc_dapm_widget_list * list = spcm -> stream [dir ].list ;
343343 struct snd_soc_dapm_widget * widget ;
344- int num_pipe_widgets = 0 ;
345344 int i , ret , num_widgets ;
346345
347346 /* nothing to set up */
@@ -351,13 +350,36 @@ int sof_widget_list_setup(struct snd_sof_dev *sdev, struct snd_sof_pcm *spcm, in
351350 /* set up widgets in the list */
352351 for_each_dapm_widgets (list , num_widgets , widget ) {
353352 struct snd_sof_widget * swidget = widget -> dobj .private ;
353+ struct snd_sof_widget * pipe_widget ;
354354
355355 if (!swidget )
356356 continue ;
357357
358- ret = sof_widget_setup (sdev , swidget );
358+ /*
359+ * The scheduler widget for a pipeline is not part of the connected DAPM
360+ * widget list and it needs to be set up before the widgets in the pipeline
361+ * are set up. The use_count for the scheduler widget is incremented for every
362+ * widget in a given pipeline to ensure that it is freed only after the last
363+ * widget in the pipeline is freed.
364+ */
365+ pipe_widget = swidget -> pipe_widget ;
366+ if (!pipe_widget ) {
367+ dev_err (sdev -> dev , "error: no pipeline widget found for %s\n" ,
368+ swidget -> widget -> name );
369+ ret = - EINVAL ;
370+ goto widget_free ;
371+ }
372+
373+ ret = sof_widget_setup (sdev , pipe_widget );
359374 if (ret < 0 )
360375 goto widget_free ;
376+
377+ /* set up the widget */
378+ ret = sof_widget_setup (sdev , swidget );
379+ if (ret < 0 ) {
380+ sof_widget_free (sdev , pipe_widget );
381+ goto widget_free ;
382+ }
361383 }
362384
363385 /*
@@ -368,7 +390,7 @@ int sof_widget_list_setup(struct snd_sof_dev *sdev, struct snd_sof_pcm *spcm, in
368390 if (ret < 0 )
369391 goto widget_free ;
370392
371- /* setup pipeline widgets and complete pipelines */
393+ /* complete pipelines */
372394 for_each_dapm_widgets (list , i , widget ) {
373395 struct snd_sof_widget * swidget = widget -> dobj .private ;
374396 struct snd_sof_widget * pipe_widget ;
@@ -381,49 +403,34 @@ int sof_widget_list_setup(struct snd_sof_dev *sdev, struct snd_sof_pcm *spcm, in
381403 dev_err (sdev -> dev , "error: no pipeline widget found for %s\n" ,
382404 swidget -> widget -> name );
383405 ret = - EINVAL ;
384- goto pipe_free ;
406+ goto widget_free ;
385407 }
386408
387- ret = sof_widget_setup (sdev , pipe_widget );
388- if (ret < 0 )
389- goto pipe_free ;
390-
391- num_pipe_widgets ++ ;
392-
393409 if (pipe_widget -> complete )
394410 continue ;
395411
396412 pipe_widget -> complete = snd_sof_complete_pipeline (sdev -> dev , pipe_widget );
397413 if (pipe_widget -> complete < 0 ) {
398414 ret = pipe_widget -> complete ;
399- goto pipe_free ;
415+ goto widget_free ;
400416 }
401417 }
402418
403419 return 0 ;
404420
405- pipe_free :
406- /* free the pipe widgets that were set up successfully */
421+ widget_free :
422+ /* free all widgets that have been set up successfully */
407423 for_each_dapm_widgets (list , i , widget ) {
408424 struct snd_sof_widget * swidget = widget -> dobj .private ;
409425
410426 if (!swidget )
411427 continue ;
412428
413- if (!num_pipe_widgets -- )
414- break ;
415-
416- sof_widget_free (sdev , swidget -> pipe_widget );
417- }
418-
419- widget_free :
420- /* free all widgets that have been set up successfully */
421- for_each_dapm_widgets (list , i , widget ) {
422429 if (!num_widgets -- )
423430 break ;
424431
425- if ( widget -> dobj . private )
426- sof_widget_free (sdev , widget -> dobj . private );
432+ sof_widget_free ( sdev , swidget );
433+ sof_widget_free (sdev , swidget -> pipe_widget );
427434 }
428435
429436 return ret ;
0 commit comments