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>
diff --git a/sound/soc/soc-generic-dmaengine-pcm.c b/sound/soc/soc-generic-dmaengine-pcm.c
index 5b70c55..585eaa6 100644
--- a/sound/soc/soc-generic-dmaengine-pcm.c
+++ b/sound/soc/soc-generic-dmaengine-pcm.c
@@ -287,16 +287,17 @@
 	[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)
 {
 	unsigned int i;
 	const char *name;
+	struct dma_chan *chan;
 
 	if ((pcm->flags & (SND_DMAENGINE_PCM_FLAG_NO_DT |
 			   SND_DMAENGINE_PCM_FLAG_CUSTOM_CHANNEL_NAME)) ||
 	    !dev->of_node)
-		return;
+		return 0;
 
 	if (config->dma_dev) {
 		/*
@@ -318,13 +319,22 @@
 			name = dmaengine_pcm_dma_channel_names[i];
 		if (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)
 			break;
 	}
 
 	if (pcm->flags & SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX)
 		pcm->chan[1] = pcm->chan[0];
+
+	return 0;
 }
 
 static void dmaengine_pcm_release_chan(struct dmaengine_pcm *pcm)
@@ -360,7 +370,9 @@
 	pcm->config = config;
 	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)
 		ret = snd_soc_add_platform(dev, &pcm->platform,