From: Kuninori Morimoto <kuninori.morimoto...@renesas.com>

commit 701172dca15b ("ASoC: rsnd: don't use devm_request_irq() for SSI")
exchanged devm_request_irq() to request_irq() for SSI, because SSI will
fallback into PIO mode if DMA doesn't work.
But, because of it, PIO mode needed to call free_irq() when removing,
not only DMA mode.
This patch call free_irq() both PIO/DMA. Otherwise, rsnd IRQ handler
will be increased if user tried many unbind/bind.

Fixes: 701172dca15b ("ASoC: rsnd: don't use devm_request_irq() for SSI")
Signed-off-by: Kuninori Morimoto <kuninori.morimoto...@renesas.com>
---
 sound/soc/sh/rcar/ssi.c | 37 +++++++++++++++++++------------------
 1 file changed, 19 insertions(+), 18 deletions(-)

diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c
index 0309de5..281ed0d 100644
--- a/sound/soc/sh/rcar/ssi.c
+++ b/sound/soc/sh/rcar/ssi.c
@@ -792,6 +792,23 @@ static int rsnd_ssi_common_probe(struct rsnd_mod *mod,
        return ret;
 }
 
+static int rsnd_ssi_common_remove(struct rsnd_mod *mod,
+                                 struct rsnd_dai_stream *io,
+                                 struct rsnd_priv *priv)
+{
+       struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
+       struct rsnd_mod *pure_ssi_mod = rsnd_io_to_mod_ssi(io);
+
+       /* Do nothing if non SSI (= SSI parent, multi SSI) mod */
+       if (pure_ssi_mod != mod)
+               return 0;
+
+       /* PIO will request IRQ again */
+       free_irq(ssi->irq, mod);
+
+       return 0;
+}
+
 static int rsnd_ssi_pointer(struct rsnd_mod *mod,
                            struct rsnd_dai_stream *io,
                            snd_pcm_uframes_t *pointer)
@@ -807,6 +824,7 @@ static int rsnd_ssi_pointer(struct rsnd_mod *mod,
 static struct rsnd_mod_ops rsnd_ssi_pio_ops = {
        .name   = SSI_NAME,
        .probe  = rsnd_ssi_common_probe,
+       .remove = rsnd_ssi_common_remove,
        .init   = rsnd_ssi_init,
        .quit   = rsnd_ssi_quit,
        .start  = rsnd_ssi_start,
@@ -841,23 +859,6 @@ static int rsnd_ssi_dma_probe(struct rsnd_mod *mod,
        return ret;
 }
 
-static int rsnd_ssi_dma_remove(struct rsnd_mod *mod,
-                              struct rsnd_dai_stream *io,
-                              struct rsnd_priv *priv)
-{
-       struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
-       struct rsnd_mod *pure_ssi_mod = rsnd_io_to_mod_ssi(io);
-
-       /* Do nothing if non SSI (= SSI parent, multi SSI) mod */
-       if (pure_ssi_mod != mod)
-               return 0;
-
-       /* PIO will request IRQ again */
-       free_irq(ssi->irq, mod);
-
-       return 0;
-}
-
 static int rsnd_ssi_fallback(struct rsnd_mod *mod,
                             struct rsnd_dai_stream *io,
                             struct rsnd_priv *priv)
@@ -899,7 +900,7 @@ static struct dma_chan *rsnd_ssi_dma_req(struct 
rsnd_dai_stream *io,
        .name   = SSI_NAME,
        .dma_req = rsnd_ssi_dma_req,
        .probe  = rsnd_ssi_dma_probe,
-       .remove = rsnd_ssi_dma_remove,
+       .remove = rsnd_ssi_common_remove,
        .init   = rsnd_ssi_init,
        .quit   = rsnd_ssi_quit,
        .start  = rsnd_ssi_start,
-- 
1.9.1

Reply via email to