Skip to content

Commit 3c19a0a

Browse files
committed
Merge remote-tracking branch 'asoc/fix/dma' into asoc-linus
2 parents 6da37d4 + 6b9f3e6 commit 3c19a0a

File tree

1 file changed

+27
-11
lines changed

1 file changed

+27
-11
lines changed

sound/soc/soc-generic-dmaengine-pcm.c

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,20 @@ static void dmaengine_pcm_request_chan_of(struct dmaengine_pcm *pcm,
305305
}
306306
}
307307

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+
308322
/**
309323
* snd_dmaengine_pcm_register - Register a dmaengine based PCM device
310324
* @dev: The parent device for the PCM device
@@ -315,6 +329,7 @@ int snd_dmaengine_pcm_register(struct device *dev,
315329
const struct snd_dmaengine_pcm_config *config, unsigned int flags)
316330
{
317331
struct dmaengine_pcm *pcm;
332+
int ret;
318333

319334
pcm = kzalloc(sizeof(*pcm), GFP_KERNEL);
320335
if (!pcm)
@@ -326,11 +341,20 @@ int snd_dmaengine_pcm_register(struct device *dev,
326341
dmaengine_pcm_request_chan_of(pcm, dev);
327342

328343
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,
330345
&dmaengine_no_residue_pcm_platform);
331346
else
332-
return snd_soc_add_platform(dev, &pcm->platform,
347+
ret = snd_soc_add_platform(dev, &pcm->platform,
333348
&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;
334358
}
335359
EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_register);
336360

@@ -345,23 +369,15 @@ void snd_dmaengine_pcm_unregister(struct device *dev)
345369
{
346370
struct snd_soc_platform *platform;
347371
struct dmaengine_pcm *pcm;
348-
unsigned int i;
349372

350373
platform = snd_soc_lookup_platform(dev);
351374
if (!platform)
352375
return;
353376

354377
pcm = soc_platform_to_pcm(platform);
355378

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-
364379
snd_soc_remove_platform(platform);
380+
dmaengine_pcm_release_chan(pcm);
365381
kfree(pcm);
366382
}
367383
EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_unregister);

0 commit comments

Comments
 (0)