mirror of
https://github.com/torvalds/linux.git
synced 2024-12-26 04:42:12 +00:00
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: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
parent
bf9b29c784
commit
b6e58fcacb
@ -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,11 +786,22 @@ 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.
|
||||
*/
|
||||
ret = request_irq(ssi->irq,
|
||||
rsnd_ssi_interrupt,
|
||||
IRQF_SHARED,
|
||||
dev_name(dev), mod);
|
||||
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,7 +818,11 @@ static int rsnd_ssi_common_remove(struct rsnd_mod *mod,
|
||||
return 0;
|
||||
|
||||
/* PIO will request IRQ again */
|
||||
free_irq(ssi->irq, mod);
|
||||
if (rsnd_ssi_flags_has(ssi, RSND_SSI_PROBED)) {
|
||||
free_irq(ssi->irq, mod);
|
||||
|
||||
rsnd_ssi_flags_del(ssi, RSND_SSI_PROBED);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user