Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 213691c7 authored by Kuninori Morimoto's avatar Kuninori Morimoto Committed by Mark Brown
Browse files

ASoC: rsnd: call free_irq() both DMA/PIO mode



commit 701172dc ("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: 701172dc ("ASoC: rsnd: don't use devm_request_irq() for SSI")
Signed-off-by: default avatarKuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 880c15b1
Loading
Loading
Loading
Loading
+19 −18
Original line number Diff line number Diff line
@@ -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,