diff options
author | Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> | 2017-08-09 20:07:38 -0400 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2017-08-10 11:07:04 -0400 |
commit | b6e58fcacb3edc6245ecf700207ba675cba18018 (patch) | |
tree | d1823179d29faaf9c8a42adea031a4719e1778f4 | |
parent | bf9b29c784b393d1e506945f1e24e871d2587eb3 (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.c | 27 |
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 | } |