Commit 5eda87b8 authored by Stephen Warren's avatar Stephen Warren Committed by Mark Brown

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: default avatarStephen Warren <swarren@nvidia.com>
Acked-by: default avatarLars-Peter Clausen <lars@metafoo.de>
Signed-off-by: default avatarMark Brown <broonie@linaro.org>
parent d3ae8835
...@@ -287,16 +287,17 @@ static const char * const dmaengine_pcm_dma_channel_names[] = { ...@@ -287,16 +287,17 @@ static const char * const dmaengine_pcm_dma_channel_names[] = {
[SNDRV_PCM_STREAM_CAPTURE] = "rx", [SNDRV_PCM_STREAM_CAPTURE] = "rx",
}; };
static void dmaengine_pcm_request_chan_of(struct dmaengine_pcm *pcm, static int dmaengine_pcm_request_chan_of(struct dmaengine_pcm *pcm,
struct device *dev, const struct snd_dmaengine_pcm_config *config) struct device *dev, const struct snd_dmaengine_pcm_config *config)
{ {
unsigned int i; unsigned int i;
const char *name; const char *name;
struct dma_chan *chan;
if ((pcm->flags & (SND_DMAENGINE_PCM_FLAG_NO_DT | if ((pcm->flags & (SND_DMAENGINE_PCM_FLAG_NO_DT |
SND_DMAENGINE_PCM_FLAG_CUSTOM_CHANNEL_NAME)) || SND_DMAENGINE_PCM_FLAG_CUSTOM_CHANNEL_NAME)) ||
!dev->of_node) !dev->of_node)
return; return 0;
if (config->dma_dev) { if (config->dma_dev) {
/* /*
...@@ -318,13 +319,22 @@ static void dmaengine_pcm_request_chan_of(struct dmaengine_pcm *pcm, ...@@ -318,13 +319,22 @@ static void dmaengine_pcm_request_chan_of(struct dmaengine_pcm *pcm,
name = dmaengine_pcm_dma_channel_names[i]; name = dmaengine_pcm_dma_channel_names[i];
if (config->chan_names[i]) if (config->chan_names[i])
name = config->chan_names[i]; name = config->chan_names[i];
pcm->chan[i] = dma_request_slave_channel(dev, name); chan = dma_request_slave_channel_reason(dev, name);
if (IS_ERR(chan)) {
if (PTR_ERR(pcm->chan[i]) == -EPROBE_DEFER)
return -EPROBE_DEFER;
pcm->chan[i] = NULL;
} else {
pcm->chan[i] = chan;
}
if (pcm->flags & SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX) if (pcm->flags & SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX)
break; break;
} }
if (pcm->flags & SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX) if (pcm->flags & SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX)
pcm->chan[1] = pcm->chan[0]; pcm->chan[1] = pcm->chan[0];
return 0;
} }
static void dmaengine_pcm_release_chan(struct dmaengine_pcm *pcm) static void dmaengine_pcm_release_chan(struct dmaengine_pcm *pcm)
...@@ -360,7 +370,9 @@ int snd_dmaengine_pcm_register(struct device *dev, ...@@ -360,7 +370,9 @@ int snd_dmaengine_pcm_register(struct device *dev,
pcm->config = config; pcm->config = config;
pcm->flags = flags; pcm->flags = flags;
dmaengine_pcm_request_chan_of(pcm, dev, config); ret = dmaengine_pcm_request_chan_of(pcm, dev, config);
if (ret)
goto err_free_dma;
if (flags & SND_DMAENGINE_PCM_FLAG_NO_RESIDUE) if (flags & SND_DMAENGINE_PCM_FLAG_NO_RESIDUE)
ret = snd_soc_add_platform(dev, &pcm->platform, ret = snd_soc_add_platform(dev, &pcm->platform,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment