From 9167f260477b18ee9ffffc35fcf721f7255c444f Mon Sep 17 00:00:00 2001 From: bui duc phuc Date: Mon, 20 Jul 2026 13:41:31 +0700 Subject: [PATCH] ASoC: soc-generic-dmaengine: Handle DMA channel request failures correctly Currently any dma_request_chan() failure other than -EPROBE_DEFER is silently ignored, since a missing channel is expected for devices that only support one DMA direction. Improve the handling of these failures by: - reporting failures when a configured DMA channel cannot be requested; - failing probe if neither playback nor capture obtains a DMA channel, since the PCM device would be unusable. Devices that legitimately support only one DMA direction continue to work as before. Signed-off-by: bui duc phuc Link: https://patch.msgid.link/20260720064131.75156-1-phucduc.bui@gmail.com Signed-off-by: Mark Brown --- sound/soc/soc-generic-dmaengine-pcm.c | 28 +++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/sound/soc/soc-generic-dmaengine-pcm.c b/sound/soc/soc-generic-dmaengine-pcm.c index 467426d2b5e4..98ba9a836936 100644 --- a/sound/soc/soc-generic-dmaengine-pcm.c +++ b/sound/soc/soc-generic-dmaengine-pcm.c @@ -3,6 +3,7 @@ // Copyright (C) 2013, Analog Devices Inc. // Author: Lars-Peter Clausen +#include #include #include #include @@ -395,6 +396,27 @@ static int dmaengine_pcm_request_chan_of(struct dmaengine_pcm *pcm, */ if (PTR_ERR(chan) == -EPROBE_DEFER) return -EPROBE_DEFER; + + bool has_fw_node = dev->of_node || is_acpi_device_node(dev->fwnode); + bool name_exists_in_fw = false; + + if (has_fw_node) + name_exists_in_fw = device_property_match_string(dev, + "dma-names", + name) >= 0; + + if (has_fw_node && name_exists_in_fw) + dev_warn(dev, "DTS/ACPI DMA channel '%s' request failed (%ld)\n", + name, PTR_ERR(chan)); + + if (has_fw_node && !name_exists_in_fw) + dev_warn(dev, "DTS/ACPI name '%s' not found, legacy failed (%ld)\n", + name, PTR_ERR(chan)); + + if (!has_fw_node) + dev_warn(dev, "Legacy DMA channel '%s' request failed (%ld)\n", + name, PTR_ERR(chan)); + pcm->chan[i] = NULL; } else { pcm->chan[i] = chan; @@ -406,6 +428,12 @@ static int dmaengine_pcm_request_chan_of(struct dmaengine_pcm *pcm, if (pcm->flags & SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX) pcm->chan[1] = pcm->chan[0]; + if (!pcm->chan[0] && + !pcm->chan[1]) { + dev_err(dev, "no DMA channel found for either playback or capture\n"); + return -ENODEV; + } + return 0; }