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

Commit 10a9cca1 authored by Kuninori Morimoto's avatar Kuninori Morimoto Committed by Mark Brown
Browse files

ASoC: rsnd: add nolock_start/stop callback



Current Renesas Sound driver requests DMA channel when .probe timing,
and release it when .remove timing. And use DMA on .start/.stop
But, Audio DMAC power ON was handled when request timing (= .probe),
and power OFF was when release timing (= .remove).
This means Audio DMAC power is always ON during driver was enabled.
To fixup this issue, it should request/release DMA channel on each
playback/recorde timing.
But, DMA channel request/release function uses mutex lock inside.
This means it will breaks current spinlock's interrupt protect.
To solve this issue, DMA channel request/release function needs to
be called from non-spinlock area. This patch adds its callback.

Signed-off-by: default avatarKuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 161ba1f1
Loading
Loading
Loading
Loading
+26 −0
Original line number Diff line number Diff line
@@ -716,7 +716,33 @@ static int rsnd_soc_set_dai_tdm_slot(struct snd_soc_dai *dai,
	return 0;
}

static int rsnd_soc_dai_startup(struct snd_pcm_substream *substream,
				struct snd_soc_dai *dai)
{
	struct rsnd_dai *rdai = rsnd_dai_to_rdai(dai);
	struct rsnd_dai_stream *io = rsnd_rdai_to_io(rdai, substream);

	/*
	 * call rsnd_dai_call without spinlock
	 */
	return rsnd_dai_call(nolock_start, io, priv);
}

static void rsnd_soc_dai_shutdown(struct snd_pcm_substream *substream,
				  struct snd_soc_dai *dai)
{
	struct rsnd_dai *rdai = rsnd_dai_to_rdai(dai);
	struct rsnd_dai_stream *io = rsnd_rdai_to_io(rdai, substream);

	/*
	 * call rsnd_dai_call without spinlock
	 */
	rsnd_dai_call(nolock_stop, io, priv);
}

static const struct snd_soc_dai_ops rsnd_soc_dai_ops = {
	.startup	= rsnd_soc_dai_startup,
	.shutdown	= rsnd_soc_dai_shutdown,
	.trigger	= rsnd_soc_dai_trigger,
	.set_fmt	= rsnd_soc_dai_set_fmt,
	.set_tdm_slot	= rsnd_soc_set_dai_tdm_slot,
+14 −1
Original line number Diff line number Diff line
@@ -259,6 +259,12 @@ struct rsnd_mod_ops {
	int (*fallback)(struct rsnd_mod *mod,
			struct rsnd_dai_stream *io,
			struct rsnd_priv *priv);
	int (*nolock_start)(struct rsnd_mod *mod,
		    struct rsnd_dai_stream *io,
		    struct rsnd_priv *priv);
	int (*nolock_stop)(struct rsnd_mod *mod,
		    struct rsnd_dai_stream *io,
		    struct rsnd_priv *priv);
};

struct rsnd_dai_stream;
@@ -276,8 +282,9 @@ struct rsnd_mod {
/*
 * status
 *
 * 0xH0000CB0
 * 0xH0000CBA
 *
 * A	0: nolock_start	1: nolock_stop
 * B	0: init		1: quit
 * C	0: start	1: stop
 *
@@ -287,6 +294,8 @@ struct rsnd_mod {
 * H	0: fallback
 * H	0: hw_params
 */
#define __rsnd_mod_shift_nolock_start	0
#define __rsnd_mod_shift_nolock_stop	0
#define __rsnd_mod_shift_init		4
#define __rsnd_mod_shift_quit		4
#define __rsnd_mod_shift_start		8
@@ -300,6 +309,8 @@ struct rsnd_mod {

#define __rsnd_mod_add_probe		0
#define __rsnd_mod_add_remove		0
#define __rsnd_mod_add_nolock_start	 1
#define __rsnd_mod_add_nolock_stop	-1
#define __rsnd_mod_add_init		 1
#define __rsnd_mod_add_quit		-1
#define __rsnd_mod_add_start		 1
@@ -319,6 +330,8 @@ struct rsnd_mod {
#define __rsnd_mod_call_pcm_new		0
#define __rsnd_mod_call_fallback	0
#define __rsnd_mod_call_hw_params	0
#define __rsnd_mod_call_nolock_start	0
#define __rsnd_mod_call_nolock_stop	1

#define rsnd_mod_to_priv(mod) ((mod)->priv)
#define rsnd_mod_id(mod) ((mod) ? (mod)->id : -1)