diff options
author | Stephen Warren <swarren@nvidia.com> | 2013-12-10 13:11:02 -0500 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2013-12-11 06:15:05 -0500 |
commit | 5eda87b890f867b098e5566b5543642851e8b9c3 (patch) | |
tree | 5edf24b4a89f7f9893701dedd96dea7c083402ea /sound/soc/soc-generic-dmaengine-pcm.c | |
parent | d3ae8835301043ed84c8e78ecb06d5f0b0548f4a (diff) |
ASoC: dmaengine: support deferred probe for DMA channels
Enhance dmaengine_pcm_request_chan_of() to support deferred probe for
DMA channels, by using the new dma_request_slave_channel_or_err() API.
This prevents snd_dmaengine_pcm_register() from succeeding without
acquiring DMA channels due to the relevant DMA controller not yet being
registered.
Signed-off-by: Stephen Warren <swarren@nvidia.com>
Acked-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Mark Brown <broonie@linaro.org>
Diffstat (limited to 'sound/soc/soc-generic-dmaengine-pcm.c')
-rw-r--r-- | sound/soc/soc-generic-dmaengine-pcm.c | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/sound/soc/soc-generic-dmaengine-pcm.c b/sound/soc/soc-generic-dmaengine-pcm.c index 5b70c556fba3..585eaa69e8c3 100644 --- a/sound/soc/soc-generic-dmaengine-pcm.c +++ b/sound/soc/soc-generic-dmaengine-pcm.c | |||
@@ -287,16 +287,17 @@ static const char * const dmaengine_pcm_dma_channel_names[] = { | |||
287 | [SNDRV_PCM_STREAM_CAPTURE] = "rx", | 287 | [SNDRV_PCM_STREAM_CAPTURE] = "rx", |
288 | }; | 288 | }; |
289 | 289 | ||
290 | static void dmaengine_pcm_request_chan_of(struct dmaengine_pcm *pcm, | 290 | static int dmaengine_pcm_request_chan_of(struct dmaengine_pcm *pcm, |
291 | struct device *dev, const struct snd_dmaengine_pcm_config *config) | 291 | struct device *dev, const struct snd_dmaengine_pcm_config *config) |
292 | { | 292 | { |
293 | unsigned int i; | 293 | unsigned int i; |
294 | const char *name; | 294 | const char *name; |
295 | struct dma_chan *chan; | ||
295 | 296 | ||
296 | if ((pcm->flags & (SND_DMAENGINE_PCM_FLAG_NO_DT | | 297 | if ((pcm->flags & (SND_DMAENGINE_PCM_FLAG_NO_DT | |
297 | SND_DMAENGINE_PCM_FLAG_CUSTOM_CHANNEL_NAME)) || | 298 | SND_DMAENGINE_PCM_FLAG_CUSTOM_CHANNEL_NAME)) || |
298 | !dev->of_node) | 299 | !dev->of_node) |
299 | return; | 300 | return 0; |
300 | 301 | ||
301 | if (config->dma_dev) { | 302 | if (config->dma_dev) { |
302 | /* | 303 | /* |
@@ -318,13 +319,22 @@ static void dmaengine_pcm_request_chan_of(struct dmaengine_pcm *pcm, | |||
318 | name = dmaengine_pcm_dma_channel_names[i]; | 319 | name = dmaengine_pcm_dma_channel_names[i]; |
319 | if (config->chan_names[i]) | 320 | if (config->chan_names[i]) |
320 | name = config->chan_names[i]; | 321 | name = config->chan_names[i]; |
321 | pcm->chan[i] = dma_request_slave_channel(dev, name); | 322 | chan = dma_request_slave_channel_reason(dev, name); |
323 | if (IS_ERR(chan)) { | ||
324 | if (PTR_ERR(pcm->chan[i]) == -EPROBE_DEFER) | ||
325 | return -EPROBE_DEFER; | ||
326 | pcm->chan[i] = NULL; | ||
327 | } else { | ||
328 | pcm->chan[i] = chan; | ||
329 | } | ||
322 | if (pcm->flags & SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX) | 330 | if (pcm->flags & SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX) |
323 | break; | 331 | break; |
324 | } | 332 | } |
325 | 333 | ||
326 | if (pcm->flags & SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX) | 334 | if (pcm->flags & SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX) |
327 | pcm->chan[1] = pcm->chan[0]; | 335 | pcm->chan[1] = pcm->chan[0]; |
336 | |||
337 | return 0; | ||
328 | } | 338 | } |
329 | 339 | ||
330 | static void dmaengine_pcm_release_chan(struct dmaengine_pcm *pcm) | 340 | static void dmaengine_pcm_release_chan(struct dmaengine_pcm *pcm) |
@@ -360,7 +370,9 @@ int snd_dmaengine_pcm_register(struct device *dev, | |||
360 | pcm->config = config; | 370 | pcm->config = config; |
361 | pcm->flags = flags; | 371 | pcm->flags = flags; |
362 | 372 | ||
363 | dmaengine_pcm_request_chan_of(pcm, dev, config); | 373 | ret = dmaengine_pcm_request_chan_of(pcm, dev, config); |
374 | if (ret) | ||
375 | goto err_free_dma; | ||
364 | 376 | ||
365 | if (flags & SND_DMAENGINE_PCM_FLAG_NO_RESIDUE) | 377 | if (flags & SND_DMAENGINE_PCM_FLAG_NO_RESIDUE) |
366 | ret = snd_soc_add_platform(dev, &pcm->platform, | 378 | ret = snd_soc_add_platform(dev, &pcm->platform, |