This patch makes the spinlock serializing access to the primary/secondary PCM a per I2S controller lock, rather than a global one. There is no need to have a global lock across multiple I2S controllers in the SoC. Signed-off-by: Sylwester Nawrocki <s.nawrocki@xxxxxxxxxxx> Acked-by: Krzysztof Kozlowski <krzk@xxxxxxxxxx> --- sound/soc/samsung/i2s.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c index 14d9fd658cfd..1156d63ce923 100644 --- a/sound/soc/samsung/i2s.c +++ b/sound/soc/samsung/i2s.c @@ -88,9 +88,6 @@ struct i2s_dai { struct samsung_i2s_priv *priv; }; -/* Lock for cross i/f checks */ -static DEFINE_SPINLOCK(lock); - struct samsung_i2s_priv { struct platform_device *pdev; struct platform_device *pdev_sec; @@ -101,6 +98,9 @@ struct samsung_i2s_priv { /* Spinlock protecting access to the device's registers */ spinlock_t lock; + /* Lock for cross i/f checks */ + spinlock_t pcm_lock; + /* CPU DAIs and their corresponding drivers */ struct i2s_dai *dai; struct snd_soc_dai_driver *dai_drv; @@ -832,7 +832,7 @@ static int i2s_startup(struct snd_pcm_substream *substream, pm_runtime_get_sync(dai->dev); - spin_lock_irqsave(&lock, flags); + spin_lock_irqsave(&priv->pcm_lock, flags); i2s->mode |= DAI_OPENED; @@ -844,7 +844,7 @@ static int i2s_startup(struct snd_pcm_substream *substream, if (!any_active(i2s) && (priv->quirks & QUIRK_NEED_RSTCLR)) writel(CON_RSTCLR, i2s->priv->addr + I2SCON); - spin_unlock_irqrestore(&lock, flags); + spin_unlock_irqrestore(&priv->pcm_lock, flags); return 0; } @@ -852,11 +852,12 @@ static int i2s_startup(struct snd_pcm_substream *substream, static void i2s_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { + struct samsung_i2s_priv *priv = snd_soc_dai_get_drvdata(dai); struct i2s_dai *i2s = to_info(dai); struct i2s_dai *other = get_other_dai(i2s); unsigned long flags; - spin_lock_irqsave(&lock, flags); + spin_lock_irqsave(&priv->pcm_lock, flags); i2s->mode &= ~DAI_OPENED; i2s->mode &= ~DAI_MANAGER; @@ -868,7 +869,7 @@ static void i2s_shutdown(struct snd_pcm_substream *substream, i2s->rfs = 0; i2s->bfs = 0; - spin_unlock_irqrestore(&lock, flags); + spin_unlock_irqrestore(&priv->pcm_lock, flags); pm_runtime_put(dai->dev); } @@ -1406,6 +1407,7 @@ static int samsung_i2s_probe(struct platform_device *pdev) pri_dai = &priv->dai[SAMSUNG_I2S_ID_PRIMARY - 1]; spin_lock_init(&priv->lock); + spin_lock_init(&priv->pcm_lock); if (!np) { if (i2s_pdata == NULL) { -- 2.20.1