diff options
author | Daniel Mack <daniel@caiaq.de> | 2010-03-22 05:11:15 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2010-04-05 14:14:11 -0400 |
commit | 5f712b2b73a9fc87fcc52124cfe8adefaa0c92f5 (patch) | |
tree | 0e7ab3cedba6b50cdf603c433b79ceebf23972b0 /sound/soc/imx | |
parent | d522ffbfb9fccf6eca283cd2e8b03cf3d21fb616 (diff) |
ALSA: ASoC: move dma_data from snd_soc_dai to snd_soc_pcm_stream
This fixes a memory corruption when ASoC devices are used in
full-duplex mode. Specifically for pxa-ssp code, where this pointer
is dynamically allocated for each direction and destroyed upon each
stream start.
All other platforms are fixed blindly, I couldn't even compile-test
them. Sorry for any breakage I may have caused.
[Note that this is a backported version for 2.6.34.
Upstream commit is fd23b7dee]
Signed-off-by: Daniel Mack <daniel@caiaq.de>
Reported-by: Sven Neumann <s.neumann@raumfeld.com>
Reported-by: Michael Hirsch <m.hirsch@raumfeld.com>
Acked-by: Liam Girdwood <lrg@slimlogic.co.uk>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/imx')
-rw-r--r-- | sound/soc/imx/imx-pcm-dma-mx2.c | 8 | ||||
-rw-r--r-- | sound/soc/imx/imx-ssi.c | 7 |
2 files changed, 11 insertions, 4 deletions
diff --git a/sound/soc/imx/imx-pcm-dma-mx2.c b/sound/soc/imx/imx-pcm-dma-mx2.c index 19452e44afdc..c78c000e2afe 100644 --- a/sound/soc/imx/imx-pcm-dma-mx2.c +++ b/sound/soc/imx/imx-pcm-dma-mx2.c | |||
@@ -83,11 +83,13 @@ static void snd_imx_dma_err_callback(int channel, void *data, int err) | |||
83 | static int imx_ssi_dma_alloc(struct snd_pcm_substream *substream) | 83 | static int imx_ssi_dma_alloc(struct snd_pcm_substream *substream) |
84 | { | 84 | { |
85 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 85 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
86 | struct imx_pcm_dma_params *dma_params = rtd->dai->cpu_dai->dma_data; | 86 | struct imx_pcm_dma_params *dma_params; |
87 | struct snd_pcm_runtime *runtime = substream->runtime; | 87 | struct snd_pcm_runtime *runtime = substream->runtime; |
88 | struct imx_pcm_runtime_data *iprtd = runtime->private_data; | 88 | struct imx_pcm_runtime_data *iprtd = runtime->private_data; |
89 | int ret; | 89 | int ret; |
90 | 90 | ||
91 | dma_params = snd_soc_get_dma_data(rtd->dai->cpu_dai, substream); | ||
92 | |||
91 | iprtd->dma = imx_dma_request_by_prio(DRV_NAME, DMA_PRIO_HIGH); | 93 | iprtd->dma = imx_dma_request_by_prio(DRV_NAME, DMA_PRIO_HIGH); |
92 | if (iprtd->dma < 0) { | 94 | if (iprtd->dma < 0) { |
93 | pr_err("Failed to claim the audio DMA\n"); | 95 | pr_err("Failed to claim the audio DMA\n"); |
@@ -192,10 +194,12 @@ static int snd_imx_pcm_prepare(struct snd_pcm_substream *substream) | |||
192 | { | 194 | { |
193 | struct snd_pcm_runtime *runtime = substream->runtime; | 195 | struct snd_pcm_runtime *runtime = substream->runtime; |
194 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 196 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
195 | struct imx_pcm_dma_params *dma_params = rtd->dai->cpu_dai->dma_data; | 197 | struct imx_pcm_dma_params *dma_params; |
196 | struct imx_pcm_runtime_data *iprtd = runtime->private_data; | 198 | struct imx_pcm_runtime_data *iprtd = runtime->private_data; |
197 | int err; | 199 | int err; |
198 | 200 | ||
201 | dma_params = snd_soc_get_dma_data(rtd->dai->cpu_dai, substream); | ||
202 | |||
199 | iprtd->substream = substream; | 203 | iprtd->substream = substream; |
200 | iprtd->buf = (unsigned int *)substream->dma_buffer.area; | 204 | iprtd->buf = (unsigned int *)substream->dma_buffer.area; |
201 | iprtd->period_cnt = 0; | 205 | iprtd->period_cnt = 0; |
diff --git a/sound/soc/imx/imx-ssi.c b/sound/soc/imx/imx-ssi.c index 56f46a75d297..28e55c7b14b4 100644 --- a/sound/soc/imx/imx-ssi.c +++ b/sound/soc/imx/imx-ssi.c | |||
@@ -234,17 +234,20 @@ static int imx_ssi_hw_params(struct snd_pcm_substream *substream, | |||
234 | struct snd_soc_dai *cpu_dai) | 234 | struct snd_soc_dai *cpu_dai) |
235 | { | 235 | { |
236 | struct imx_ssi *ssi = cpu_dai->private_data; | 236 | struct imx_ssi *ssi = cpu_dai->private_data; |
237 | struct imx_pcm_dma_params *dma_data; | ||
237 | u32 reg, sccr; | 238 | u32 reg, sccr; |
238 | 239 | ||
239 | /* Tx/Rx config */ | 240 | /* Tx/Rx config */ |
240 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | 241 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
241 | reg = SSI_STCCR; | 242 | reg = SSI_STCCR; |
242 | cpu_dai->dma_data = &ssi->dma_params_tx; | 243 | dma_data = &ssi->dma_params_tx; |
243 | } else { | 244 | } else { |
244 | reg = SSI_SRCCR; | 245 | reg = SSI_SRCCR; |
245 | cpu_dai->dma_data = &ssi->dma_params_rx; | 246 | dma_data = &ssi->dma_params_rx; |
246 | } | 247 | } |
247 | 248 | ||
249 | snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data); | ||
250 | |||
248 | sccr = readl(ssi->base + reg) & ~SSI_STCCR_WL_MASK; | 251 | sccr = readl(ssi->base + reg) & ~SSI_STCCR_WL_MASK; |
249 | 252 | ||
250 | /* DAI data (word) size */ | 253 | /* DAI data (word) size */ |