diff options
-rw-r--r-- | sound/soc/soc-dapm.c | 47 |
1 files changed, 35 insertions, 12 deletions
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 7a61b5cc2d4f..68acec667242 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -707,14 +707,33 @@ static int dapm_new_pga(struct snd_soc_dapm_widget *w) } /* reset 'walked' bit for each dapm path */ -static inline void dapm_clear_walk(struct snd_soc_dapm_context *dapm) +static void dapm_clear_walk_output(struct snd_soc_dapm_context *dapm, + struct list_head *sink) { struct snd_soc_dapm_path *p; - list_for_each_entry(p, &dapm->card->paths, list) - p->walked = 0; + list_for_each_entry(p, sink, list_source) { + if (p->walked) { + p->walked = 0; + dapm_clear_walk_output(dapm, &p->sink->sinks); + } + } +} + +static void dapm_clear_walk_input(struct snd_soc_dapm_context *dapm, + struct list_head *source) +{ + struct snd_soc_dapm_path *p; + + list_for_each_entry(p, source, list_sink) { + if (p->walked) { + p->walked = 0; + dapm_clear_walk_input(dapm, &p->source->sources); + } + } } + /* We implement power down on suspend by checking the power state of * the ALSA card - when we are suspending the ALSA state for the card * is set to D3. @@ -983,13 +1002,17 @@ int snd_soc_dapm_dai_get_connected_widgets(struct snd_soc_dai *dai, int stream, mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); dapm_reset(card); - if (stream == SNDRV_PCM_STREAM_PLAYBACK) + if (stream == SNDRV_PCM_STREAM_PLAYBACK) { paths = is_connected_output_ep(dai->playback_widget, list); - else + dapm_clear_walk_output(&card->dapm, + &dai->playback_widget->sinks); + } else { paths = is_connected_input_ep(dai->capture_widget, list); + dapm_clear_walk_input(&card->dapm, + &dai->capture_widget->sources); + } trace_snd_soc_dapm_connected(paths, stream); - dapm_clear_walk(&card->dapm); mutex_unlock(&card->dapm_mutex); return paths; @@ -1092,9 +1115,9 @@ static int dapm_generic_check_power(struct snd_soc_dapm_widget *w) DAPM_UPDATE_STAT(w, power_checks); in = is_connected_input_ep(w, NULL); - dapm_clear_walk(w->dapm); + dapm_clear_walk_input(w->dapm, &w->sources); out = is_connected_output_ep(w, NULL); - dapm_clear_walk(w->dapm); + dapm_clear_walk_output(w->dapm, &w->sinks); return out != 0 && in != 0; } @@ -1117,7 +1140,7 @@ static int dapm_adc_check_power(struct snd_soc_dapm_widget *w) if (w->active) { in = is_connected_input_ep(w, NULL); - dapm_clear_walk(w->dapm); + dapm_clear_walk_input(w->dapm, &w->sources); return in != 0; } else { return dapm_generic_check_power(w); @@ -1133,7 +1156,7 @@ static int dapm_dac_check_power(struct snd_soc_dapm_widget *w) if (w->active) { out = is_connected_output_ep(w, NULL); - dapm_clear_walk(w->dapm); + dapm_clear_walk_output(w->dapm, &w->sinks); return out != 0; } else { return dapm_generic_check_power(w); @@ -1745,9 +1768,9 @@ static ssize_t dapm_widget_power_read_file(struct file *file, return -ENOMEM; in = is_connected_input_ep(w, NULL); - dapm_clear_walk(w->dapm); + dapm_clear_walk_input(w->dapm, &w->sources); out = is_connected_output_ep(w, NULL); - dapm_clear_walk(w->dapm); + dapm_clear_walk_output(w->dapm, &w->sinks); ret = snprintf(buf, PAGE_SIZE, "%s: %s%s in %d out %d", w->name, w->power ? "On" : "Off", |