dmaengine: kill off dma_slave_config->slave_id
Subsystems (23)
v2 cover dmaengine: kill off dma_slave_config->slave_id
From: Arnd Bergmann <[email protected]>
I recently came across some new uses of the 'slave_id' field that I had (almost) removed a few years ago. There are no legitimate uses of this field in the kernel, only a few stale references and two drivers that abuse the field as a side-channel between the dmaengine driver and its client.
Let's change the xilinx and qualcomm drivers to use the documented side-channel (peripheral_data) instead, and remove the remnants of it to prevent new users from coming in.
I think I got all the necessary Acks on v1 already, so if there are no further concerns, please merge this through the dmaengine tree for v5.17, or pull from
git://git.kernel.org/pub/scm/linux/kernel/git/arnd/asm-generic.git tags/dma-slave-id-removal
Arnd
Arnd Bergmann (13):
ASoC: tegra20-spdif: stop setting slave_id
ASoC: dai_dma: remove slave_id field
spi: pic32: stop setting dma_config->slave_id
mmc: bcm2835: stop setting chan_config->slave_id
dmaengine: shdma: remove legacy slave_id parsing
dmaengine: pxa/mmp: stop referencing config->slave_id
dmaengine: sprd: stop referencing config->slave_id
dmaengine: qcom-adm: stop abusing slave_id config
dmaengine: xilinx_dpdma: stop using slave_id field
dmaengine: tegra20-apb: stop checking config->slave_id
dmaengine: remove slave_id config field
---
Changes in v2:
- drop obsolete drivers/staging/patch
- split tegra change into a separate patch
- improve some patch descriptions.
drivers/dma/mmp_pdma.c | 6 --- drivers/dma/pxa_dma.c | 7 ---- drivers/dma/qcom/qcom_adm.c | 56 ++++++++++++++++++++++---- drivers/dma/sh/shdma-base.c | 8 ---- drivers/dma/sprd-dma.c | 3 -- drivers/dma/tegra20-apb-dma.c | 6 --- drivers/dma/xilinx/xilinx_dpdma.c | 17 +++++--- drivers/gpu/drm/xlnx/zynqmp_disp.c | 9 ++++- drivers/mmc/host/bcm2835.c | 2 - drivers/mtd/nand/raw/qcom_nandc.c | 14 ++++++- drivers/spi/spi-pic32.c | 2 - drivers/tty/serial/msm_serial.c | 15 ++++++- include/linux/dma/qcom_adm.h | 12 ++++++ include/linux/dma/xilinx_dpdma.h | 11 +++++ include/linux/dmaengine.h | 4 -- include/linux/platform_data/asoc-s3c.h | 6 --- include/sound/dmaengine_pcm.h | 4 -- sound/core/pcm_dmaengine.c | 26 +----------- sound/soc/tegra/tegra20_spdif.c | 1 - 27 files changed, 134 insertions(+), 146 deletions(-) create mode 100644 include/linux/dma/qcom_adm.h create mode 100644 include/linux/dma/xilinx_dpdma.h
Signature · 39 lines
2.29.2 Cc: Andy Gross <[email protected]> Cc: Andy Shevchenko <[email protected]> Cc: Arnd Bergmann <[email protected]> Cc: Baolin Wang <[email protected]> Cc: Bjorn Andersson <[email protected]> Cc: Chunyan Zhang <[email protected]> Cc: Greg Kroah-Hartman <[email protected]> Cc: Hyun Kwon <[email protected]> Cc: Jaroslav Kysela <[email protected]> Cc: Jon Hunter <[email protected]> Cc: Lars-Peter Clausen <[email protected]> Cc: Laurent Pinchart <[email protected]> Cc: Laxman Dewangan <[email protected]> Cc: Manivannan Sadhasivam <[email protected]> Cc: Mark Brown <[email protected]> Cc: Michal Simek <[email protected]> Cc: Nicolas Saenz Julienne <[email protected]> Cc: Orson Zhai <[email protected]> Cc: Robert Jarzmik <[email protected]> Cc: Scott Branden <[email protected]> Cc: Takashi Iwai <[email protected]> Cc: Thierry Reding <[email protected]> Cc: Vinod Koul <[email protected]> Cc: [email protected] Cc: [email protected] Cc: [email protected] Cc: [email protected] Cc: [email protected] Cc: [email protected] Cc: [email protected] Cc: [email protected] Cc: [email protected] Cc: [email protected] Cc: [email protected] Cc: [email protected] Cc: [email protected] Cc: [email protected]
PATCH v2 1/11 ASoC: tegra20-spdif: stop setting slave_id
From: Arnd Bergmann <[email protected]>
The DMA resource is never set up anywhere, and passing this as slave_id has not been the proper procedure in a long time.
As a preparation for removing all slave_id references from the ALSA code, remove this one.
According to Dmitry Osipenko, this driver has never been used and the mechanism for configuring DMA would not work as it is implemented, so this part will get rewritten when the driver gets put into use again in the future.
--- sound/soc/tegra/tegra20_spdif.c | 1 - 1 file changed, 1 deletion(-)
sound/soc/tegra/tegra20_spdif.c +0 -1
@@ -284,7 +284,6 @@ static int tegra20_spdif_platform_probe(struct platform_device *pdev) spdif->playback_dma_data.addr = mem->start +TEGRA20_SPDIF_DATA_OUT ; spdif->playback_dma_data.addr_width =DMA_SLAVE_BUSWIDTH_4_BYTES ; spdif->playback_dma_data.maxburst =4 ; - spdif->playback_dma_data.slave_id = dmareq->start;pm_runtime_enable (&pdev->dev);
Signature · 1 line
2.29.2
Re: [PATCH v2 01/11] ASoC: tegra20-spdif: stop setting slave_id
23.11.2021 01:21, Arnd Bergmann пишет:
Quoted 24 lines
From: Arnd Bergmann <[email protected]>
The DMA resource is never set up anywhere, and passing this as
slave_idhas not been the proper procedure in a long time.As a preparation for removing all
slave_idreferences from the ALSA code, remove this one.According to Dmitry Osipenko, this driver has never been used and the mechanism for configuring DMA would not work as it is implemented, so this part will get rewritten when the driver gets put into use again in the future.
Signed-off-by Arnd Bergmann <[email protected]>--- sound/soc/tegra/tegra20_spdif.c | 1 - 1 file changed, 1 deletion(-)sound/soc/tegra/tegra20_spdif.c +0
-0
sound/soc/tegra/tegra20_spdif.c static int tegra20_spdif_platform_probe(struct platform_device *pdev) · line 289
Quoted 7 lines
sound/soc/tegra/tegra20_spdif.c +0
-1@@ -284,7 +284,6 @@ static int tegra20_spdif_platform_probe(struct platform_device *pdev) spdif->playback_dma_data.addr = mem->start +TEGRA20_SPDIF_DATA_OUT ; spdif->playback_dma_data.addr_width =DMA_SLAVE_BUSWIDTH_4_BYTES ; spdif->playback_dma_data.maxburst =4 ; - spdif->playback_dma_data.slave_id = dmareq->start;pm_runtime_enable (&pdev->dev);
Thanks, Arnd!
The commit message is correct, however you could remove even more code here. But there is no need to make a v3 just because this patch because I already prepared patchset that revives this S/PDIF driver and enables HDMI audio on Tegra20. I'll take care of cleaning up the whole code of this driver.
(quoted diff) +0 -0
b/sound/soc/tegra/tegra20_spdif.c
index 7751575cd6d6..1c3385da6f82 100644
sound/soc/tegra/tegra20_spdif.c +0 -0
@@ -251,7 +251,7 @@ static const struct regmap_config
tegra20_spdif_regmap_config = {
static int tegra20_spdif_platform_probe(struct platform_device *pdev) {
struct tegra20_spdif *spdif;
- struct resource *mem, *dmareq;
+ struct resource *mem;
void __iomem *regs;
int ret;
@@ -273,12 +273,6 @@ static int tegra20_spdif_platform_probe(struct platform_device *pdev)
if (IS_ERR(regs))
return PTR_ERR(regs);
- dmareq = platform_get_resource(pdev, IORESOURCE_DMA, 0);
- if (!dmareq) {
- dev_err(&pdev->dev, "No DMA resource\n");
- return -ENODEV;
- }
-
spdif->regmap = devm_regmap_init_mmio(&pdev->dev, regs,
&tegra20_spdif_regmap_config);
if (IS_ERR(spdif->regmap)) {
@@ -290,7 +284,6 @@ static int tegra20_spdif_platform_probe(struct platform_device *pdev)
spdif->playback_dma_data.addr = mem->start + TEGRA20_SPDIF_DATA_OUT; spdif->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; spdif->playback_dma_data.maxburst = 4;
- spdif->playback_dma_data.slave_id = dmareq->start;
pm_runtime_enable(&pdev->dev);
Re: [PATCH v2 01/11] ASoC: tegra20-spdif: stop setting slave_id
Quoted 7 lines · Dmitry Osipenko
23.11.2021 01:21, Arnd Bergmann пишет:
The commit message is correct, however you could remove even more code here. But there is no need to make a v3 just because this patch because I already prepared patchset that revives this S/PDIF driver and enables HDMI audio on Tegra20. I'll take care of cleaning up the whole code of this driver.
Ok, perfect, thanks for taking a closer look as well.
Review
Quoted 7 lines
(quoted diff) +0
-6- dmareq = platform_get_resource(pdev, IORESOURCE_DMA, 0); - if (!dmareq) { - dev_err(&pdev->dev, "No DMA resource\n"); - return -ENODEV; - } -
Right, I think I considered doing this at some point as well, not sure why I left it in for the version I posted. Passing the IORESOURCE_DMA values is clearly wrong by itself and needs to be removed, though it's not obvious what the correct way of requesting the DMA channel is for this driver either, without a DT binding or users.
Arnd
Re: [PATCH v2 01/11] ASoC: tegra20-spdif: stop setting slave_id
24.11.2021 19:47, Arnd Bergmann пишет:
Quoted 19 lines · Dmitry Osipenko
Quoted 7 lines
23.11.2021 01:21, Arnd Bergmann пишет:
The commit message is correct, however you could remove even more code here. But there is no need to make a v3 just because this patch because I already prepared patchset that revives this S/PDIF driver and enables HDMI audio on Tegra20. I'll take care of cleaning up the whole code of this driver.
Ok, perfect, thanks for taking a closer look as well.
Review
Quoted 7 lines
(quoted diff) +0
-6- dmareq = platform_get_resource(pdev, IORESOURCE_DMA, 0); - if (!dmareq) { - dev_err(&pdev->dev, "No DMA resource\n"); - return -ENODEV; - } -
Quoted 5 lines
Right, I think I considered doing this at some point as well, not sure why I left it in for the version I posted. Passing the
IORESOURCE_DMAvalues is clearly wrong by itself and needs to be removed, though it's not obvious what the correct way of requesting the DMA channel is for this driver either, without a DT binding or users.
Yes, it's indeed not obvious.
Re: [PATCH v2 01/11] ASoC: tegra20-spdif: stop setting slave_id
In reply to Arnd Bergmann23.11.2021 01:21, Arnd Bergmann пишет:
Quoted 24 lines
From: Arnd Bergmann <[email protected]>
The DMA resource is never set up anywhere, and passing this as
slave_idhas not been the proper procedure in a long time.As a preparation for removing all
slave_idreferences from the ALSA code, remove this one.According to Dmitry Osipenko, this driver has never been used and the mechanism for configuring DMA would not work as it is implemented, so this part will get rewritten when the driver gets put into use again in the future.
Signed-off-by Arnd Bergmann <[email protected]>--- sound/soc/tegra/tegra20_spdif.c | 1 - 1 file changed, 1 deletion(-)sound/soc/tegra/tegra20_spdif.c +0
-0
sound/soc/tegra/tegra20_spdif.c static int tegra20_spdif_platform_probe(struct platform_device *pdev) · line 289
Quoted 7 lines
sound/soc/tegra/tegra20_spdif.c +0
-1@@ -284,7 +284,6 @@ static int tegra20_spdif_platform_probe(struct platform_device *pdev) spdif->playback_dma_data.addr = mem->start +TEGRA20_SPDIF_DATA_OUT ; spdif->playback_dma_data.addr_width =DMA_SLAVE_BUSWIDTH_4_BYTES ; spdif->playback_dma_data.maxburst =4 ; - spdif->playback_dma_data.slave_id = dmareq->start;pm_runtime_enable (&pdev->dev);
PATCH v2 2/11 ASoC: dai_dma: remove slave_id field
In reply to Arnd BergmannFrom: Arnd Bergmann <[email protected]>
This field is no longer set from any driver now, so remove the last references as well.
--- include/sound/dmaengine_pcm.h | 2 -- sound/core/pcm_dmaengine.c | 5 ++--- 2 files changed, 2 insertions(+), 5 deletions(-)
include/sound/dmaengine_pcm.h +0 -2
@@ -58,7 +58,6 @@ struct dma_chan *snd_dmaengine_pcm_get_chan(struct snd_pcm_substream *substream)* @maxburst: Maximum number of words(note: words, as in units of the * src_addr_width member, not bytes) that can be send to or received from the * DAI in one burst. -* @slave_id: Slave requester id for the DMA channel. * @filter_data: Custom DMA channel filter data, this will usually be used when * requesting the DMA channel. * @chan_name: Custom channel name to use when requesting DMA channel.
@@ -72,7 +71,6 @@ struct snd_dmaengine_dai_dma_data {dma_addr_t addr;enum dma_slave_buswidth addr_width;u32 maxburst; -unsigned int slave_id;void *filter_data;const char *chan_name;unsigned int fifo_size;
sound/core/pcm_dmaengine.c +2 -3
@@ -91,8 +91,8 @@ EXPORT_SYMBOL_GPL(snd_hwparams_to_dma_slave_config);* @dma_data: DAI DMA data * @slave_config: DMA slave configuration * -* Initializes the {dst,src}_addr, {dst,src}_maxburst, {dst,src}_addr_width and -* slave_id fields of the DMA slave config from the same fields of the DAI DMA +* Initializes the {dst,src}_addr, {dst,src}_maxburst, {dst,src}_addr_width +* fields of the DMA slave config from the same fields of the DAI DMA * data struct. The src and dst fields will be initialized depending on the * direction of the substream. If the substream is a playback stream the dst * fields will be initialized, if it is a capture stream the src fields will be
@@ -124,7 +124,6 @@ void snd_dmaengine_pcm_set_config_from_dai_data( slave_config->src_addr_width = dma_data->addr_width; } - slave_config->slave_id = dma_data->slave_id; slave_config->peripheral_config = dma_data->peripheral_config; slave_config->peripheral_size = dma_data->peripheral_size; }
Signature · 1 line
2.29.2
PATCH v2 3/11 spi: pic32: stop setting dma_config->slave_id
In reply to Arnd BergmannFrom: Arnd Bergmann <[email protected]>
Setting slave_id makes no sense with DT based probing, and should eventually get removed entirely. Address this driver by no longer setting the field here.
I could not find which DMA driver is used on PIC32, if it's in the tree at all, but none of the obvious ones even care about slave_id any more.
--- drivers/spi/spi-pic32.c | 2 -- 1 file changed, 2 deletions(-)
drivers/spi/spi-pic32.c +0 -2
@@ -370,7 +370,6 @@ static int pic32_spi_dma_config(struct pic32_spi *pic32s, u32 dma_width) cfg.src_addr_width = dma_width; cfg.dst_addr_width = dma_width;/* tx channel */ - cfg.slave_id = pic32s->tx_irq; cfg.direction =DMA_MEM_TO_DEV ; ret =dmaengine_slave_config (master->dma_tx, &cfg);if (ret) {
@@ -378,7 +377,6 @@ static int pic32_spi_dma_config(struct pic32_spi *pic32s, u32 dma_width)return ret; }/* rx channel */ - cfg.slave_id = pic32s->rx_irq; cfg.direction =DMA_DEV_TO_MEM ; ret =dmaengine_slave_config (master->dma_rx, &cfg);if (ret)
Signature · 1 line
2.29.2
PATCH v2 4/11 mmc: bcm2835: stop setting chan_config->slave_id
In reply to Arnd BergmannFrom: Arnd Bergmann <[email protected]>
The field is not interpreted by the DMA engine driver, as all the data is passed from devicetree instead. Remove the assignment so the field can eventually be deleted.
--- drivers/mmc/host/bcm2835.c | 2 -- 1 file changed, 2 deletions(-)
drivers/mmc/host/bcm2835.c +0 -2
@@ -1293,14 +1293,12 @@ static int bcm2835_add_host(struct bcm2835_host *host) host->dma_cfg_tx.src_addr_width =DMA_SLAVE_BUSWIDTH_4_BYTES ; host->dma_cfg_tx.dst_addr_width =DMA_SLAVE_BUSWIDTH_4_BYTES ; - host->dma_cfg_tx.slave_id =13 ;/* DREQ channel */ host->dma_cfg_tx.direction =DMA_MEM_TO_DEV ; host->dma_cfg_tx.src_addr =0 ; host->dma_cfg_tx.dst_addr = host->phys_addr +SDDATA ; host->dma_cfg_rx.src_addr_width =DMA_SLAVE_BUSWIDTH_4_BYTES ; host->dma_cfg_rx.dst_addr_width =DMA_SLAVE_BUSWIDTH_4_BYTES ; - host->dma_cfg_rx.slave_id =13 ;/* DREQ channel */ host->dma_cfg_rx.direction =DMA_DEV_TO_MEM ; host->dma_cfg_rx.src_addr = host->phys_addr +SDDATA ; host->dma_cfg_rx.dst_addr =0 ;
Signature · 1 line
2.29.2
Re: [PATCH v2 04/11] mmc: bcm2835: stop setting chan_config->slave_id
Quoted 9 lines · Arnd Bergmann
From: Arnd Bergmann <[email protected]>
The field is not interpreted by the DMA engine driver, as all the data is passed from devicetree instead. Remove the assignment so the field can eventually be deleted.
Reviewed-by Nicolas Saenz Julienne <[email protected]>Signed-off-by Arnd Bergmann <[email protected]>
I think I acked the previous version, but nevermind:
Kind regards
Uffe
Quoted 26 lines
--- drivers/mmc/host/bcm2835.c | 2 -- 1 file changed, 2 deletions(-)drivers/mmc/host/bcm2835.c +0
-3@@ -1293,14 +1293,12 @@ static int bcm2835_add_host(struct bcm2835_host *host) host->dma_cfg_tx.src_addr_width =DMA_SLAVE_BUSWIDTH_4_BYTES ; host->dma_cfg_tx.dst_addr_width =DMA_SLAVE_BUSWIDTH_4_BYTES ; - host->dma_cfg_tx.slave_id =13 ;/* DREQ channel */ host->dma_cfg_tx.direction =DMA_MEM_TO_DEV ; host->dma_cfg_tx.src_addr =0 ; host->dma_cfg_tx.dst_addr = host->phys_addr +SDDATA ; host->dma_cfg_rx.src_addr_width =DMA_SLAVE_BUSWIDTH_4_BYTES ; host->dma_cfg_rx.dst_addr_width =DMA_SLAVE_BUSWIDTH_4_BYTES ; - host->dma_cfg_rx.slave_id =13 ;/* DREQ channel */ host->dma_cfg_rx.direction =DMA_DEV_TO_MEM ; host->dma_cfg_rx.src_addr = host->phys_addr +SDDATA ; host->dma_cfg_rx.dst_addr =0 ; --2.29.2
PATCH v2 5/11 dmaengine: shdma: remove legacy slave_id parsing
In reply to Arnd BergmannFrom: Arnd Bergmann <[email protected]>
The slave device is picked through either devicetree or a filter function, and any remaining out-of-tree drivers would have warned about this usage since 2015.
Stop interpreting the field finally so it can be removed from the interface.
--- drivers/dma/sh/shdma-base.c | 8 -------- 1 file changed, 8 deletions(-)
drivers/dma/sh/shdma-base.c +0 -8
@@ -786,14 +786,6 @@ static int shdma_config(struct dma_chan *chan,if (!config)return -EINVAL ; -/* -* overriding the slave_id through dma_slave_config is deprecated, -* but possibly some out-of-tree drivers still do it. -*/ -if (WARN_ON_ONCE (config->slave_id && - config->slave_id != schan->real_slave_id)) - schan->real_slave_id = config->slave_id; -/* * We could lock this, but you shouldn't be configuring the * channel, while using it...
Signature · 1 line
2.29.2
PATCH v2 6/11 dmaengine: pxa/mmp: stop referencing config->slave_id
In reply to Arnd BergmannFrom: Arnd Bergmann <[email protected]>
The last driver referencing the slave_id on Marvell PXA and MMP platforms was the SPI driver, but this stopped doing so a long time ago, so the TODO from the earlier patch can no be removed.
--- drivers/dma/mmp_pdma.c | 6 ------ drivers/dma/pxa_dma.c | 7 ------- 2 files changed, 13 deletions(-)
drivers/dma/mmp_pdma.c +0 -6
@@ -727,12 +727,6 @@ static int mmp_pdma_config_write(struct dma_chan *dchan, chan->dir = direction; chan->dev_addr = addr; -/* FIXME: drivers should be ported over to use the filter -* function. Once that's done, the following two lines can -* be removed. -*/ -if (cfg->slave_id) - chan->drcmr = cfg->slave_id;return 0 ; }
drivers/dma/pxa_dma.c +0 -7
@@ -909,13 +909,6 @@ static void pxad_get_config(struct pxad_chan *chan, *dcmd |=PXA_DCMD_BURST16 ; else if (maxburst == 32) *dcmd |= PXA_DCMD_BURST32; - - /* FIXME: drivers should be ported over to use the filter - * function. Once that's done, the following two lines can - * be removed. - */ - if (chan->cfg.slave_id) - chan->drcmr = chan->cfg.slave_id; } static struct dma_async_tx_descriptor *
Signature · 1 line
2.29.2
PATCH v2 7/11 dmaengine: sprd: stop referencing config->slave_id
In reply to Arnd BergmannFrom: Arnd Bergmann <[email protected]>
It appears that the code that reads the slave_id from the channel config was copied incorrectly from other drivers. Nothing ever sets this field on platforms that use this driver, so remove the reference.
--- drivers/dma/sprd-dma.c | 3 --- 1 file changed, 3 deletions(-)
drivers/dma/sprd-dma.c +0 -3
@@ -795,9 +795,6 @@ static int sprd_dma_fill_desc(struct dma_chan *chan,return dst_datawidth; } -if (slave_cfg->slave_id) - schan->dev_id = slave_cfg->slave_id; - hw->cfg =SPRD_DMA_DONOT_WAIT_BDONE <<SPRD_DMA_WAIT_BDONE_OFFSET ;/*
Signature · 1 line
2.29.2
PATCH v2 8/11 dmaengine: qcom-adm: stop abusing slave_id config
In reply to Arnd BergmannFrom: Arnd Bergmann <[email protected]>
The slave_id was previously used to pick one DMA slave instead of another, but this is now done through the DMA descriptors in device tree.
For the qcom_adm driver, the configuration is documented in the DT binding to contain a tuple of device identifier and a "crci" field, but the implementation ends up using only a single cell for identifying the slave, with the crci getting passed in nonstandard properties of the device, and passed through the dma driver using the old slave_id field. Part of the problem apparently is that the nand driver ends up using only a single DMA request ID, but requires distinct values for "crci" depending on the type of transfer.
Change both the dmaengine driver and the two slave drivers to allow the documented binding to work in addition to the ad-hoc passing of crci values. In order to no longer abuse the slave_id field, pass the data using the "peripheral_config" mechanism instead.
--- drivers/dma/qcom/qcom_adm.c | 56 +++++++++++++++++++++++++++---- drivers/mtd/nand/raw/qcom_nandc.c | 14 ++++++-- drivers/tty/serial/msm_serial.c | 15 +++++++-- include/linux/dma/qcom_adm.h | 12 +++++++ 4 files changed, 86 insertions(+), 11 deletions(-) create mode 100644 include/linux/dma/qcom_adm.h
drivers/dma/qcom/qcom_adm.c +49 -7
@@ -8,6 +8,7 @@#include <linux/device.h> #include <linux/dmaengine.h> #include <linux/dma-mapping.h> +#include <linux/dma/qcom_adm.h> #include <linux/init.h> #include <linux/interrupt.h> #include <linux/io.h>
@@ -140,6 +141,8 @@ struct adm_chan {struct adm_async_desc *curr_txd;struct dma_slave_config slave; +u32 crci; +u32 mux;struct list_head node;int error;
@@ -379,8 +382,8 @@ static struct dma_async_tx_descriptor *adm_prep_slave_sg(struct dma_chan *chan,return ERR_PTR (-EINVAL ); } - crci = achan->slave.slave_id &0xf ; -if (!crci || achan->slave.slave_id >0x1f ) { + crci = achan->crci &0xf ; +if (!crci || achan->crci >0x1f ) {dev_err (adev->dev,"invalid crci value\n" );return ERR_PTR (-EINVAL ); }
@@ -403,9 +406,7 @@ static struct dma_async_tx_descriptor *adm_prep_slave_sg(struct dma_chan *chan,if (!async_desc)return ERR_PTR (-ENOMEM ); -if (crci) - async_desc->mux = achan->slave.slave_id &ADM_CRCI_MUX_SEL ? -ADM_CRCI_CTL_MUX_SEL :0 ; + async_desc->mux = achan->mux ?ADM_CRCI_CTL_MUX_SEL :0 ; async_desc->crci = crci; async_desc->blk_size = blk_size; async_desc->dma_len = single_count * sizeof(struct adm_desc_hw_single) +
@@ -488,10 +489,13 @@ static int adm_terminate_all(struct dma_chan *chan)static int adm_slave_config (struct dma_chan *chan,struct dma_slave_config *cfg) {struct adm_chan *achan =to_adm_chan (chan); +struct qcom_adm_peripheral_config *config = cfg->peripheral_config;unsigned long flag;spin_lock_irqsave (&achan->vc.lock, flag);memcpy (&achan->slave, cfg,sizeof (struct dma_slave_config )); +if (cfg->peripheral_size ==sizeof (config)) + achan->crci = config->crci;spin_unlock_irqrestore (&achan->vc.lock, flag);return 0 ;
@@ -694,6 +698,45 @@ static void adm_channel_init(struct adm_device *adev, struct adm_chan *achan, achan->vc.desc_free = adm_dma_free_desc; } +/** +* adm_dma_xlate +* @dma_spec: pointer to DMA specifier as found in the device tree +* @ofdma: pointer to DMA controller data +* +* This can use either 1-cell or 2-cell formats, the first cell +* identifies the slave device, while the optional second cell +* contains the crci value. +* +* Returns pointer to appropriate dma channel on success or NULL on error. +*/ +struct dma_chan *adm_dma_xlate (struct of_phandle_args *dma_spec, +struct of_dma *ofdma) +{ +struct dma_device *dev = ofdma->of_dma_data; +struct dma_chan *chan, *candidate =NULL ; +struct adm_chan *achan; + +if (!dev || dma_spec->args_count >2 ) +return NULL ; + +list_for_each_entry (chan, &dev->channels, device_node) +if (chan->chan_id == dma_spec->args[0 ]) { + candidate = chan; +break ; + } + +if (!candidate) +return NULL ; + + achan =to_adm_chan (candidate); +if (dma_spec->args_count ==2 ) + achan->crci = dma_spec->args[1 ]; +else + achan->crci =0 ; + +return dma_get_slave_channel (candidate); +} +static int adm_dma_probe (struct platform_device *pdev) {struct adm_device *adev;
@@ -838,8 +881,7 @@ static int adm_dma_probe(struct platform_device *pdev) goto err_disable_clks; } - ret =of_dma_controller_register (pdev->dev.of_node, - of_dma_xlate_by_chan_id, + ret =of_dma_controller_register (pdev->dev.of_node, adm_dma_xlate, &adev->common);if (ret) goto err_unregister_dma;
drivers/mtd/nand/raw/qcom_nandc.c +12 -2
@@ -6,6 +6,7 @@#include <linux/clk.h> #include <linux/slab.h> #include <linux/bitops.h> +#include <linux/dma/qcom_adm.h> #include <linux/dma-mapping.h> #include <linux/dmaengine.h> #include <linux/module.h>
@@ -952,6 +953,7 @@ static int prep_adm_dma_desc(struct qcom_nand_controller *nandc, bool read,struct dma_async_tx_descriptor *dma_desc;struct scatterlist *sgl;struct dma_slave_config slave_conf; +struct qcom_adm_peripheral_config periph_conf = {};enum dma_transfer_direction dir_eng;int ret;
@@ -983,11 +985,19 @@ static int prep_adm_dma_desc(struct qcom_nand_controller *nandc, bool read,if (read) { slave_conf.src_maxburst =16 ; slave_conf.src_addr = nandc->base_dma + reg_off; - slave_conf.slave_id = nandc->data_crci; +if (nandc->data_crci) { + periph_conf.crci = nandc->data_crci; + slave_conf.peripheral_config = &periph_conf; + slave_conf.peripheral_size =sizeof (periph_conf); + } }else { slave_conf.dst_maxburst =16 ; slave_conf.dst_addr = nandc->base_dma + reg_off; - slave_conf.slave_id = nandc->cmd_crci; +if (nandc->cmd_crci) { + periph_conf.crci = nandc->cmd_crci; + slave_conf.peripheral_config = &periph_conf; + slave_conf.peripheral_size =sizeof (periph_conf); + } } ret =dmaengine_slave_config (nandc->chan, &slave_conf);
drivers/tty/serial/msm_serial.c +13 -2
@@ -9,6 +9,7 @@#include <linux/kernel.h> #include <linux/atomic.h> +#include <linux/dma/qcom_adm.h> #include <linux/dma-mapping.h> #include <linux/dmaengine.h> #include <linux/module.h>
@@ -290,6 +291,7 @@ static void msm_request_tx_dma(struct msm_port *msm_port, resource_size_t base) {struct device *dev = msm_port->uart.dev;struct dma_slave_config conf; +struct qcom_adm_peripheral_config periph_conf = {};struct msm_dma *dma;u32 crci =0 ;int ret;
@@ -308,7 +310,11 @@ static void msm_request_tx_dma(struct msm_port *msm_port, resource_size_t base) conf.device_fc = true; conf.dst_addr = base +UARTDM_TF ; conf.dst_maxburst =UARTDM_BURST_SIZE ; - conf.slave_id = crci; +if (crci) { + conf.peripheral_config = &periph_conf; + conf.peripheral_size =sizeof (periph_conf); + periph_conf.crci = crci; + } ret =dmaengine_slave_config (dma->chan, &conf);if (ret)
@@ -333,6 +339,7 @@ static void msm_request_rx_dma(struct msm_port *msm_port, resource_size_t base) {struct device *dev = msm_port->uart.dev;struct dma_slave_config conf; +struct qcom_adm_peripheral_config periph_conf = {};struct msm_dma *dma;u32 crci =0 ;int ret;
@@ -355,7 +362,11 @@ static void msm_request_rx_dma(struct msm_port *msm_port, resource_size_t base) conf.device_fc = true; conf.src_addr = base +UARTDM_RF ; conf.src_maxburst =UARTDM_BURST_SIZE ; - conf.slave_id = crci; +if (crci) { + conf.peripheral_config = &periph_conf; + conf.peripheral_size =sizeof (periph_conf); + periph_conf.crci = crci; + } ret =dmaengine_slave_config (dma->chan, &conf);if (ret)
include/linux/dma/qcom_adm.h new file +12 -0
@@ -0,0 +1,12 @@ +// SPDX-License-Identifier: GPL-2.0-only +#ifndef __LINUX_DMA_QCOM_ADM_H +#define __LINUX_DMA_QCOM_ADM_H + +#include <linux/types.h> + +struct qcom_adm_peripheral_config { +u32 crci; +u32 mux; +}; + +#endif /* __LINUX_DMA_QCOM_ADM_H */
Signature · 1 line
2.29.2
PATCH v2 9/11 dmaengine: xilinx_dpdma: stop using slave_id field
In reply to Arnd BergmannFrom: Arnd Bergmann <[email protected]>
The display driver wants to pass a custom flag to the DMA engine driver, which it started doing by using the slave_id field that was traditionally used for a different purpose.
As there is no longer a correct use for the slave_id field, it should really be removed, and the remaining users changed over to something different.
The new mechanism for passing nonstandard settings is using the .peripheral_config field, so use that to pass a newly defined structure here, making it clear that this will not work in portable drivers.
--- drivers/dma/xilinx/xilinx_dpdma.c | 17 +++++++++++------ drivers/gpu/drm/xlnx/zynqmp_disp.c | 9 +++++++-- include/linux/dma/xilinx_dpdma.h | 11 +++++++++++ 3 files changed, 29 insertions(+), 8 deletions(-) create mode 100644 include/linux/dma/xilinx_dpdma.h
drivers/dma/xilinx/xilinx_dpdma.c +11 -6
@@ -12,6 +12,7 @@#include <linux/clk.h> #include <linux/debugfs.h> #include <linux/delay.h> +#include <linux/dma/xilinx_dpdma.h> #include <linux/dmaengine.h> #include <linux/dmapool.h> #include <linux/interrupt.h>
@@ -1273,6 +1274,7 @@ static int xilinx_dpdma_config(struct dma_chan *dchan, struct dma_slave_config *config) {struct xilinx_dpdma_chan *chan =to_xilinx_chan (dchan); +struct xilinx_dpdma_peripheral_config *pconfig;unsigned long flags;/*
@@ -1282,15 +1284,18 @@ static int xilinx_dpdma_config(struct dma_chan *dchan,* fixed both on the DPDMA side and on the DP controller side. */ -spin_lock_irqsave (&chan->lock, flags); -/* -* Abuse the slave_id to indicate that the channel is part of a video -* group. +* Use the peripheral_config to indicate that the channel is part +* of a video group. This requires matching use of the custom +* structure in each driver. */ -if (chan->id <=ZYNQMP_DPDMA_VIDEO2 ) - chan->video_group = config->slave_id !=0 ; + pconfig = config->peripheral_config; +if (WARN_ON (pconfig && config->peripheral_size !=sizeof (*pconfig))) +return -EINVAL ; +spin_lock_irqsave (&chan->lock, flags); +if (chan->id <=ZYNQMP_DPDMA_VIDEO2 && pconfig) + chan->video_group = pconfig->video_group;spin_unlock_irqrestore (&chan->lock, flags);return 0 ;
drivers/gpu/drm/xlnx/zynqmp_disp.c +7 -2
@@ -24,6 +24,7 @@#include <linux/clk.h> #include <linux/delay.h> +#include <linux/dma/xilinx_dpdma.h> #include <linux/dma-mapping.h> #include <linux/dmaengine.h> #include <linux/module.h>
@@ -1058,14 +1059,18 @@ static void zynqmp_disp_layer_set_format(struct zynqmp_disp_layer *layer,zynqmp_disp_avbuf_set_format (layer->disp, layer, layer->disp_fmt);/* -* Set slave_id for each DMA channel to indicate they're part of a +* Set pconfig for each DMA channel to indicate they're part of a * video group. */ for (i =0 ; i < info->num_planes; i++) {struct zynqmp_disp_layer_dma *dma = &layer->dmas[i]; +struct xilinx_dpdma_peripheral_config pconfig = { + .video_group = true, + };struct dma_slave_config config = { .direction =DMA_MEM_TO_DEV , - .slave_id =1 , + .peripheral_config = &pconfig, + .peripheral_size =sizeof (pconfig), };dmaengine_slave_config (dma->chan, &config);
include/linux/dma/xilinx_dpdma.h new file +11 -0
@@ -0,0 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0 +#ifndef __LINUX_DMA_XILINX_DPDMA_H +#define __LINUX_DMA_XILINX_DPDMA_H + +#include <linux/types.h> + +struct xilinx_dpdma_peripheral_config { +bool video_group; +}; + +#endif /* __LINUX_DMA_XILINX_DPDMA_H */
Signature · 1 line
2.29.2
PATCH v2 10/11 dmaengine: tegra20-apb: stop checking config->slave_id
In reply to Arnd BergmannFrom: Arnd Bergmann <[email protected]>
Nothing sets the slave_id field any more, so stop accessing it to allow the removal of this field.
--- drivers/dma/tegra20-apb-dma.c | 6 ------ 1 file changed, 6 deletions(-)
drivers/dma/tegra20-apb-dma.c +0 -6
@@ -343,12 +343,6 @@ static int tegra_dma_slave_config(struct dma_chan *dc, }memcpy (&tdc->dma_sconfig, sconfig,sizeof (*sconfig)); -if (tdc->slave_id ==TEGRA_APBDMA_SLAVE_ID_INVALID && - sconfig->device_fc) { -if (sconfig->slave_id >TEGRA_APBDMA_CSR_REQ_SEL_MASK ) -return -EINVAL ; - tdc->slave_id = sconfig->slave_id; - } tdc->config_init = true;return 0 ;
Signature · 1 line
2.29.2
PATCH v2 11/11 dmaengine: remove slave_id config field
In reply to Arnd BergmannFrom: Arnd Bergmann <[email protected]>
All references to the slave_id field have been removed, so remove the field as well to prevent new references from creeping in again.
Originally this allowed slave DMA drivers to configure which device is accessed with the dmaengine_slave_config() call, but this was inconsistent, as the same information is also passed while requesting a channel, and never changes in practice.
In modern kernels, the device is always selected when requesting the channel, so the .slave_id field is no longer useful.
--- include/linux/dmaengine.h | 4 ---- 1 file changed, 4 deletions(-)
include/linux/dmaengine.h +0 -4
@@ -418,9 +418,6 @@ enum dma_slave_buswidth {* @device_fc: Flow Controller Settings. Only valid for slave channels. Fill * with 'true' if peripheral should be flow controller. Direction will be * selected at Runtime. -* @slave_id: Slave requester id. Only valid for slave channels. The dma -* slave peripheral will have unique id as dma requester which need to be -* pass as slave config. * @peripheral_config: peripheral configuration for programming peripheral * for dmaengine transfer * @peripheral_size: peripheral configuration buffer size
@@ -448,7 +445,6 @@ struct dma_slave_config {u32 src_port_window_size;u32 dst_port_window_size;bool device_fc; -unsigned int slave_id;void *peripheral_config;size_t peripheral_size; };
Signature · 1 line
2.29.2
Quoted 7 lines · Arnd Bergmann
From: Arnd Bergmann <[email protected]>
I recently came across some new uses of the '
slave_id' field that I had (almost) removed a few years ago. There are no legitimate uses of this field in the kernel, only a few stale references and two drivers that abuse the field as a side-channel between the dmaengine driver and its client.
Vinod Koul
maintainerQuoted 8 lines · Arnd Bergmann
From: Arnd Bergmann <[email protected]>
I recently came across some new uses of the '
slave_id' field that I had (almost) removed a few years ago. There are no legitimate uses of this field in the kernel, only a few stale references and two drivers that abuse the field as a side-channel between the dmaengine driver and its client.
Quoted 7 lines
Let's change the xilinx and qualcomm drivers to use the documented side-channel (
peripheral_data) instead, and remove the remnants of it to prevent new users from coming in.I think I got all the necessary Acks on v1 already, so if there are no further concerns, please merge this through the dmaengine tree for v5.17, or pull from
Arnd, Thanks for the cleanup. I have applied and folder the fix you sent in this
Signature · 1 line
~Vinod