summaryrefslogtreecommitdiff
path: root/drivers/dma/fsl-edma-main.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2024-09-23 14:08:08 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2024-09-23 14:08:08 -0700
commit8874d92b579bf86f61f044ab43a4cd961d112269 (patch)
tree0fb95b1ab56d69196a5268541c5b96e305358d26 /drivers/dma/fsl-edma-main.c
parentfbb86b0d5f38184873772a84ae50d5edd6a8b046 (diff)
parente0bee4bcdc3238ebcae6e5960544b9e3d0a62abf (diff)
Merge tag 'dmaengine-6.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/dmaengine
Pull dmaengine updates from Vinod Koul: "Unusually, more new driver and device support than updates. Couple of new device support, AMD, Rcar, Intel and New drivers in Freescale, Loonsoon, AMD and LPC32XX with DT conversion and mode updates etc. New support: - Support for AMD Versal Gen 2 DMA IP - Rcar RZ/G3S SoC dma controller - Support for Intel Diamond Rapids and Granite Rapids-D dma controllers - Support for Freescale ls1021a-qdma controller - New driver for Loongson-1 APB DMA - New driver for AMD QDMA - Pl08x in LPC32XX router dma driver Updates: - Support for dpdma cyclic dma mode - XML conversion for marvell xor dma bindings - Dma clocks documentation for imx dma" * tag 'dmaengine-6.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/dmaengine: (24 commits) dmaengine: loongson1-apb-dma: Fix the build warning caused by the size of pdev_irqname dmaengine: Fix spelling mistakes dmaengine: Add dma router for pl08x in LPC32XX SoC dmaengine: fsl-edma: add edma src ID check at request channel dmaengine: fsl-edma: change to guard(mutex) within fsl_edma3_xlate() dmaengine: avoid non-constant format string dmaengine: imx-dma: Remove i.MX21 support dt-bindings: dma: fsl,imx-dma: Document the DMA clocks dmaengine: Loongson1: Add Loongson-1 APB DMA driver dt-bindings: dma: Add Loongson-1 APB DMA dmaengine: zynqmp_dma: Add support for AMD Versal Gen 2 DMA IP dt-bindings: dmaengine: zynqmp_dma: Add a new compatible string dmaengine: idxd: Add new DSA and IAA device IDs for Diamond Rapids platform dmaengine: idxd: Add a new DSA device ID for Granite Rapids-D platform dmaengine: ti: k3-udma: Remove unused declarations dmaengine: amd: qdma: Add AMD QDMA driver dmaengine: xilinx: dpdma: Add support for cyclic dma mode dma: ipu: Remove include/linux/dma/ipu-dma.h dt-bindings: dma: fsl-mxs-dma: Add compatible string "fsl,imx8qxp-dma-apbh" dt-bindings: fsl-qdma: allow compatible string fallback to fsl,ls1021a-qdma ...
Diffstat (limited to 'drivers/dma/fsl-edma-main.c')
-rw-r--r--drivers/dma/fsl-edma-main.c27
1 files changed, 23 insertions, 4 deletions
diff --git a/drivers/dma/fsl-edma-main.c b/drivers/dma/fsl-edma-main.c
index c66185c5a199..f9f1eda79254 100644
--- a/drivers/dma/fsl-edma-main.c
+++ b/drivers/dma/fsl-edma-main.c
@@ -100,6 +100,22 @@ static irqreturn_t fsl_edma_irq_handler(int irq, void *dev_id)
return fsl_edma_err_handler(irq, dev_id);
}
+static bool fsl_edma_srcid_in_use(struct fsl_edma_engine *fsl_edma, u32 srcid)
+{
+ struct fsl_edma_chan *fsl_chan;
+ int i;
+
+ for (i = 0; i < fsl_edma->n_chans; i++) {
+ fsl_chan = &fsl_edma->chans[i];
+
+ if (fsl_chan->srcid && srcid == fsl_chan->srcid) {
+ dev_err(&fsl_chan->pdev->dev, "The srcid is in use, can't use!");
+ return true;
+ }
+ }
+ return false;
+}
+
static struct dma_chan *fsl_edma_xlate(struct of_phandle_args *dma_spec,
struct of_dma *ofdma)
{
@@ -117,6 +133,10 @@ static struct dma_chan *fsl_edma_xlate(struct of_phandle_args *dma_spec,
list_for_each_entry_safe(chan, _chan, &fsl_edma->dma_dev.channels, device_node) {
if (chan->client_count)
continue;
+
+ if (fsl_edma_srcid_in_use(fsl_edma, dma_spec->args[1]))
+ return NULL;
+
if ((chan->chan_id / chans_per_mux) == dma_spec->args[0]) {
chan = dma_get_slave_channel(chan);
if (chan) {
@@ -153,7 +173,7 @@ static struct dma_chan *fsl_edma3_xlate(struct of_phandle_args *dma_spec,
b_chmux = !!(fsl_edma->drvdata->flags & FSL_EDMA_DRV_HAS_CHMUX);
- mutex_lock(&fsl_edma->fsl_edma_mutex);
+ guard(mutex)(&fsl_edma->fsl_edma_mutex);
list_for_each_entry_safe(chan, _chan, &fsl_edma->dma_dev.channels,
device_node) {
@@ -161,6 +181,8 @@ static struct dma_chan *fsl_edma3_xlate(struct of_phandle_args *dma_spec,
continue;
fsl_chan = to_fsl_edma_chan(chan);
+ if (fsl_edma_srcid_in_use(fsl_edma, dma_spec->args[0]))
+ return NULL;
i = fsl_chan - fsl_edma->chans;
fsl_chan->priority = dma_spec->args[1];
@@ -177,18 +199,15 @@ static struct dma_chan *fsl_edma3_xlate(struct of_phandle_args *dma_spec,
if (!b_chmux && i == dma_spec->args[0]) {
chan = dma_get_slave_channel(chan);
chan->device->privatecnt++;
- mutex_unlock(&fsl_edma->fsl_edma_mutex);
return chan;
} else if (b_chmux && !fsl_chan->srcid) {
/* if controller support channel mux, choose a free channel */
chan = dma_get_slave_channel(chan);
chan->device->privatecnt++;
fsl_chan->srcid = dma_spec->args[0];
- mutex_unlock(&fsl_edma->fsl_edma_mutex);
return chan;
}
}
- mutex_unlock(&fsl_edma->fsl_edma_mutex);
return NULL;
}