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: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:

committed by
Mark Brown

parent
161ba1f1a5
commit
10a9cca132
@@ -716,7 +716,33 @@ static int rsnd_soc_set_dai_tdm_slot(struct snd_soc_dai *dai,
|
|||||||
return 0;
|
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 = {
|
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,
|
.trigger = rsnd_soc_dai_trigger,
|
||||||
.set_fmt = rsnd_soc_dai_set_fmt,
|
.set_fmt = rsnd_soc_dai_set_fmt,
|
||||||
.set_tdm_slot = rsnd_soc_set_dai_tdm_slot,
|
.set_tdm_slot = rsnd_soc_set_dai_tdm_slot,
|
||||||
|
@@ -259,6 +259,12 @@ struct rsnd_mod_ops {
|
|||||||
int (*fallback)(struct rsnd_mod *mod,
|
int (*fallback)(struct rsnd_mod *mod,
|
||||||
struct rsnd_dai_stream *io,
|
struct rsnd_dai_stream *io,
|
||||||
struct rsnd_priv *priv);
|
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;
|
struct rsnd_dai_stream;
|
||||||
@@ -276,8 +282,9 @@ struct rsnd_mod {
|
|||||||
/*
|
/*
|
||||||
* status
|
* status
|
||||||
*
|
*
|
||||||
* 0xH0000CB0
|
* 0xH0000CBA
|
||||||
*
|
*
|
||||||
|
* A 0: nolock_start 1: nolock_stop
|
||||||
* B 0: init 1: quit
|
* B 0: init 1: quit
|
||||||
* C 0: start 1: stop
|
* C 0: start 1: stop
|
||||||
*
|
*
|
||||||
@@ -287,6 +294,8 @@ struct rsnd_mod {
|
|||||||
* H 0: fallback
|
* H 0: fallback
|
||||||
* H 0: hw_params
|
* 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_init 4
|
||||||
#define __rsnd_mod_shift_quit 4
|
#define __rsnd_mod_shift_quit 4
|
||||||
#define __rsnd_mod_shift_start 8
|
#define __rsnd_mod_shift_start 8
|
||||||
@@ -300,6 +309,8 @@ struct rsnd_mod {
|
|||||||
|
|
||||||
#define __rsnd_mod_add_probe 0
|
#define __rsnd_mod_add_probe 0
|
||||||
#define __rsnd_mod_add_remove 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_init 1
|
||||||
#define __rsnd_mod_add_quit -1
|
#define __rsnd_mod_add_quit -1
|
||||||
#define __rsnd_mod_add_start 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_pcm_new 0
|
||||||
#define __rsnd_mod_call_fallback 0
|
#define __rsnd_mod_call_fallback 0
|
||||||
#define __rsnd_mod_call_hw_params 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_to_priv(mod) ((mod)->priv)
|
||||||
#define rsnd_mod_id(mod) ((mod) ? (mod)->id : -1)
|
#define rsnd_mod_id(mod) ((mod) ? (mod)->id : -1)
|
||||||
|
Reference in New Issue
Block a user