aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>2017-08-09 20:07:38 -0400
committerMark Brown <broonie@kernel.org>2017-08-10 11:07:04 -0400
commitb6e58fcacb3edc6245ecf700207ba675cba18018 (patch)
treed1823179d29faaf9c8a42adea031a4719e1778f4
parentbf9b29c784b393d1e506945f1e24e871d2587eb3 (diff)
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>
-rw-r--r--sound/soc/sh/rcar/ssi.c27
1 files changed, 22 insertions, 5 deletions
diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c
index ca9355b86bd9..8bb47144660b 100644
--- a/sound/soc/sh/rcar/ssi.c
+++ b/sound/soc/sh/rcar/ssi.c
@@ -90,6 +90,7 @@ struct rsnd_ssi {
90#define RSND_SSI_NO_BUSIF (1 << 1) /* SSI+DMA without BUSIF */ 90#define RSND_SSI_NO_BUSIF (1 << 1) /* SSI+DMA without BUSIF */
91#define RSND_SSI_HDMI0 (1 << 2) /* for HDMI0 */ 91#define RSND_SSI_HDMI0 (1 << 2) /* for HDMI0 */
92#define RSND_SSI_HDMI1 (1 << 3) /* for HDMI1 */ 92#define RSND_SSI_HDMI1 (1 << 3) /* for HDMI1 */
93#define RSND_SSI_PROBED (1 << 4)
93 94
94#define for_each_rsnd_ssi(pos, priv, i) \ 95#define for_each_rsnd_ssi(pos, priv, i) \
95 for (i = 0; \ 96 for (i = 0; \
@@ -103,6 +104,7 @@ struct rsnd_ssi {
103#define rsnd_mod_to_ssi(_mod) container_of((_mod), struct rsnd_ssi, mod) 104#define rsnd_mod_to_ssi(_mod) container_of((_mod), struct rsnd_ssi, mod)
104#define rsnd_ssi_flags_has(p, f) ((p)->flags & f) 105#define rsnd_ssi_flags_has(p, f) ((p)->flags & f)
105#define rsnd_ssi_flags_set(p, f) ((p)->flags |= f) 106#define rsnd_ssi_flags_set(p, f) ((p)->flags |= f)
107#define rsnd_ssi_flags_del(p, f) ((p)->flags = ((p)->flags & ~f))
106#define rsnd_ssi_is_parent(ssi, io) ((ssi) == rsnd_io_to_mod_ssip(io)) 108#define rsnd_ssi_is_parent(ssi, io) ((ssi) == rsnd_io_to_mod_ssip(io))
107#define rsnd_ssi_is_multi_slave(mod, io) \ 109#define rsnd_ssi_is_multi_slave(mod, io) \
108 (rsnd_ssi_multi_slaves(io) & (1 << rsnd_mod_id(mod))) 110 (rsnd_ssi_multi_slaves(io) & (1 << rsnd_mod_id(mod)))
@@ -784,11 +786,22 @@ static int rsnd_ssi_common_probe(struct rsnd_mod *mod,
784 /* 786 /*
785 * SSI might be called again as PIO fallback 787 * SSI might be called again as PIO fallback
786 * It is easy to manual handling for IRQ request/free 788 * It is easy to manual handling for IRQ request/free
789 *
790 * OTOH, this function might be called many times if platform is
791 * using MIX. It needs xxx_attach() many times on xxx_probe().
792 * Because of it, we can't control .probe/.remove calling count by
793 * mod->status.
794 * But it don't need to call request_irq() many times.
795 * Let's control it by RSND_SSI_PROBED flag.
787 */ 796 */
788 ret = request_irq(ssi->irq, 797 if (!rsnd_ssi_flags_has(ssi, RSND_SSI_PROBED)) {
789 rsnd_ssi_interrupt, 798 ret = request_irq(ssi->irq,
790 IRQF_SHARED, 799 rsnd_ssi_interrupt,
791 dev_name(dev), mod); 800 IRQF_SHARED,
801 dev_name(dev), mod);
802
803 rsnd_ssi_flags_set(ssi, RSND_SSI_PROBED);
804 }
792 805
793 return ret; 806 return ret;
794} 807}
@@ -805,7 +818,11 @@ static int rsnd_ssi_common_remove(struct rsnd_mod *mod,
805 return 0; 818 return 0;
806 819
807 /* PIO will request IRQ again */ 820 /* PIO will request IRQ again */
808 free_irq(ssi->irq, mod); 821 if (rsnd_ssi_flags_has(ssi, RSND_SSI_PROBED)) {
822 free_irq(ssi->irq, mod);
823
824 rsnd_ssi_flags_del(ssi, RSND_SSI_PROBED);
825 }
809 826
810 return 0; 827 return 0;
811} 828}