Commit 3c19a0a2bdb31beed5da10caab1323aeb924cee3

Authored by Mark Brown

Merge remote-tracking branch 'asoc/fix/dma' into asoc-linus

Showing 1 changed file Side-by-side Diff

sound/soc/soc-generic-dmaengine-pcm.c
... ... @@ -305,6 +305,20 @@
305 305 }
306 306 }
307 307  
  308 +static void dmaengine_pcm_release_chan(struct dmaengine_pcm *pcm)
  309 +{
  310 + unsigned int i;
  311 +
  312 + for (i = SNDRV_PCM_STREAM_PLAYBACK; i <= SNDRV_PCM_STREAM_CAPTURE;
  313 + i++) {
  314 + if (!pcm->chan[i])
  315 + continue;
  316 + dma_release_channel(pcm->chan[i]);
  317 + if (pcm->flags & SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX)
  318 + break;
  319 + }
  320 +}
  321 +
308 322 /**
309 323 * snd_dmaengine_pcm_register - Register a dmaengine based PCM device
310 324 * @dev: The parent device for the PCM device
... ... @@ -315,6 +329,7 @@
315 329 const struct snd_dmaengine_pcm_config *config, unsigned int flags)
316 330 {
317 331 struct dmaengine_pcm *pcm;
  332 + int ret;
318 333  
319 334 pcm = kzalloc(sizeof(*pcm), GFP_KERNEL);
320 335 if (!pcm)
321 336  
322 337  
... ... @@ -326,11 +341,20 @@
326 341 dmaengine_pcm_request_chan_of(pcm, dev);
327 342  
328 343 if (flags & SND_DMAENGINE_PCM_FLAG_NO_RESIDUE)
329   - return snd_soc_add_platform(dev, &pcm->platform,
  344 + ret = snd_soc_add_platform(dev, &pcm->platform,
330 345 &dmaengine_no_residue_pcm_platform);
331 346 else
332   - return snd_soc_add_platform(dev, &pcm->platform,
  347 + ret = snd_soc_add_platform(dev, &pcm->platform,
333 348 &dmaengine_pcm_platform);
  349 + if (ret)
  350 + goto err_free_dma;
  351 +
  352 + return 0;
  353 +
  354 +err_free_dma:
  355 + dmaengine_pcm_release_chan(pcm);
  356 + kfree(pcm);
  357 + return ret;
334 358 }
335 359 EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_register);
336 360  
... ... @@ -345,7 +369,6 @@
345 369 {
346 370 struct snd_soc_platform *platform;
347 371 struct dmaengine_pcm *pcm;
348   - unsigned int i;
349 372  
350 373 platform = snd_soc_lookup_platform(dev);
351 374 if (!platform)
352 375  
... ... @@ -353,15 +376,8 @@
353 376  
354 377 pcm = soc_platform_to_pcm(platform);
355 378  
356   - for (i = SNDRV_PCM_STREAM_PLAYBACK; i <= SNDRV_PCM_STREAM_CAPTURE; i++) {
357   - if (pcm->chan[i]) {
358   - dma_release_channel(pcm->chan[i]);
359   - if (pcm->flags & SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX)
360   - break;
361   - }
362   - }
363   -
364 379 snd_soc_remove_platform(platform);
  380 + dmaengine_pcm_release_chan(pcm);
365 381 kfree(pcm);
366 382 }
367 383 EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_unregister);