ASoC: dapm: Mark endpoints instead of IO widgets dirty during suspend/resume

The state of endpoint widgets is affected by that card's power state.
Endpoint widgets that do no have the ignore_suspend flag set will be
considered inactive during suspend. So they have to be re-checked and marked
dirty after the card's power state changes. Currently the input and output
widgets are marked dirty instead, this works most of the time since
typically a path from one endpoint to another will go via a input or output
widget. But marking the endpoints dirty is technically more correct and will
also work for odd corner cases.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
Lars-Peter Clausen 2014-10-25 17:42:01 +02:00 committed by Mark Brown
parent c1862c8bae
commit 8be4da29cf
3 changed files with 9 additions and 16 deletions

View File

@ -435,7 +435,7 @@ void snd_soc_dapm_auto_nc_pins(struct snd_soc_card *card);
unsigned int dapm_kcontrol_get_value(const struct snd_kcontrol *kcontrol); unsigned int dapm_kcontrol_get_value(const struct snd_kcontrol *kcontrol);
/* Mostly internal - should not normally be used */ /* Mostly internal - should not normally be used */
void dapm_mark_io_dirty(struct snd_soc_dapm_context *dapm); void dapm_mark_endpoints_dirty(struct snd_soc_card *card);
/* dapm path query */ /* dapm path query */
int snd_soc_dapm_dai_get_connected_widgets(struct snd_soc_dai *dai, int stream, int snd_soc_dapm_dai_get_connected_widgets(struct snd_soc_dai *dai, int stream,

View File

@ -629,8 +629,8 @@ int snd_soc_suspend(struct device *dev)
SND_SOC_DAPM_STREAM_SUSPEND); SND_SOC_DAPM_STREAM_SUSPEND);
} }
/* Recheck all analogue paths too */ /* Recheck all endpoints too, their state is affected by suspend */
dapm_mark_io_dirty(&card->dapm); dapm_mark_endpoints_dirty(card);
snd_soc_dapm_sync(&card->dapm); snd_soc_dapm_sync(&card->dapm);
/* suspend all CODECs */ /* suspend all CODECs */
@ -796,8 +796,8 @@ static void soc_resume_deferred(struct work_struct *work)
/* userspace can access us now we are back as we were before */ /* userspace can access us now we are back as we were before */
snd_power_change_state(card->snd_card, SNDRV_CTL_POWER_D0); snd_power_change_state(card->snd_card, SNDRV_CTL_POWER_D0);
/* Recheck all analogue paths too */ /* Recheck all endpoints too, their state is affected by suspend */
dapm_mark_io_dirty(&card->dapm); dapm_mark_endpoints_dirty(card);
snd_soc_dapm_sync(&card->dapm); snd_soc_dapm_sync(&card->dapm);
} }

View File

@ -159,27 +159,20 @@ static void dapm_mark_dirty(struct snd_soc_dapm_widget *w, const char *reason)
} }
} }
void dapm_mark_io_dirty(struct snd_soc_dapm_context *dapm) void dapm_mark_endpoints_dirty(struct snd_soc_card *card)
{ {
struct snd_soc_card *card = dapm->card;
struct snd_soc_dapm_widget *w; struct snd_soc_dapm_widget *w;
mutex_lock(&card->dapm_mutex); mutex_lock(&card->dapm_mutex);
list_for_each_entry(w, &card->widgets, list) { list_for_each_entry(w, &card->widgets, list) {
switch (w->id) { if (w->is_sink || w->is_source)
case snd_soc_dapm_input: dapm_mark_dirty(w, "Rechecking endpoints");
case snd_soc_dapm_output:
dapm_mark_dirty(w, "Rechecking inputs and outputs");
break;
default:
break;
}
} }
mutex_unlock(&card->dapm_mutex); mutex_unlock(&card->dapm_mutex);
} }
EXPORT_SYMBOL_GPL(dapm_mark_io_dirty); EXPORT_SYMBOL_GPL(dapm_mark_endpoints_dirty);
/* create a new dapm widget */ /* create a new dapm widget */
static inline struct snd_soc_dapm_widget *dapm_cnew_widget( static inline struct snd_soc_dapm_widget *dapm_cnew_widget(