]>
Commit | Line | Data |
---|---|---|
e7e2c20d SL |
1 | From d6c3ab267c315ce9bd36e434c610b93de2684211 Mon Sep 17 00:00:00 2001 |
2 | From: Olivier Moysan <olivier.moysan@st.com> | |
3 | Date: Mon, 4 Mar 2019 15:52:43 +0100 | |
4 | Subject: ASoC: stm32: dfsdm: manage multiple prepare | |
5 | ||
6 | [ Upstream commit 19441e35a43b616ea6afad91ed0d9e77268d8f6a ] | |
7 | ||
8 | The DFSDM must be stopped when a new setting is applied. | |
9 | restart systematically DFSDM on multiple prepare calls, | |
10 | to apply changes. | |
11 | ||
12 | Signed-off-by: Olivier Moysan <olivier.moysan@st.com> | |
13 | Signed-off-by: Mark Brown <broonie@kernel.org> | |
14 | Signed-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 | ||
19 | diff --git a/sound/soc/stm/stm32_adfsdm.c b/sound/soc/stm/stm32_adfsdm.c | |
20 | index 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 | -- | |
93 | 2.20.1 | |
94 |