Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8be4da29 authored by Lars-Peter Clausen's avatar Lars-Peter Clausen Committed by Mark Brown
Browse files

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: default avatarLars-Peter Clausen <lars@metafoo.de>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent c1862c8b
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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);

/* 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 */
int snd_soc_dapm_dai_get_connected_widgets(struct snd_soc_dai *dai, int stream,
+4 −4
Original line number Diff line number Diff line
@@ -629,8 +629,8 @@ int snd_soc_suspend(struct device *dev)
					  SND_SOC_DAPM_STREAM_SUSPEND);
	}

	/* Recheck all analogue paths too */
	dapm_mark_io_dirty(&card->dapm);
	/* Recheck all endpoints too, their state is affected by suspend */
	dapm_mark_endpoints_dirty(card);
	snd_soc_dapm_sync(&card->dapm);

	/* 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 */
	snd_power_change_state(card->snd_card, SNDRV_CTL_POWER_D0);

	/* Recheck all analogue paths too */
	dapm_mark_io_dirty(&card->dapm);
	/* Recheck all endpoints too, their state is affected by suspend */
	dapm_mark_endpoints_dirty(card);
	snd_soc_dapm_sync(&card->dapm);
}

+4 −11
Original line number Diff line number Diff line
@@ -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;

	mutex_lock(&card->dapm_mutex);

	list_for_each_entry(w, &card->widgets, list) {
		switch (w->id) {
		case snd_soc_dapm_input:
		case snd_soc_dapm_output:
			dapm_mark_dirty(w, "Rechecking inputs and outputs");
			break;
		default:
			break;
		}
		if (w->is_sink || w->is_source)
			dapm_mark_dirty(w, "Rechecking endpoints");
	}

	mutex_unlock(&card->dapm_mutex);
}
EXPORT_SYMBOL_GPL(dapm_mark_io_dirty);
EXPORT_SYMBOL_GPL(dapm_mark_endpoints_dirty);

/* create a new dapm widget */
static inline struct snd_soc_dapm_widget *dapm_cnew_widget(