diff options
author | Daniel Mack <daniel@caiaq.de> | 2010-03-19 10:52:55 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2010-03-19 15:37:29 -0400 |
commit | fd23b7dee5e4d369f620979cb120f53629389355 (patch) | |
tree | bbfa4637b0b97662b8ee63922eccb01913baaf1d /sound/soc/s3c24xx/s3c-i2s-v2.c | |
parent | 093208f5d03980d7216b706e3c54432d0f299e26 (diff) |
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.
Reported-by: Sven Neumann <s.neumann@raumfeld.com>
Reported-by: Michael Hirsch <m.hirsch@raumfeld.com>
Signed-off-by: Daniel Mack <daniel@caiaq.de>
Acked-by: Peter Ujfalusi <peter.ujfalusi@nokia.com>
Acked-by: Jarkko Nikula <jhnikula@gmail.com>
Acked-by: Liam Girdwood <lrg@slimlogic.co.uk>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/s3c24xx/s3c-i2s-v2.c')
-rw-r--r-- | sound/soc/s3c24xx/s3c-i2s-v2.c | 13 |
1 files changed, 8 insertions, 5 deletions
diff --git a/sound/soc/s3c24xx/s3c-i2s-v2.c b/sound/soc/s3c24xx/s3c-i2s-v2.c index c3fcb63cbf25..865f93143bf1 100644 --- a/sound/soc/s3c24xx/s3c-i2s-v2.c +++ b/sound/soc/s3c24xx/s3c-i2s-v2.c | |||
@@ -333,14 +333,17 @@ static int s3c_i2sv2_hw_params(struct snd_pcm_substream *substream, | |||
333 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 333 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
334 | struct snd_soc_dai_link *dai = rtd->dai; | 334 | struct snd_soc_dai_link *dai = rtd->dai; |
335 | struct s3c_i2sv2_info *i2s = to_info(dai->cpu_dai); | 335 | struct s3c_i2sv2_info *i2s = to_info(dai->cpu_dai); |
336 | struct s3c_dma_params *dma_data; | ||
336 | u32 iismod; | 337 | u32 iismod; |
337 | 338 | ||
338 | pr_debug("Entered %s\n", __func__); | 339 | pr_debug("Entered %s\n", __func__); |
339 | 340 | ||
340 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 341 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
341 | dai->cpu_dai->dma_data = i2s->dma_playback; | 342 | dma_data = i2s->dma_playback; |
342 | else | 343 | else |
343 | dai->cpu_dai->dma_data = i2s->dma_capture; | 344 | dma_data = i2s->dma_capture; |
345 | |||
346 | snd_soc_dai_set_dma_data(dai->cpu_dai, substream, dma_data); | ||
344 | 347 | ||
345 | /* Working copies of register */ | 348 | /* Working copies of register */ |
346 | iismod = readl(i2s->regs + S3C2412_IISMOD); | 349 | iismod = readl(i2s->regs + S3C2412_IISMOD); |
@@ -372,8 +375,8 @@ static int s3c2412_i2s_trigger(struct snd_pcm_substream *substream, int cmd, | |||
372 | int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE); | 375 | int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE); |
373 | unsigned long irqs; | 376 | unsigned long irqs; |
374 | int ret = 0; | 377 | int ret = 0; |
375 | int channel = ((struct s3c_dma_params *) | 378 | struct s3c_dma_params *dma_data = |
376 | rtd->dai->cpu_dai->dma_data)->channel; | 379 | snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream); |
377 | 380 | ||
378 | pr_debug("Entered %s\n", __func__); | 381 | pr_debug("Entered %s\n", __func__); |
379 | 382 | ||
@@ -409,7 +412,7 @@ static int s3c2412_i2s_trigger(struct snd_pcm_substream *substream, int cmd, | |||
409 | * of the auto reload mechanism of S3C24XX. | 412 | * of the auto reload mechanism of S3C24XX. |
410 | * This call won't bother S3C64XX. | 413 | * This call won't bother S3C64XX. |
411 | */ | 414 | */ |
412 | s3c2410_dma_ctrl(channel, S3C2410_DMAOP_STARTED); | 415 | s3c2410_dma_ctrl(dma_data->channel, S3C2410_DMAOP_STARTED); |
413 | 416 | ||
414 | break; | 417 | break; |
415 | 418 | ||