]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/4.19.42/asoc-stm32-dfsdm-manage-multiple-prepare.patch
Linux 4.19.42
[thirdparty/kernel/stable-queue.git] / releases / 4.19.42 / asoc-stm32-dfsdm-manage-multiple-prepare.patch
CommitLineData
e7e2c20d
SL
1From d6c3ab267c315ce9bd36e434c610b93de2684211 Mon Sep 17 00:00:00 2001
2From: Olivier Moysan <olivier.moysan@st.com>
3Date: Mon, 4 Mar 2019 15:52:43 +0100
4Subject: ASoC: stm32: dfsdm: manage multiple prepare
5
6[ Upstream commit 19441e35a43b616ea6afad91ed0d9e77268d8f6a ]
7
8The DFSDM must be stopped when a new setting is applied.
9restart systematically DFSDM on multiple prepare calls,
10to apply changes.
11
12Signed-off-by: Olivier Moysan <olivier.moysan@st.com>
13Signed-off-by: Mark Brown <broonie@kernel.org>
14Signed-off-by: Sasha Levin <sashal@kernel.org>
15---
16 sound/soc/stm/stm32_adfsdm.c | 17 ++++++++++++++++-
17 1 file changed, 16 insertions(+), 1 deletion(-)
18
19diff --git a/sound/soc/stm/stm32_adfsdm.c b/sound/soc/stm/stm32_adfsdm.c
20index 706ff005234f3..71d341b732a4d 100644
21--- a/sound/soc/stm/stm32_adfsdm.c
22+++ b/sound/soc/stm/stm32_adfsdm.c
23@@ -9,6 +9,7 @@
24
25 #include <linux/clk.h>
26 #include <linux/module.h>
27+#include <linux/mutex.h>
28 #include <linux/platform_device.h>
29 #include <linux/slab.h>
30
31@@ -37,6 +38,8 @@ struct stm32_adfsdm_priv {
32 /* PCM buffer */
33 unsigned char *pcm_buff;
34 unsigned int pos;
35+
36+ struct mutex lock; /* protect against race condition on iio state */
37 };
38
39 static const struct snd_pcm_hardware stm32_adfsdm_pcm_hw = {
40@@ -62,10 +65,12 @@ static void stm32_adfsdm_shutdown(struct snd_pcm_substream *substream,
41 {
42 struct stm32_adfsdm_priv *priv = snd_soc_dai_get_drvdata(dai);
43
44+ mutex_lock(&priv->lock);
45 if (priv->iio_active) {
46 iio_channel_stop_all_cb(priv->iio_cb);
47 priv->iio_active = false;
48 }
49+ mutex_unlock(&priv->lock);
50 }
51
52 static int stm32_adfsdm_dai_prepare(struct snd_pcm_substream *substream,
53@@ -74,13 +79,19 @@ static int stm32_adfsdm_dai_prepare(struct snd_pcm_substream *substream,
54 struct stm32_adfsdm_priv *priv = snd_soc_dai_get_drvdata(dai);
55 int ret;
56
57+ mutex_lock(&priv->lock);
58+ if (priv->iio_active) {
59+ iio_channel_stop_all_cb(priv->iio_cb);
60+ priv->iio_active = false;
61+ }
62+
63 ret = iio_write_channel_attribute(priv->iio_ch,
64 substream->runtime->rate, 0,
65 IIO_CHAN_INFO_SAMP_FREQ);
66 if (ret < 0) {
67 dev_err(dai->dev, "%s: Failed to set %d sampling rate\n",
68 __func__, substream->runtime->rate);
69- return ret;
70+ goto out;
71 }
72
73 if (!priv->iio_active) {
74@@ -92,6 +103,9 @@ static int stm32_adfsdm_dai_prepare(struct snd_pcm_substream *substream,
75 __func__, ret);
76 }
77
78+out:
79+ mutex_unlock(&priv->lock);
80+
81 return ret;
82 }
83
84@@ -298,6 +312,7 @@ static int stm32_adfsdm_probe(struct platform_device *pdev)
85
86 priv->dev = &pdev->dev;
87 priv->dai_drv = stm32_adfsdm_dai;
88+ mutex_init(&priv->lock);
89
90 dev_set_drvdata(&pdev->dev, priv);
91
92--
932.20.1
94