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

ASoC: rsnd: call request_irq/free_irq once in MIX case



Each module's dai callback function availability is controlled
by mod->status. For example "always called", "call once".
In .probe/.remove case, it needs to be called always, because
.probe will call xxx_attach() function on .probe, especially
if platform is using MIXer.
For example, below case, MIX0/DVC0/SSI0 needs to be called twice.

        playback = <&src0 &ctu02 &mix0 &dvc0 &ssi0>;
        playback = <&src2 &ctu03 &mix0 &dvc0 &ssi0>;

But in this case, SSI0 will call request_irq() twice.
This patch add new RSND_SSI_PROBED flag and control it

Signed-off-by: default avatarKuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent bf9b29c7
Loading
Loading
Loading
Loading
+22 −5
Original line number Diff line number Diff line
@@ -90,6 +90,7 @@ struct rsnd_ssi {
#define RSND_SSI_NO_BUSIF		(1 << 1) /* SSI+DMA without BUSIF */
#define RSND_SSI_HDMI0			(1 << 2) /* for HDMI0 */
#define RSND_SSI_HDMI1			(1 << 3) /* for HDMI1 */
#define RSND_SSI_PROBED			(1 << 4)

#define for_each_rsnd_ssi(pos, priv, i)					\
	for (i = 0;							\
@@ -103,6 +104,7 @@ struct rsnd_ssi {
#define rsnd_mod_to_ssi(_mod) container_of((_mod), struct rsnd_ssi, mod)
#define rsnd_ssi_flags_has(p, f) ((p)->flags & f)
#define rsnd_ssi_flags_set(p, f) ((p)->flags |= f)
#define rsnd_ssi_flags_del(p, f) ((p)->flags = ((p)->flags & ~f))
#define rsnd_ssi_is_parent(ssi, io) ((ssi) == rsnd_io_to_mod_ssip(io))
#define rsnd_ssi_is_multi_slave(mod, io) \
	(rsnd_ssi_multi_slaves(io) & (1 << rsnd_mod_id(mod)))
@@ -784,12 +786,23 @@ static int rsnd_ssi_common_probe(struct rsnd_mod *mod,
	/*
	 * SSI might be called again as PIO fallback
	 * It is easy to manual handling for IRQ request/free
	 *
	 * OTOH, this function might be called many times if platform is
	 * using MIX. It needs xxx_attach() many times on xxx_probe().
	 * Because of it, we can't control .probe/.remove calling count by
	 * mod->status.
	 * But it don't need to call request_irq() many times.
	 * Let's control it by RSND_SSI_PROBED flag.
	 */
	if (!rsnd_ssi_flags_has(ssi, RSND_SSI_PROBED)) {
		ret = request_irq(ssi->irq,
				  rsnd_ssi_interrupt,
				  IRQF_SHARED,
				  dev_name(dev), mod);

		rsnd_ssi_flags_set(ssi, RSND_SSI_PROBED);
	}

	return ret;
}

@@ -805,8 +818,12 @@ static int rsnd_ssi_common_remove(struct rsnd_mod *mod,
		return 0;

	/* PIO will request IRQ again */
	if (rsnd_ssi_flags_has(ssi, RSND_SSI_PROBED)) {
		free_irq(ssi->irq, mod);

		rsnd_ssi_flags_del(ssi, RSND_SSI_PROBED);
	}

	return 0;
}