This patch adds lock to fix comcurrency between tx/rx to fix 'rockchip-i2s ff070000.i2s; fail to clear' Considering the situation; tx stream rx stream | | | disable enable | | reset After this patch: lock | tx stream | enable | unlock -------- --------- lock | rx stream | disable | reset | unlock Signed-off-by: Sugar Zhang <sugar.zhang@xxxxxxxxxxxxxx> --- Changes in v2: - Fix compile error. sound/soc/rockchip/rockchip_i2s.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c index c7dc350..88e340f 100644 --- a/sound/soc/rockchip/rockchip_i2s.c +++ b/sound/soc/rockchip/rockchip_i2s.c @@ -15,6 +15,7 @@ #include <linux/clk.h> #include <linux/pm_runtime.h> #include <linux/regmap.h> +#include <linux/spinlock.h> #include <sound/pcm_params.h> #include <sound/dmaengine_pcm.h> @@ -49,6 +50,7 @@ struct rk_i2s_dev { bool rx_start; bool is_master_mode; const struct rk_i2s_pins *pins; + spinlock_t lock; /* tx/rx lock */ }; static int i2s_runtime_suspend(struct device *dev) @@ -92,6 +94,7 @@ static void rockchip_snd_txctrl(struct rk_i2s_dev *i2s, int on) unsigned int val = 0; int retry = 10; + spin_lock(&i2s->lock); if (on) { regmap_update_bits(i2s->regmap, I2S_DMACR, I2S_DMACR_TDE_ENABLE, I2S_DMACR_TDE_ENABLE); @@ -132,6 +135,7 @@ static void rockchip_snd_txctrl(struct rk_i2s_dev *i2s, int on) } } } + spin_unlock(&i2s->lock); } static void rockchip_snd_rxctrl(struct rk_i2s_dev *i2s, int on) @@ -139,6 +143,7 @@ static void rockchip_snd_rxctrl(struct rk_i2s_dev *i2s, int on) unsigned int val = 0; int retry = 10; + spin_lock(&i2s->lock); if (on) { regmap_update_bits(i2s->regmap, I2S_DMACR, I2S_DMACR_RDE_ENABLE, I2S_DMACR_RDE_ENABLE); @@ -179,6 +184,7 @@ static void rockchip_snd_rxctrl(struct rk_i2s_dev *i2s, int on) } } } + spin_unlock(&i2s->lock); } static int rockchip_i2s_set_fmt(struct snd_soc_dai *cpu_dai, @@ -589,6 +595,7 @@ static int rockchip_i2s_probe(struct platform_device *pdev) if (!i2s) return -ENOMEM; + spin_lock_init(&i2s->lock); i2s->dev = &pdev->dev; i2s->grf = syscon_regmap_lookup_by_phandle(node, "rockchip,grf"); -- 2.7.4