Skip to content

Commit

Permalink
ASoC: dapm: Fix handling of loops
Browse files Browse the repository at this point in the history
Currently if a path loops back on itself we correctly skip over it to
avoid going into an infinite loop but this causes us to ignore the need
to power up the path as we don't count the loop for the purposes of
counting inputs and outputs. This means that internal loopbacks within a
device that have powered devices on them won't be powered up.

Fix this by treating any path that is currently in the process of being
recursed as having a single input or output so that it is counted for
the purposes of power decisions.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Acked-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
  • Loading branch information
Mark Brown committed Feb 25, 2013
1 parent 19f949f commit 8af294b
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 0 deletions.
1 change: 1 addition & 0 deletions include/sound/soc-dapm.h
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,7 @@ struct snd_soc_dapm_path {
/* status */
u32 connect:1; /* source and sink widgets are connected */
u32 walked:1; /* path has been walked */
u32 walking:1; /* path is in the process of being walked */
u32 weak:1; /* path ignored for power management */

int (*connected)(struct snd_soc_dapm_widget *source,
Expand Down
15 changes: 15 additions & 0 deletions sound/soc/soc-dapm.c
Original file line number Diff line number Diff line change
Expand Up @@ -821,6 +821,7 @@ static int is_connected_output_ep(struct snd_soc_dapm_widget *widget,
(widget->id == snd_soc_dapm_line &&
!list_empty(&widget->sources))) {
widget->outputs = snd_soc_dapm_suspend_check(widget);
path->walking = 0;
return widget->outputs;
}
}
Expand All @@ -831,13 +832,17 @@ static int is_connected_output_ep(struct snd_soc_dapm_widget *widget,
if (path->weak)
continue;

if (path->walking)
return 1;

if (path->walked)
continue;

trace_snd_soc_dapm_output_path(widget, path);

if (path->sink && path->connect) {
path->walked = 1;
path->walking = 1;

/* do we need to add this widget to the list ? */
if (list) {
Expand All @@ -847,11 +852,14 @@ static int is_connected_output_ep(struct snd_soc_dapm_widget *widget,
dev_err(widget->dapm->dev,
"ASoC: could not add widget %s\n",
widget->name);
path->walking = 0;
return con;
}
}

con += is_connected_output_ep(path->sink, list);

path->walking = 0;
}
}

Expand Down Expand Up @@ -931,13 +939,17 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget,
if (path->weak)
continue;

if (path->walking)
return 1;

if (path->walked)
continue;

trace_snd_soc_dapm_input_path(widget, path);

if (path->source && path->connect) {
path->walked = 1;
path->walking = 1;

/* do we need to add this widget to the list ? */
if (list) {
Expand All @@ -947,11 +959,14 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget,
dev_err(widget->dapm->dev,
"ASoC: could not add widget %s\n",
widget->name);
path->walking = 0;
return con;
}
}

con += is_connected_input_ep(path->source, list);

path->walking = 0;
}
}

Expand Down

0 comments on commit 8af294b

Please sign in to comment.