Unverified Commit 21a00fb3 authored by Pierre-Louis Bossart's avatar Pierre-Louis Bossart Committed by Mark Brown
Browse files

ASoC: soc-link: introduce exit() callback



Some machine drivers allocate or request resources with
snd_soc_link_init() phase of the card probe. These resources need to
be properly released when removing a card, and this patch suggests a
dual exit() callback.

The exit() is invoked in soc_remove_pcm_runtime(), which is not
completely symmetric with the init() invoked in soc_init_pcm_runtime().

Alternate solutions were considered, e.g. adding a .remove() callback
for the platform driver, but that's not symmetrical at all and would
be difficult to handle if there are more than one dailink implementing
an .init(). We looked also into using .remove_dai_link() callback, but
that would also be imbalanced.

Note that because of the error handling in snd_soc_bind_card(), which
jumps to probe_end, there is no way to guarantee the exit() is invoked
with resources allocated in the init(). Prior to releasing those
resources, implementations of the exit() callback shall check the
resources are valid.

Suggested-by: default avatarAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: default avatarPierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: default avatarGuennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
Reviewed-by: default avatarCurtis Malainey <curtis@malainey.com>
Link: https://lore.kernel.org/r/20200622154241.29053-2-pierre-louis.bossart@linux.intel.com


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 39853b14
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@
#define __SOC_LINK_H

int snd_soc_link_init(struct snd_soc_pcm_runtime *rtd);
void snd_soc_link_exit(struct snd_soc_pcm_runtime *rtd);
int snd_soc_link_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
				    struct snd_pcm_hw_params *params);

+3 −0
Original line number Diff line number Diff line
@@ -799,6 +799,9 @@ struct snd_soc_dai_link {
	/* codec/machine specific init - e.g. add machine controls */
	int (*init)(struct snd_soc_pcm_runtime *rtd);

	/* codec/machine specific exit - dual of init() */
	void (*exit)(struct snd_soc_pcm_runtime *rtd);

	/* optional hw_params re-writing for BE and FE sync */
	int (*be_hw_params_fixup)(struct snd_soc_pcm_runtime *rtd,
			struct snd_pcm_hw_params *params);
+3 −0
Original line number Diff line number Diff line
@@ -945,6 +945,9 @@ void snd_soc_remove_pcm_runtime(struct snd_soc_card *card,
{
	lockdep_assert_held(&client_mutex);

	/* release machine specific resources */
	snd_soc_link_exit(rtd);

	/*
	 * Notify the machine driver for extra destruction
	 */
+6 −0
Original line number Diff line number Diff line
@@ -40,6 +40,12 @@ int snd_soc_link_init(struct snd_soc_pcm_runtime *rtd)
	return soc_link_ret(rtd, ret);
}

void snd_soc_link_exit(struct snd_soc_pcm_runtime *rtd)
{
	if (rtd->dai_link->exit)
		rtd->dai_link->exit(rtd);
}

int snd_soc_link_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
				    struct snd_pcm_hw_params *params)
{