diff mbox series

[v3,05/14] ASoC: rockchip: i2s: Fix concurrency between tx/rx

Message ID 1629950520-14190-5-git-send-email-sugar.zhang@rock-chips.com (mailing list archive)
State New, archived
Headers show
Series Patches to update for rockchip i2s | expand

Commit Message

Sugar Zhang Aug. 26, 2021, 4:01 a.m. UTC
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>
---

Changes in v3: None
Changes in v2: None

 sound/soc/rockchip/rockchip_i2s.c | 8 ++++++++
 1 file changed, 8 insertions(+)

Comments

Mark Brown Aug. 26, 2021, 12:52 p.m. UTC | #1
On Thu, Aug 26, 2021 at 12:01:51PM +0800, Sugar Zhang wrote:

> +/* tx/rx ctrl lock */
> +static DEFINE_SPINLOCK(lock);
> +

Why is this a global and not part of the driver data?  It's also not
clear to me why this is a spinlock and not a mutex.
Sugar Zhang Aug. 27, 2021, 1:37 a.m. UTC | #2
Hi Mark,

On 2021/8/26 20:52, Mark Brown wrote:
> On Thu, Aug 26, 2021 at 12:01:51PM +0800, Sugar Zhang wrote:
>
>> +/* tx/rx ctrl lock */
>> +static DEFINE_SPINLOCK(lock);
>> +
> Why is this a global and not part of the driver data?  It's also not
> clear to me why this is a spinlock and not a mutex.

Yes, this should be moved into driver data, will do in v4.

it's not allowed to sleep in this context, so use spinlock instead.
diff mbox series

Patch

diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c
index 90877e8..0ba728f 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>
 
@@ -52,6 +53,9 @@  struct rk_i2s_dev {
 	unsigned int bclk_ratio;
 };
 
+/* tx/rx ctrl lock */
+static DEFINE_SPINLOCK(lock);
+
 static int i2s_runtime_suspend(struct device *dev)
 {
 	struct rk_i2s_dev *i2s = dev_get_drvdata(dev);
@@ -93,6 +97,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);
@@ -133,6 +138,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)
@@ -140,6 +146,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);
@@ -180,6 +187,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,