summaryrefslogtreecommitdiff
path: root/sound/soc/sh/rcar/ssi.c
diff options
context:
space:
mode:
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>2015-06-15 06:21:15 +0000
committerMark Brown <broonie@kernel.org>2015-06-16 12:34:01 +0100
commit75defee0f1b3fcd91d8a304d6444635a459b8249 (patch)
treedd5d78d7c54bdeacbc3e6e5cc1e17fe7c770ff95 /sound/soc/sh/rcar/ssi.c
parent12927a8f80264256e6cb2d3241fe9d6f4ad7face (diff)
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>
Diffstat (limited to 'sound/soc/sh/rcar/ssi.c')
-rw-r--r--sound/soc/sh/rcar/ssi.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c
index 856917392b79..25483211a349 100644
--- a/sound/soc/sh/rcar/ssi.c
+++ b/sound/soc/sh/rcar/ssi.c
@@ -426,6 +426,7 @@ static irqreturn_t rsnd_ssi_interrupt(int irq, void *data)
struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
int is_dma = rsnd_ssi_is_dma_mode(mod);
u32 status;
+ bool elapsed = false;
spin_lock(&priv->lock);
@@ -451,7 +452,7 @@ static irqreturn_t rsnd_ssi_interrupt(int irq, void *data)
else
*buf = rsnd_mod_read(mod, SSIRDR);
- rsnd_dai_pointer_update(io, sizeof(*buf));
+ elapsed = rsnd_dai_pointer_update(io, sizeof(*buf));
}
/* DMA only */
@@ -476,6 +477,9 @@ static irqreturn_t rsnd_ssi_interrupt(int irq, void *data)
rsnd_ssi_interrupt_out:
spin_unlock(&priv->lock);
+ if (elapsed)
+ rsnd_dai_period_elapsed(io);
+
return IRQ_HANDLED;
}