[PATCH] ASoC: rockchip: i2s: Fix concurrency between tx/rx
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@rock-chips.com ---
--- 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..e4782ba 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(&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(&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(&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(&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");
Hi Sugar,
Thank you for the patch! Yet something to improve:
[auto build test ERROR on rockchip/for-next] [also build test ERROR on v5.14] [cannot apply to asoc/for-next next-20210827] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch]
url: https://github.com/0day-ci/linux/commits/Sugar-Zhang/ASoC-rockchip-i2s-Fix-c... base: https://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip.git for-next config: hexagon-randconfig-r041-20210829 (attached as .config) compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project 4b1fde8a2b681dad2ce0c082a5d6422caa06b0bc) reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # https://github.com/0day-ci/linux/commit/69f422462083a0abbfbe83c9ed6628dc6cc7... git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review Sugar-Zhang/ASoC-rockchip-i2s-Fix-concurrency-between-tx-rx/20210830-103815 git checkout 69f422462083a0abbfbe83c9ed6628dc6cc728a9 # save the attached .config to linux build tree mkdir build_dir COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross O=build_dir ARCH=hexagon SHELL=/bin/bash sound/soc/rockchip/
If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot lkp@intel.com
All errors (new ones prefixed by >>):
sound/soc/rockchip/rockchip_i2s.c:97:13: error: use of undeclared identifier 'lock'
spin_lock(&lock); ^ sound/soc/rockchip/rockchip_i2s.c:138:15: error: use of undeclared identifier 'lock' spin_unlock(&lock); ^ sound/soc/rockchip/rockchip_i2s.c:146:13: error: use of undeclared identifier 'lock' spin_lock(&lock); ^ sound/soc/rockchip/rockchip_i2s.c:187:15: error: use of undeclared identifier 'lock' spin_unlock(&lock); ^ 4 errors generated.
vim +/lock +97 sound/soc/rockchip/rockchip_i2s.c
91 92 static void rockchip_snd_txctrl(struct rk_i2s_dev *i2s, int on) 93 { 94 unsigned int val = 0; 95 int retry = 10; 96
97 spin_lock(&lock);
98 if (on) { 99 regmap_update_bits(i2s->regmap, I2S_DMACR, 100 I2S_DMACR_TDE_ENABLE, I2S_DMACR_TDE_ENABLE); 101 102 regmap_update_bits(i2s->regmap, I2S_XFER, 103 I2S_XFER_TXS_START | I2S_XFER_RXS_START, 104 I2S_XFER_TXS_START | I2S_XFER_RXS_START); 105 106 i2s->tx_start = true; 107 } else { 108 i2s->tx_start = false; 109 110 regmap_update_bits(i2s->regmap, I2S_DMACR, 111 I2S_DMACR_TDE_ENABLE, I2S_DMACR_TDE_DISABLE); 112 113 if (!i2s->rx_start) { 114 regmap_update_bits(i2s->regmap, I2S_XFER, 115 I2S_XFER_TXS_START | 116 I2S_XFER_RXS_START, 117 I2S_XFER_TXS_STOP | 118 I2S_XFER_RXS_STOP); 119 120 udelay(150); 121 regmap_update_bits(i2s->regmap, I2S_CLR, 122 I2S_CLR_TXC | I2S_CLR_RXC, 123 I2S_CLR_TXC | I2S_CLR_RXC); 124 125 regmap_read(i2s->regmap, I2S_CLR, &val); 126 127 /* Should wait for clear operation to finish */ 128 while (val) { 129 regmap_read(i2s->regmap, I2S_CLR, &val); 130 retry--; 131 if (!retry) { 132 dev_warn(i2s->dev, "fail to clear\n"); 133 break; 134 } 135 } 136 } 137 } 138 spin_unlock(&lock); 139 } 140
--- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
Hi Sugar,
Thank you for the patch! Yet something to improve:
[auto build test ERROR on rockchip/for-next] [also build test ERROR on v5.14] [cannot apply to asoc/for-next next-20210827] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch]
url: https://github.com/0day-ci/linux/commits/Sugar-Zhang/ASoC-rockchip-i2s-Fix-c... base: https://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip.git for-next config: arc-allyesconfig (attached as .config) compiler: arceb-elf-gcc (GCC) 11.2.0 reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # https://github.com/0day-ci/linux/commit/69f422462083a0abbfbe83c9ed6628dc6cc7... git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review Sugar-Zhang/ASoC-rockchip-i2s-Fix-concurrency-between-tx-rx/20210830-103815 git checkout 69f422462083a0abbfbe83c9ed6628dc6cc728a9 # save the attached .config to linux build tree mkdir build_dir COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=arc SHELL=/bin/bash
If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot lkp@intel.com
All errors (new ones prefixed by >>):
sound/soc/rockchip/rockchip_i2s.c: In function 'rockchip_snd_txctrl':
sound/soc/rockchip/rockchip_i2s.c:97:20: error: 'lock' undeclared (first use in this function); did you mean 'flock'?
97 | spin_lock(&lock); | ^~~~ | flock sound/soc/rockchip/rockchip_i2s.c:97:20: note: each undeclared identifier is reported only once for each function it appears in sound/soc/rockchip/rockchip_i2s.c: In function 'rockchip_snd_rxctrl': sound/soc/rockchip/rockchip_i2s.c:146:20: error: 'lock' undeclared (first use in this function); did you mean 'flock'? 146 | spin_lock(&lock); | ^~~~ | flock
vim +97 sound/soc/rockchip/rockchip_i2s.c
91 92 static void rockchip_snd_txctrl(struct rk_i2s_dev *i2s, int on) 93 { 94 unsigned int val = 0; 95 int retry = 10; 96
97 spin_lock(&lock);
98 if (on) { 99 regmap_update_bits(i2s->regmap, I2S_DMACR, 100 I2S_DMACR_TDE_ENABLE, I2S_DMACR_TDE_ENABLE); 101 102 regmap_update_bits(i2s->regmap, I2S_XFER, 103 I2S_XFER_TXS_START | I2S_XFER_RXS_START, 104 I2S_XFER_TXS_START | I2S_XFER_RXS_START); 105 106 i2s->tx_start = true; 107 } else { 108 i2s->tx_start = false; 109 110 regmap_update_bits(i2s->regmap, I2S_DMACR, 111 I2S_DMACR_TDE_ENABLE, I2S_DMACR_TDE_DISABLE); 112 113 if (!i2s->rx_start) { 114 regmap_update_bits(i2s->regmap, I2S_XFER, 115 I2S_XFER_TXS_START | 116 I2S_XFER_RXS_START, 117 I2S_XFER_TXS_STOP | 118 I2S_XFER_RXS_STOP); 119 120 udelay(150); 121 regmap_update_bits(i2s->regmap, I2S_CLR, 122 I2S_CLR_TXC | I2S_CLR_RXC, 123 I2S_CLR_TXC | I2S_CLR_RXC); 124 125 regmap_read(i2s->regmap, I2S_CLR, &val); 126 127 /* Should wait for clear operation to finish */ 128 while (val) { 129 regmap_read(i2s->regmap, I2S_CLR, &val); 130 retry--; 131 if (!retry) { 132 dev_warn(i2s->dev, "fail to clear\n"); 133 break; 134 } 135 } 136 } 137 } 138 spin_unlock(&lock); 139 } 140
--- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
participants (2)
-
kernel test robot
-
Sugar Zhang