@@ -305,6 +305,20 @@ static void dmaengine_pcm_request_chan_of(struct dmaengine_pcm *pcm,
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 @@ int snd_dmaengine_pcm_register(struct device *dev,
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 )
@@ -326,11 +341,20 @@ int snd_dmaengine_pcm_register(struct device *dev,
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,23 +369,15 @@ void snd_dmaengine_pcm_unregister(struct device *dev)
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
return ;
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 );
0 commit comments