ASoC: rsnd: call free_irq() both DMA/PIO mode
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Thu, 10 Aug 2017 00:07:00 +0000 (00:07 +0000)
committerMark Brown <broonie@kernel.org>
Thu, 10 Aug 2017 15:06:56 +0000 (16:06 +0100)
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.gx@renesas.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/sh/rcar/ssi.c

index 0309de58bf18f41975cc98a33d9be155a42e634e..281ed0da6ba1ee87f857ce3dd31eb98317985434 100644 (file)
@@ -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 rsnd_mod_ops rsnd_ssi_dma_ops = {
        .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,