diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index 2b7323c92994..d460d2aa82ee 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -170,6 +170,14 @@ void rsnd_mod_quit(struct rsnd_mod *mod) clk_unprepare(mod->clk); } +int rsnd_mod_is_working(struct rsnd_mod *mod) +{ + struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); + + /* see rsnd_dai_stream_init/quit() */ + return !!io->substream; +} + /* * settting function */ @@ -362,7 +370,7 @@ static int rsnd_soc_dai_trigger(struct snd_pcm_substream *substream, int cmd, int ret; unsigned long flags; - rsnd_lock(priv, flags); + spin_lock_irqsave(&priv->lock, flags); switch (cmd) { case SNDRV_PCM_TRIGGER_START: @@ -400,7 +408,7 @@ static int rsnd_soc_dai_trigger(struct snd_pcm_substream *substream, int cmd, } dai_trigger_end: - rsnd_unlock(priv, flags); + spin_unlock_irqrestore(&priv->lock, flags); return ret; } diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index 4e6de6804cfb..03ff071d012f 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h @@ -303,6 +303,7 @@ int rsnd_mod_init(struct rsnd_mod *mod, int id); void rsnd_mod_quit(struct rsnd_mod *mod); char *rsnd_mod_name(struct rsnd_mod *mod); +int rsnd_mod_is_working(struct rsnd_mod *mod); struct dma_chan *rsnd_mod_dma_req(struct rsnd_mod *mod); /* @@ -449,8 +450,6 @@ struct rsnd_priv { #define rsnd_priv_to_pdev(priv) ((priv)->pdev) #define rsnd_priv_to_dev(priv) (&(rsnd_priv_to_pdev(priv)->dev)) #define rsnd_priv_to_info(priv) ((priv)->info) -#define rsnd_lock(priv, flags) spin_lock_irqsave(&priv->lock, flags) -#define rsnd_unlock(priv, flags) spin_unlock_irqrestore(&priv->lock, flags) /* * rsnd_kctrl diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c index 3beb32eb412a..fbe9166e26d1 100644 --- a/sound/soc/sh/rcar/src.c +++ b/sound/soc/sh/rcar/src.c @@ -673,10 +673,13 @@ static int _rsnd_src_stop_gen2(struct rsnd_mod *mod) static irqreturn_t rsnd_src_interrupt_gen2(int irq, void *data) { struct rsnd_mod *mod = data; - struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); + struct rsnd_priv *priv = rsnd_mod_to_priv(mod); - if (!io) - return IRQ_NONE; + spin_lock(&priv->lock); + + /* ignore all cases if not working */ + if (!rsnd_mod_is_working(mod)) + goto rsnd_src_interrupt_gen2_out; if (rsnd_src_error_record_gen2(mod)) { struct rsnd_priv *priv = rsnd_mod_to_priv(mod); @@ -692,6 +695,8 @@ static irqreturn_t rsnd_src_interrupt_gen2(int irq, void *data) else dev_warn(dev, "no more SRC restart\n"); } +rsnd_src_interrupt_gen2_out: + spin_unlock(&priv->lock); return IRQ_HANDLED; } diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index 927ac52a6d1e..50fa3928a003 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c @@ -423,10 +423,15 @@ static irqreturn_t rsnd_ssi_interrupt(int irq, void *data) struct rsnd_priv *priv = rsnd_mod_to_priv(mod); struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); int is_dma = rsnd_ssi_is_dma_mode(mod); - u32 status = rsnd_mod_read(mod, SSISR); + u32 status; - if (!io) - return IRQ_NONE; + spin_lock(&priv->lock); + + /* ignore all cases if not working */ + if (!rsnd_mod_is_working(mod)) + goto rsnd_ssi_interrupt_out; + + status = rsnd_mod_read(mod, SSISR); /* PIO only */ if (!is_dma && (status & DIRQ)) { @@ -466,6 +471,9 @@ static irqreturn_t rsnd_ssi_interrupt(int irq, void *data) rsnd_ssi_record_error(ssi, status); +rsnd_ssi_interrupt_out: + spin_unlock(&priv->lock); + return IRQ_HANDLED; }