summaryrefslogtreecommitdiffstats
path: root/drivers/spi/spi-dw-dma.c
diff options
context:
space:
mode:
authorSerge Semin <Sergey.Semin@baikalelectronics.ru>2022-06-24 23:06:23 +0200
committerMark Brown <broonie@kernel.org>2022-06-27 14:24:33 +0200
commite95a1cd2cfe722dc8434db6de33958035853aa05 (patch)
tree82b0585218d4a6baa5ba1c6339081276da8f1f30 /drivers/spi/spi-dw-dma.c
parentspi: s3c64xx: constify fsd_spi_port_config (diff)
downloadlinux-e95a1cd2cfe722dc8434db6de33958035853aa05.tar.xz
linux-e95a1cd2cfe722dc8434db6de33958035853aa05.zip
spi: dw: Add deferred DMA-channels setup support
Currently if the source DMA device isn't ready to provide the channels capable of the SPI DMA transfers, the DW SSI controller will be registered with no DMA support. It isn't right since all what the driver needs to do is to postpone the probe procedure until the DMA device is ready. Let's fix that in the framework of the DWC SSI generic DMA implementation. First we need to use the dma_request_chan() method instead of the dma_request_slave_channel() function, because the later one is deprecated and most importantly doesn't return the failure cause but the NULL-pointer. Second we need to stop the DW SSI controller probe procedure if the -EPROBE_DEFER error is returned on the DMA initialization. The procedure will resume later when the channels are ready to be requested. Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> Link: https://lore.kernel.org/r/20220624210623.6383-1-Sergey.Semin@baikalelectronics.ru Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'drivers/spi/spi-dw-dma.c')
-rw-r--r--drivers/spi/spi-dw-dma.c25
1 files changed, 18 insertions, 7 deletions
diff --git a/drivers/spi/spi-dw-dma.c b/drivers/spi/spi-dw-dma.c
index 63e5260100ec..1322b8cce5b7 100644
--- a/drivers/spi/spi-dw-dma.c
+++ b/drivers/spi/spi-dw-dma.c
@@ -139,15 +139,20 @@ err_exit:
static int dw_spi_dma_init_generic(struct device *dev, struct dw_spi *dws)
{
- dws->rxchan = dma_request_slave_channel(dev, "rx");
- if (!dws->rxchan)
- return -ENODEV;
+ int ret;
- dws->txchan = dma_request_slave_channel(dev, "tx");
- if (!dws->txchan) {
- dma_release_channel(dws->rxchan);
+ dws->rxchan = dma_request_chan(dev, "rx");
+ if (IS_ERR(dws->rxchan)) {
+ ret = PTR_ERR(dws->rxchan);
dws->rxchan = NULL;
- return -ENODEV;
+ goto err_exit;
+ }
+
+ dws->txchan = dma_request_chan(dev, "tx");
+ if (IS_ERR(dws->txchan)) {
+ ret = PTR_ERR(dws->txchan);
+ dws->txchan = NULL;
+ goto free_rxchan;
}
dws->master->dma_rx = dws->rxchan;
@@ -160,6 +165,12 @@ static int dw_spi_dma_init_generic(struct device *dev, struct dw_spi *dws)
dw_spi_dma_sg_burst_init(dws);
return 0;
+
+free_rxchan:
+ dma_release_channel(dws->rxchan);
+ dws->rxchan = NULL;
+err_exit:
+ return ret;
}
static void dw_spi_dma_exit(struct dw_spi *dws)