ASoC: rsnd: don't call snd_pcm_period_elapsed() under spin lock

'a9e1ac1a9e4585b5("ASoC: rsnd: spin lock for interrupt handler")'
added spin lock under interrupt handler to solve HW restart issue.

OTOH, current rsnd driver calls snd_pcm_period_elapsed() from
rsnd_dai_pointer_update(). but, it will be called under spin lock
if SSI was PIO mode.

If it was called under spin lock, it will call
snd_pcm_update_state() -> snd_pcm_drain_done().
Then, it calls rsnd_soc_dai_trigger() and will be dead-lock.
This patch doesn't call rsnd_dai_pointer_update() under spin lock

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Tested-by: Keita Kobayashi <keita.kobayashi.ym@renesas.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
这个提交包含在:
Kuninori Morimoto
2015-06-15 06:21:15 +00:00
提交者 Mark Brown
父节点 12927a8f80
当前提交 75defee0f1
修改 4 个文件,包含 35 行新增5 行删除

查看文件

@@ -36,7 +36,10 @@ static void rsnd_dmaen_complete(void *data)
{
struct rsnd_dma *dma = (struct rsnd_dma *)data;
struct rsnd_mod *mod = rsnd_dma_to_mod(dma);
struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
bool elapsed = false;
unsigned long flags;
/*
* Renesas sound Gen1 needs 1 DMAC,
@@ -49,8 +52,14 @@ static void rsnd_dmaen_complete(void *data)
* rsnd_dai_pointer_update() will be called twice,
* ant it will breaks io->byte_pos
*/
spin_lock_irqsave(&priv->lock, flags);
rsnd_dai_pointer_update(io, io->byte_per_period);
elapsed = rsnd_dai_pointer_update(io, io->byte_per_period);
spin_unlock_irqrestore(&priv->lock, flags);
if (elapsed)
rsnd_dai_period_elapsed(io);
}
static void rsnd_dmaen_stop(struct rsnd_dma *dma)