* [PATCH v3 1/7] dmaengine: fsl-edma: unregister channels before vchan cleanup
2026-11-02 6:49 [PATCH v3 0/7] dmaengine: add DMA channel bus and fsl-edma per-channel IOMMU support Peng Fan (OSS)
@ 2026-11-02 6:49 ` Peng Fan (OSS)
2026-11-02 6:49 ` [PATCH v3 2/7] dmaengine: add a bus for DMA channel devices Peng Fan (OSS)
` (5 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Peng Fan (OSS) @ 2026-11-02 6:49 UTC (permalink / raw)
To: Frank Li, Vinod Koul, Joerg Roedel (AMD),
Will Deacon, Robin Murphy, Laxman Dewangan, Jon Hunter,
Thierry Reding, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam
Cc: Frank Li, Larisa IIeana Grigore, imx, dmaengine, linux-kernel,
iommu, linux-tegra, devicetree, linux-arm-kernel, Peng Fan
From: Peng Fan <peng.fan@nxp.com>
Since commit 4035726a6b72 ("dmaengine: fsl-edma: Use managed API
dmaenginem_async_device_register()"), dma_async_device_unregister() runs
as a devres action after fsl_edma_remove(). However, fsl_edma_remove()
still calls fsl_edma_cleanup_vchan() first, which removes every channel
from dma_dev.channels. When the devres action later runs,
dma_async_device_unregister() sees an empty channel list and never
unregisters the channel devices. They remain visible in /sys/class/dma.
Keep the vchan cleanup, but register it as a devres action before
dmaenginem_async_device_register(). Devres actions run in reverse
order, so the DMA channels are unregistered first and the vchan list is
cleaned up afterwards. Remove the premature cleanup call from
fsl_edma_remove().
Fixes: 4035726a6b72 ("dmaengine: fsl-edma: Use managed API dmaenginem_async_device_register()")
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
drivers/dma/fsl-edma-main.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/drivers/dma/fsl-edma-main.c b/drivers/dma/fsl-edma-main.c
index 630285c854824..30d548a723462 100644
--- a/drivers/dma/fsl-edma-main.c
+++ b/drivers/dma/fsl-edma-main.c
@@ -31,6 +31,11 @@ static void fsl_edma_synchronize(struct dma_chan *chan)
vchan_synchronize(&fsl_chan->vchan);
}
+static void fsl_edma_cleanup_vchan_action(void *data)
+{
+ fsl_edma_cleanup_vchan(data);
+}
+
static irqreturn_t fsl_edma_tx_handler(int irq, void *dev_id)
{
struct fsl_edma_engine *fsl_edma = dev_id;
@@ -882,6 +887,12 @@ static int fsl_edma_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, fsl_edma);
+ ret = devm_add_action_or_reset(&pdev->dev,
+ fsl_edma_cleanup_vchan_action,
+ &fsl_edma->dma_dev);
+ if (ret)
+ return ret;
+
ret = dmaenginem_async_device_register(&fsl_edma->dma_dev);
if (ret)
return dev_err_probe(&pdev->dev, ret,
@@ -906,7 +917,6 @@ static void fsl_edma_remove(struct platform_device *pdev)
struct fsl_edma_engine *fsl_edma = platform_get_drvdata(pdev);
fsl_edma_irq_exit(pdev, fsl_edma);
- fsl_edma_cleanup_vchan(&fsl_edma->dma_dev);
}
static int fsl_edma_suspend_late(struct device *dev)
--
2.34.1
^ permalink raw reply [flat|nested] 8+ messages in thread* [PATCH v3 2/7] dmaengine: add a bus for DMA channel devices
2026-11-02 6:49 [PATCH v3 0/7] dmaengine: add DMA channel bus and fsl-edma per-channel IOMMU support Peng Fan (OSS)
2026-11-02 6:49 ` [PATCH v3 1/7] dmaengine: fsl-edma: unregister channels before vchan cleanup Peng Fan (OSS)
@ 2026-11-02 6:49 ` Peng Fan (OSS)
2026-11-02 6:49 ` [PATCH v3 3/7] iommu: register the DMA channel bus for IOMMU notifications Peng Fan (OSS)
` (4 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Peng Fan (OSS) @ 2026-11-02 6:49 UTC (permalink / raw)
To: Frank Li, Vinod Koul, Joerg Roedel (AMD),
Will Deacon, Robin Murphy, Laxman Dewangan, Jon Hunter,
Thierry Reding, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam
Cc: Frank Li, Larisa IIeana Grigore, imx, dmaengine, linux-kernel,
iommu, linux-tegra, devicetree, linux-arm-kernel, Peng Fan
From: Peng Fan <peng.fan@nxp.com>
DMA channel devices are currently created as class devices without a bus.
This works for sysfs, but it prevents per-channel DMA/IOMMU configuration:
of_dma_configure() only probes the IOMMU when dev->bus is set, and the
IOMMU core only installs probe/release notifiers for buses listed in
iommu_buses[].
Drivers that need per-channel IOMMU support currently work around this by
assigning dev->bus after device_register(). That leaves the bus subsystem
reference count unbalanced because bus_add_device() already ran with a NULL
bus, and bus_remove_device() will later drop a reference that was never
taken.
Add a dedicated bus for DMA channel devices and register it during
dmaengine initialisation, before iommu_subsys_init(). The match callback
never succeeds, so no driver can bind to these devices. A follow-up patch
will register the channel devices on this bus.
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
drivers/dma/dmaengine.c | 24 +++++++++++++++++++++---
include/linux/dmaengine.h | 4 ++++
2 files changed, 25 insertions(+), 3 deletions(-)
diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
index 34be53487a21d..6fea67f088b35 100644
--- a/drivers/dma/dmaengine.c
+++ b/drivers/dma/dmaengine.c
@@ -1643,17 +1643,35 @@ void dma_run_dependencies(struct dma_async_tx_descriptor *tx)
}
EXPORT_SYMBOL_GPL(dma_run_dependencies);
+static int dma_chan_bus_match(struct device *dev,
+ const struct device_driver *drv)
+{
+ return 0;
+}
+
+const struct bus_type dma_chan_bus_type = {
+ .name = "dma",
+ .match = dma_chan_bus_match,
+};
+
static int __init dma_bus_init(void)
{
int err = dmaengine_init_unmap_pool();
+ if (err)
+ return err;
+
+ err = bus_register(&dma_chan_bus_type);
if (err)
return err;
err = class_register(&dma_devclass);
- if (!err)
- dmaengine_debugfs_init();
+ if (err) {
+ bus_unregister(&dma_chan_bus_type);
+ return err;
+ }
- return err;
+ dmaengine_debugfs_init();
+ return 0;
}
arch_initcall(dma_bus_init);
diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
index 805668fbe4376..14d8f182c7cb5 100644
--- a/include/linux/dmaengine.h
+++ b/include/linux/dmaengine.h
@@ -412,6 +412,10 @@ struct dma_chan_dev {
bool chan_dma_dev;
};
+#ifdef CONFIG_DMA_ENGINE
+extern const struct bus_type dma_chan_bus_type;
+#endif
+
/**
* enum dma_slave_buswidth - defines bus width of the DMA slave
* device, source or target buses
--
2.34.1
^ permalink raw reply [flat|nested] 8+ messages in thread* [PATCH v3 3/7] iommu: register the DMA channel bus for IOMMU notifications
2026-11-02 6:49 [PATCH v3 0/7] dmaengine: add DMA channel bus and fsl-edma per-channel IOMMU support Peng Fan (OSS)
2026-11-02 6:49 ` [PATCH v3 1/7] dmaengine: fsl-edma: unregister channels before vchan cleanup Peng Fan (OSS)
2026-11-02 6:49 ` [PATCH v3 2/7] dmaengine: add a bus for DMA channel devices Peng Fan (OSS)
@ 2026-11-02 6:49 ` Peng Fan (OSS)
2026-11-02 6:49 ` [PATCH v3 4/7] dmaengine: move channel devices to the DMA channel bus Peng Fan (OSS)
` (3 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Peng Fan (OSS) @ 2026-11-02 6:49 UTC (permalink / raw)
To: Frank Li, Vinod Koul, Joerg Roedel (AMD),
Will Deacon, Robin Murphy, Laxman Dewangan, Jon Hunter,
Thierry Reding, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam
Cc: Frank Li, Larisa IIeana Grigore, imx, dmaengine, linux-kernel,
iommu, linux-tegra, devicetree, linux-arm-kernel, Peng Fan
From: Peng Fan <peng.fan@nxp.com>
DMA channel devices are about to be registered on a dedicated DMA channel
bus so that they get a properly balanced bus association before
device_register().
Add that bus to iommu_buses[] so the IOMMU core installs its bus notifier
for it. This allows of_dma_configure() to probe a per-channel IOMMU and,
more importantly, lets BUS_NOTIFY_REMOVED_DEVICE release the IOMMU group
and domain when the channel device is unregistered.
The dmaengine bus is registered from an arch_initcall, before
iommu_subsys_init() consumes iommu_buses[]. Guard the entry with
CONFIG_DMA_ENGINE because the bus does not exist when the DMA engine core
is not built.
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
drivers/iommu/iommu.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index b486b8bbd1fcd..6fa871bbd63ad 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -8,6 +8,7 @@
#include <linux/amba/bus.h>
#include <linux/device.h>
+#include <linux/dmaengine.h>
#include <linux/kernel.h>
#include <linux/bits.h>
#include <linux/bug.h>
@@ -191,6 +192,9 @@ static const struct bus_type * const iommu_buses[] = {
#ifdef CONFIG_ARM_AMBA
&amba_bustype,
#endif
+#ifdef CONFIG_DMA_ENGINE
+ &dma_chan_bus_type,
+#endif
#ifdef CONFIG_FSL_MC_BUS
&fsl_mc_bus_type,
#endif
--
2.34.1
^ permalink raw reply [flat|nested] 8+ messages in thread* [PATCH v3 4/7] dmaengine: move channel devices to the DMA channel bus
2026-11-02 6:49 [PATCH v3 0/7] dmaengine: add DMA channel bus and fsl-edma per-channel IOMMU support Peng Fan (OSS)
` (2 preceding siblings ...)
2026-11-02 6:49 ` [PATCH v3 3/7] iommu: register the DMA channel bus for IOMMU notifications Peng Fan (OSS)
@ 2026-11-02 6:49 ` Peng Fan (OSS)
2026-11-02 6:49 ` [PATCH v3 5/7] dt-bindings: dma: fsl,edma: add per-channel child node support Peng Fan (OSS)
` (2 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Peng Fan (OSS) @ 2026-11-02 6:49 UTC (permalink / raw)
To: Frank Li, Vinod Koul, Joerg Roedel (AMD),
Will Deacon, Robin Murphy, Laxman Dewangan, Jon Hunter,
Thierry Reding, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam
Cc: Frank Li, Larisa IIeana Grigore, imx, dmaengine, linux-kernel,
iommu, linux-tegra, devicetree, linux-arm-kernel, Peng Fan
From: Peng Fan <peng.fan@nxp.com>
Register each dma_chan_dev on dma_chan_bus_type before device_register()
and make it a bus device instead of a class device. Setting the bus
before registration lets bus_add_device() take the bus subsystem
reference, so the matching bus_remove_device() calls drop references that
were actually acquired. Attach dma_dev_groups to the bus and set the
device release callback directly.
Keep the existing /sys/class/dma interface by registering a class_compat
named "dma" and creating a link for each channel device. The channel
devices now live on the DMA bus, while /sys/class/dma/dmaNchanM remains
available to userspace. The uevent subsystem name stays "dma" because
the bus has the same name as the old class.
Remove the post-registration dev->bus assignment from the Tegra GPC DMA
driver. Leaving it in place would overwrite the bus selected by the DMA
engine core and reintroduce the reference imbalance.
The DMA channel bus match callback never matches, so no driver can bind
to these channel devices.
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
drivers/dma/dmaengine.c | 27 ++++++++++++++++-----------
drivers/dma/tegra186-gpc-dma.c | 1 -
2 files changed, 16 insertions(+), 12 deletions(-)
diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
index 6fea67f088b35..0e2eea339f1ce 100644
--- a/drivers/dma/dmaengine.c
+++ b/drivers/dma/dmaengine.c
@@ -239,11 +239,7 @@ static void chan_dev_release(struct device *dev)
kfree(chan_dev);
}
-static struct class dma_devclass = {
- .name = "dma",
- .dev_groups = dma_dev_groups,
- .dev_release = chan_dev_release,
-};
+static struct class_compat *dma_chan_class;
/* --- client and device registration --- */
@@ -1115,8 +1111,9 @@ static int __dma_async_device_channel_register(struct dma_device *device,
goto err_free_dev;
}
- dmaengine_chan_dev(chan)->class = &dma_devclass;
dmaengine_chan_dev(chan)->parent = device->dev;
+ dmaengine_chan_dev(chan)->bus = &dma_chan_bus_type;
+ dmaengine_chan_dev(chan)->release = chan_dev_release;
chan->chan_dev->chan = chan;
chan->chan_dev->dev_id = device->dev_id;
spin_lock_init(&chan->lock);
@@ -1128,6 +1125,11 @@ static int __dma_async_device_channel_register(struct dma_device *device,
rc = device_register(dmaengine_chan_dev(chan));
if (rc)
goto err_out_ida;
+
+ rc = class_compat_create_link(dma_chan_class, dmaengine_chan_dev(chan));
+ if (rc)
+ dev_warn(device->dev, "Failed to create compatibility class link\n");
+
chan->client_count = 0;
device->chancnt++;
@@ -1172,6 +1174,7 @@ static void __dma_async_device_channel_unregister(struct dma_device *device,
chan->chan_dev->chan = NULL;
mutex_unlock(&dma_list_mutex);
ida_free(&device->chan_ida, chan->chan_id);
+ class_compat_remove_link(dma_chan_class, dmaengine_chan_dev(chan));
device_unregister(dmaengine_chan_dev(chan));
free_percpu(chan->local);
}
@@ -1306,6 +1309,7 @@ int dma_async_device_register(struct dma_device *device)
mutex_lock(&dma_list_mutex);
chan->chan_dev->chan = NULL;
mutex_unlock(&dma_list_mutex);
+ class_compat_remove_link(dma_chan_class, dmaengine_chan_dev(chan));
device_unregister(dmaengine_chan_dev(chan));
free_percpu(chan->local);
}
@@ -1650,8 +1654,9 @@ static int dma_chan_bus_match(struct device *dev,
}
const struct bus_type dma_chan_bus_type = {
- .name = "dma",
- .match = dma_chan_bus_match,
+ .name = "dma",
+ .match = dma_chan_bus_match,
+ .dev_groups = dma_dev_groups,
};
static int __init dma_bus_init(void)
@@ -1665,10 +1670,10 @@ static int __init dma_bus_init(void)
if (err)
return err;
- err = class_register(&dma_devclass);
- if (err) {
+ dma_chan_class = class_compat_register("dma");
+ if (!dma_chan_class) {
bus_unregister(&dma_chan_bus_type);
- return err;
+ return -ENOMEM;
}
dmaengine_debugfs_init();
diff --git a/drivers/dma/tegra186-gpc-dma.c b/drivers/dma/tegra186-gpc-dma.c
index e76c58f213d84..71a935d873868 100644
--- a/drivers/dma/tegra186-gpc-dma.c
+++ b/drivers/dma/tegra186-gpc-dma.c
@@ -1541,7 +1541,6 @@ static int tegra_dma_probe(struct platform_device *pdev)
tdc = to_tegra_dma_chan(chan);
if (use_iommu_map) {
- chdev->bus = pdev->dev.bus;
dma_coerce_mask_and_coherent(chdev, DMA_BIT_MASK(cdata->addr_bits));
ret = of_dma_configure_id(chdev, pdev->dev.of_node,
--
2.34.1
^ permalink raw reply [flat|nested] 8+ messages in thread* [PATCH v3 5/7] dt-bindings: dma: fsl,edma: add per-channel child node support
2026-11-02 6:49 [PATCH v3 0/7] dmaengine: add DMA channel bus and fsl-edma per-channel IOMMU support Peng Fan (OSS)
` (3 preceding siblings ...)
2026-11-02 6:49 ` [PATCH v3 4/7] dmaengine: move channel devices to the DMA channel bus Peng Fan (OSS)
@ 2026-11-02 6:49 ` Peng Fan (OSS)
2026-11-02 6:50 ` [PATCH v3 6/7] dmaengine: fsl-edma: support per-channel DT child nodes Peng Fan (OSS)
2026-11-02 6:50 ` [PATCH v3 7/7] arm64: dts: imx95: convert eDMA to per-channel " Peng Fan (OSS)
6 siblings, 0 replies; 8+ messages in thread
From: Peng Fan (OSS) @ 2026-11-02 6:49 UTC (permalink / raw)
To: Frank Li, Vinod Koul, Joerg Roedel (AMD),
Will Deacon, Robin Murphy, Laxman Dewangan, Jon Hunter,
Thierry Reding, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam
Cc: Frank Li, Larisa IIeana Grigore, imx, dmaengine, linux-kernel,
iommu, linux-tegra, devicetree, linux-arm-kernel, Peng Fan
From: Peng Fan <peng.fan@nxp.com>
Add support for optional per-channel child nodes (dma-channel@<addr>)
to the fsl,edma binding. Each child node can carry its own reg,
interrupts, iommus, and power-domains properties, describing a real
per-channel MMIO region.
Enables per-channel IOMMU stream ID assignment via the standard
iommus property on each child.
The interrupts property is removed from the required list since
channels with child nodes carry their own interrupts. Existing DTS
without child nodes remains valid.
Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
.../devicetree/bindings/dma/fsl,edma.yaml | 70 +++++++++++++++++++++-
1 file changed, 69 insertions(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/dma/fsl,edma.yaml b/Documentation/devicetree/bindings/dma/fsl,edma.yaml
index f609038e35ae1..19a103baccaf4 100644
--- a/Documentation/devicetree/bindings/dma/fsl,edma.yaml
+++ b/Documentation/devicetree/bindings/dma/fsl,edma.yaml
@@ -104,11 +104,40 @@ properties:
Bit semantics: 0 means channel available, 1 means channel unavailable
default: 0
+ "#address-cells":
+ const: 1
+
+ "#size-cells":
+ const: 1
+
+ ranges: true
+
+patternProperties:
+ "^dma-channel@[0-9a-f]+$":
+ type: object
+ additionalProperties: false
+
+ properties:
+ reg:
+ maxItems: 1
+ description: Per-channel register region within the eDMA block.
+
+ interrupts:
+ maxItems: 1
+
+ iommus:
+ maxItems: 1
+
+ power-domains:
+ maxItems: 1
+
+ required:
+ - reg
+
required:
- "#dma-cells"
- compatible
- reg
- - interrupts
- dma-channels
allOf:
@@ -351,3 +380,42 @@ examples:
<&pd IMX_SC_R_DMA_3_CH6>,
<&pd IMX_SC_R_DMA_3_CH7>;
};
+
+ - |
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+ dma-controller@42000000 {
+ compatible = "fsl,imx95-edma5";
+ reg = <0x42000000 0x210000>;
+ #dma-cells = <3>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ dma-channels = <64>;
+ clocks = <&clk 0>;
+ clock-names = "dma";
+
+ dma-channel@42020000 {
+ reg = <0x42020000 0x8000>;
+ interrupts = <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>;
+ iommus = <&smmu 0x30>;
+ };
+
+ dma-channel@42028000 {
+ reg = <0x42028000 0x8000>;
+ interrupts = <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>;
+ iommus = <&smmu 0x30>;
+ };
+
+ dma-channel@42030000 {
+ reg = <0x42030000 0x8000>;
+ interrupts = <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>;
+ iommus = <&smmu 0x31>;
+ };
+
+ dma-channel@42038000 {
+ reg = <0x42038000 0x8000>;
+ interrupts = <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>;
+ iommus = <&smmu 0x31>;
+ };
+ };
--
2.34.1
^ permalink raw reply [flat|nested] 8+ messages in thread* [PATCH v3 6/7] dmaengine: fsl-edma: support per-channel DT child nodes
2026-11-02 6:49 [PATCH v3 0/7] dmaengine: add DMA channel bus and fsl-edma per-channel IOMMU support Peng Fan (OSS)
` (4 preceding siblings ...)
2026-11-02 6:49 ` [PATCH v3 5/7] dt-bindings: dma: fsl,edma: add per-channel child node support Peng Fan (OSS)
@ 2026-11-02 6:50 ` Peng Fan (OSS)
2026-11-02 6:50 ` [PATCH v3 7/7] arm64: dts: imx95: convert eDMA to per-channel " Peng Fan (OSS)
6 siblings, 0 replies; 8+ messages in thread
From: Peng Fan (OSS) @ 2026-11-02 6:50 UTC (permalink / raw)
To: Frank Li, Vinod Koul, Joerg Roedel (AMD),
Will Deacon, Robin Murphy, Laxman Dewangan, Jon Hunter,
Thierry Reding, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam
Cc: Frank Li, Larisa IIeana Grigore, imx, dmaengine, linux-kernel,
iommu, linux-tegra, devicetree, linux-arm-kernel, Peng Fan
From: Peng Fan <peng.fan@nxp.com>
Add support for parsing per-channel child nodes from devicetree.
Each child node can carry its own interrupts, iommus, and
power-domains properties.
The implementation is split into three functions:
- fsl_edma_child_to_chan_id(): derives the channel index from the
child MMIO address relative to the parent base.
- fsl_edma_configure_chan_from_dt(): called before setup_irq() to
populate per-channel txirq from child interrupt properties.
fsl_edma3_irq_init() is updated to skip platform_get_irq() for
channels that already have an IRQ assigned from their child node.
- fsl_edma_configure_chan_iommu(): called after
dmaenginem_async_device_register() to configure per-channel IOMMU
by calling of_dma_configure() on each dma_chan_dev and setting
chan_dma_dev so dmaengine_get_dma_device() returns the per-channel
device.
Existing DTS without child nodes continues to work unchanged.
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
drivers/dma/fsl-edma-common.c | 10 +--
drivers/dma/fsl-edma-main.c | 152 ++++++++++++++++++++++++++++++++++++++++--
2 files changed, 152 insertions(+), 10 deletions(-)
diff --git a/drivers/dma/fsl-edma-common.c b/drivers/dma/fsl-edma-common.c
index 513b0f4e5be21..62cd60179bc6f 100644
--- a/drivers/dma/fsl-edma-common.c
+++ b/drivers/dma/fsl-edma-common.c
@@ -310,10 +310,10 @@ int fsl_edma_resume(struct dma_chan *chan)
static void fsl_edma_unprep_slave_dma(struct fsl_edma_chan *fsl_chan)
{
+ struct device *dev = dmaengine_get_dma_device(&fsl_chan->vchan.chan);
+
if (fsl_chan->dma_dir != DMA_NONE)
- dma_unmap_resource(fsl_chan->vchan.chan.device->dev,
- fsl_chan->dma_dev_addr,
- fsl_chan->dma_dev_size,
+ dma_unmap_resource(dev, fsl_chan->dma_dev_addr, fsl_chan->dma_dev_size,
fsl_chan->dma_dir, 0);
fsl_chan->dma_dir = DMA_NONE;
}
@@ -321,7 +321,7 @@ static void fsl_edma_unprep_slave_dma(struct fsl_edma_chan *fsl_chan)
static bool fsl_edma_prep_slave_dma(struct fsl_edma_chan *fsl_chan,
enum dma_transfer_direction dir)
{
- struct device *dev = fsl_chan->vchan.chan.device->dev;
+ struct device *dev = dmaengine_get_dma_device(&fsl_chan->vchan.chan);
enum dma_data_direction dma_dir;
phys_addr_t addr = 0;
u32 size = 0;
@@ -1090,7 +1090,7 @@ int fsl_edma_alloc_chan_resources(struct dma_chan *chan)
if (fsl_edma_drvflags(fsl_chan) & FSL_EDMA_DRV_HAS_CHCLK)
clk_prepare_enable(fsl_chan->clk);
- fsl_chan->tcd_pool = dma_pool_create("tcd_pool", chan->device->dev,
+ fsl_chan->tcd_pool = dma_pool_create("tcd_pool", dmaengine_get_dma_device(chan),
fsl_edma_drvflags(fsl_chan) & FSL_EDMA_DRV_TCD64 ?
sizeof(struct fsl_edma_hw_tcd64) : sizeof(struct fsl_edma_hw_tcd),
32, 0);
diff --git a/drivers/dma/fsl-edma-main.c b/drivers/dma/fsl-edma-main.c
index 30d548a723462..795744e67837d 100644
--- a/drivers/dma/fsl-edma-main.c
+++ b/drivers/dma/fsl-edma-main.c
@@ -16,7 +16,10 @@
#include <linux/interrupt.h>
#include <linux/clk.h>
#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
#include <linux/of_dma.h>
+#include <linux/of_irq.h>
#include <linux/dma-mapping.h>
#include <linux/pm_runtime.h>
#include <linux/pm_domain.h>
@@ -400,12 +403,13 @@ static int fsl_edma3_irq_init(struct platform_device *pdev, struct fsl_edma_engi
if (fsl_edma->chan_masked & BIT(i))
continue;
- /* request channel irq */
- fsl_chan->txirq = platform_get_irq(pdev, i);
- if (fsl_chan->txirq < 0)
- return -EINVAL;
+ if (fsl_chan->txirq <= 0) {
+ fsl_chan->txirq = platform_get_irq(pdev, i);
+ if (fsl_chan->txirq < 0)
+ return fsl_chan->txirq;
- fsl_chan->irq_handler = fsl_edma3_tx_handler;
+ fsl_chan->irq_handler = fsl_edma3_tx_handler;
+ }
if (!(fsl_edma->drvdata->flags & FSL_EDMA_DRV_ERRIRQ_SHARE)) {
fsl_chan->errirq = fsl_chan->txirq;
@@ -703,6 +707,136 @@ static int fsl_edma3_attach_pd(struct platform_device *pdev, struct fsl_edma_eng
return -EINVAL;
}
+static int fsl_edma_child_to_chan_id(struct platform_device *pdev,
+ struct fsl_edma_engine *fsl_edma,
+ struct device_node *child,
+ struct resource *parent_res)
+{
+ const struct fsl_edma_drvdata *drvdata = fsl_edma->drvdata;
+ struct resource child_res;
+ u32 ch_id;
+ int ret;
+
+ ret = of_address_to_resource(child, 0, &child_res);
+ if (ret)
+ return ret;
+
+ if (child_res.start < parent_res->start + drvdata->chreg_off)
+ return -EINVAL;
+
+ ch_id = (child_res.start - parent_res->start - drvdata->chreg_off)
+ / drvdata->chreg_space_sz;
+
+ if (ch_id >= fsl_edma->n_chans)
+ return -EINVAL;
+
+ return ch_id;
+}
+
+static int fsl_edma_configure_chan_from_dt(struct platform_device *pdev,
+ struct fsl_edma_engine *fsl_edma)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct resource parent_res;
+ struct device_node *child;
+ int ret;
+
+ ret = of_address_to_resource(np, 0, &parent_res);
+ if (ret)
+ return ret;
+
+ for_each_available_child_of_node(np, child) {
+ struct fsl_edma_chan *fsl_chan;
+ int ch_id, irq;
+
+ ch_id = fsl_edma_child_to_chan_id(pdev, fsl_edma, child,
+ &parent_res);
+ if (ch_id < 0) {
+ dev_err(&pdev->dev, "invalid channel in %pOFn\n", child);
+ of_node_put(child);
+ return -EINVAL;
+ }
+
+ if (fsl_edma->chan_masked & BIT(ch_id))
+ continue;
+
+ fsl_chan = &fsl_edma->chans[ch_id];
+
+ irq = of_irq_get(child, 0);
+ if (irq == -EPROBE_DEFER) {
+ of_node_put(child);
+ return -EPROBE_DEFER;
+ }
+ if (irq > 0) {
+ fsl_chan->txirq = irq;
+ fsl_chan->irq_handler = fsl_edma3_tx_handler;
+ }
+ }
+
+ return 0;
+}
+
+static int fsl_edma_configure_chan_iommu(struct platform_device *pdev,
+ struct fsl_edma_engine *fsl_edma)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct resource parent_res;
+ struct device_node *child;
+ struct dma_chan *chan;
+ int ret;
+
+ ret = of_address_to_resource(np, 0, &parent_res);
+ if (ret)
+ return ret;
+
+ for_each_available_child_of_node(np, child) {
+ struct fsl_edma_chan *fsl_chan;
+ int ch_id;
+
+ if (!of_property_present(child, "iommus"))
+ continue;
+
+ ch_id = fsl_edma_child_to_chan_id(pdev, fsl_edma, child,
+ &parent_res);
+ if (ch_id < 0)
+ continue;
+
+ if (fsl_edma->chan_masked & BIT(ch_id))
+ continue;
+
+ fsl_chan = &fsl_edma->chans[ch_id];
+
+ list_for_each_entry(chan, &fsl_edma->dma_dev.channels,
+ device_node) {
+ struct device *chdev;
+
+ if (to_fsl_edma_chan(chan) != fsl_chan)
+ continue;
+
+ chdev = dmaengine_chan_dev(chan);
+ if (fsl_edma->drvdata->flags & FSL_EDMA_DRV_TCD64)
+ dma_coerce_mask_and_coherent(chdev,
+ DMA_BIT_MASK(64));
+ else
+ dma_coerce_mask_and_coherent(chdev,
+ DMA_BIT_MASK(32));
+ ret = of_dma_configure(chdev, child, true);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "IOMMU config failed for channel %d: %d\n",
+ ch_id, ret);
+ of_node_put(child);
+ return ret;
+ }
+
+ chan->chan_dev->chan_dma_dev = true;
+ break;
+ }
+ }
+
+ return 0;
+}
+
static int fsl_edma_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
@@ -836,6 +970,10 @@ static int fsl_edma_probe(struct platform_device *pdev)
clk_disable_unprepare(fsl_chan->clk);
}
+ ret = fsl_edma_configure_chan_from_dt(pdev, fsl_edma);
+ if (ret)
+ return ret;
+
ret = fsl_edma->drvdata->setup_irq(pdev, fsl_edma);
if (ret)
return ret;
@@ -898,6 +1036,10 @@ static int fsl_edma_probe(struct platform_device *pdev)
return dev_err_probe(&pdev->dev, ret,
"Can't register Freescale eDMA engine.\n");
+ ret = fsl_edma_configure_chan_iommu(pdev, fsl_edma);
+ if (ret)
+ return ret;
+
ret = devm_of_dma_controller_register(&pdev->dev, np,
drvdata->dmamuxs ? fsl_edma_xlate : fsl_edma3_xlate,
fsl_edma);
--
2.34.1
^ permalink raw reply [flat|nested] 8+ messages in thread* [PATCH v3 7/7] arm64: dts: imx95: convert eDMA to per-channel child nodes
2026-11-02 6:49 [PATCH v3 0/7] dmaengine: add DMA channel bus and fsl-edma per-channel IOMMU support Peng Fan (OSS)
` (5 preceding siblings ...)
2026-11-02 6:50 ` [PATCH v3 6/7] dmaengine: fsl-edma: support per-channel DT child nodes Peng Fan (OSS)
@ 2026-11-02 6:50 ` Peng Fan (OSS)
6 siblings, 0 replies; 8+ messages in thread
From: Peng Fan (OSS) @ 2026-11-02 6:50 UTC (permalink / raw)
To: Frank Li, Vinod Koul, Joerg Roedel (AMD),
Will Deacon, Robin Murphy, Laxman Dewangan, Jon Hunter,
Thierry Reding, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam
Cc: Frank Li, Larisa IIeana Grigore, imx, dmaengine, linux-kernel,
iommu, linux-tegra, devicetree, linux-arm-kernel, Peng Fan
From: Peng Fan <peng.fan@nxp.com>
Convert edma2 and edma3 from flat interrupt arrays at the parent node
to per-channel child nodes (dma-channel@<addr>). Each child carries
its own reg (real per-channel MMIO region) and interrupts property.
edma2 (64 channels at 0x42000000):
- Channel N at 0x42010000 + N * 0x8000 (size 0x8000)
- Paired interrupts: SPI 128-159, two channels per SPI
edma3 (64 channels at 0x42210000):
- Channel N at 0x42220000 + N * 0x8000 (size 0x8000)
- Paired interrupts: SPI 256-287, two channels per SPI
edma1 (imx93-edma3, 31 channels with 1:1 non-paired interrupts) is
left unchanged as it uses a different interrupt scheme.
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
arch/arm64/boot/dts/freescale/imx95.dtsi | 774 ++++++++++++++++++++++++++-----
1 file changed, 646 insertions(+), 128 deletions(-)
diff --git a/arch/arm64/boot/dts/freescale/imx95.dtsi b/arch/arm64/boot/dts/freescale/imx95.dtsi
index d20c2498b9aa2..64570703ce6cb 100644
--- a/arch/arm64/boot/dts/freescale/imx95.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx95.dtsi
@@ -635,148 +635,666 @@ edma2: dma-controller@42000000 {
compatible = "fsl,imx95-edma5";
reg = <0x42000000 0x210000>;
#dma-cells = <3>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
dma-channels = <64>;
/* channels 0 and 1 reserved for V2X fast hash */
dma-channel-mask = <0x3>;
- interrupts = <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 139 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 139 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 151 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 151 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 157 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 157 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 158 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 158 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 159 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 159 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&scmi_clk IMX95_CLK_BUSWAKEUP>;
clock-names = "dma";
+
+ dma-channel@42010000 {
+ reg = <0x42010000 0x8000>;
+ interrupts = <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42018000 {
+ reg = <0x42018000 0x8000>;
+ interrupts = <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42020000 {
+ reg = <0x42020000 0x8000>;
+ interrupts = <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42028000 {
+ reg = <0x42028000 0x8000>;
+ interrupts = <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42030000 {
+ reg = <0x42030000 0x8000>;
+ interrupts = <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42038000 {
+ reg = <0x42038000 0x8000>;
+ interrupts = <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42040000 {
+ reg = <0x42040000 0x8000>;
+ interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42048000 {
+ reg = <0x42048000 0x8000>;
+ interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42050000 {
+ reg = <0x42050000 0x8000>;
+ interrupts = <GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42058000 {
+ reg = <0x42058000 0x8000>;
+ interrupts = <GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42060000 {
+ reg = <0x42060000 0x8000>;
+ interrupts = <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42068000 {
+ reg = <0x42068000 0x8000>;
+ interrupts = <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42070000 {
+ reg = <0x42070000 0x8000>;
+ interrupts = <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42078000 {
+ reg = <0x42078000 0x8000>;
+ interrupts = <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42080000 {
+ reg = <0x42080000 0x8000>;
+ interrupts = <GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42088000 {
+ reg = <0x42088000 0x8000>;
+ interrupts = <GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42090000 {
+ reg = <0x42090000 0x8000>;
+ interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42098000 {
+ reg = <0x42098000 0x8000>;
+ interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@420a0000 {
+ reg = <0x420a0000 0x8000>;
+ interrupts = <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@420a8000 {
+ reg = <0x420a8000 0x8000>;
+ interrupts = <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@420b0000 {
+ reg = <0x420b0000 0x8000>;
+ interrupts = <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@420b8000 {
+ reg = <0x420b8000 0x8000>;
+ interrupts = <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@420c0000 {
+ reg = <0x420c0000 0x8000>;
+ interrupts = <GIC_SPI 139 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@420c8000 {
+ reg = <0x420c8000 0x8000>;
+ interrupts = <GIC_SPI 139 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@420d0000 {
+ reg = <0x420d0000 0x8000>;
+ interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@420d8000 {
+ reg = <0x420d8000 0x8000>;
+ interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@420e0000 {
+ reg = <0x420e0000 0x8000>;
+ interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@420e8000 {
+ reg = <0x420e8000 0x8000>;
+ interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@420f0000 {
+ reg = <0x420f0000 0x8000>;
+ interrupts = <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@420f8000 {
+ reg = <0x420f8000 0x8000>;
+ interrupts = <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42100000 {
+ reg = <0x42100000 0x8000>;
+ interrupts = <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42108000 {
+ reg = <0x42108000 0x8000>;
+ interrupts = <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42110000 {
+ reg = <0x42110000 0x8000>;
+ interrupts = <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42118000 {
+ reg = <0x42118000 0x8000>;
+ interrupts = <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42120000 {
+ reg = <0x42120000 0x8000>;
+ interrupts = <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42128000 {
+ reg = <0x42128000 0x8000>;
+ interrupts = <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42130000 {
+ reg = <0x42130000 0x8000>;
+ interrupts = <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42138000 {
+ reg = <0x42138000 0x8000>;
+ interrupts = <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42140000 {
+ reg = <0x42140000 0x8000>;
+ interrupts = <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42148000 {
+ reg = <0x42148000 0x8000>;
+ interrupts = <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42150000 {
+ reg = <0x42150000 0x8000>;
+ interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42158000 {
+ reg = <0x42158000 0x8000>;
+ interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42160000 {
+ reg = <0x42160000 0x8000>;
+ interrupts = <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42168000 {
+ reg = <0x42168000 0x8000>;
+ interrupts = <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42170000 {
+ reg = <0x42170000 0x8000>;
+ interrupts = <GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42178000 {
+ reg = <0x42178000 0x8000>;
+ interrupts = <GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42180000 {
+ reg = <0x42180000 0x8000>;
+ interrupts = <GIC_SPI 151 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42188000 {
+ reg = <0x42188000 0x8000>;
+ interrupts = <GIC_SPI 151 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42190000 {
+ reg = <0x42190000 0x8000>;
+ interrupts = <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42198000 {
+ reg = <0x42198000 0x8000>;
+ interrupts = <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@421a0000 {
+ reg = <0x421a0000 0x8000>;
+ interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@421a8000 {
+ reg = <0x421a8000 0x8000>;
+ interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@421b0000 {
+ reg = <0x421b0000 0x8000>;
+ interrupts = <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@421b8000 {
+ reg = <0x421b8000 0x8000>;
+ interrupts = <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@421c0000 {
+ reg = <0x421c0000 0x8000>;
+ interrupts = <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@421c8000 {
+ reg = <0x421c8000 0x8000>;
+ interrupts = <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@421d0000 {
+ reg = <0x421d0000 0x8000>;
+ interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@421d8000 {
+ reg = <0x421d8000 0x8000>;
+ interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@421e0000 {
+ reg = <0x421e0000 0x8000>;
+ interrupts = <GIC_SPI 157 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@421e8000 {
+ reg = <0x421e8000 0x8000>;
+ interrupts = <GIC_SPI 157 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@421f0000 {
+ reg = <0x421f0000 0x8000>;
+ interrupts = <GIC_SPI 158 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@421f8000 {
+ reg = <0x421f8000 0x8000>;
+ interrupts = <GIC_SPI 158 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42200000 {
+ reg = <0x42200000 0x8000>;
+ interrupts = <GIC_SPI 159 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42208000 {
+ reg = <0x42208000 0x8000>;
+ interrupts = <GIC_SPI 159 IRQ_TYPE_LEVEL_HIGH>;
+ };
};
edma3: dma-controller@42210000 {
compatible = "fsl,imx95-edma5";
reg = <0x42210000 0x210000>;
#dma-cells = <3>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
dma-channels = <64>;
- interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 257 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 257 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 258 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 258 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 259 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 259 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 260 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 260 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 261 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 261 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 262 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 262 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 263 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 263 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 264 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 264 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 265 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 265 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 266 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 266 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 267 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 267 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 269 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 269 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 270 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 270 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 271 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 271 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 272 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 272 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 273 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 273 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 274 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 274 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 275 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 275 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 276 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 276 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 277 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 277 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 278 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 278 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 279 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 279 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 280 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 280 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 281 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 281 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 282 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 282 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 283 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 283 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 284 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 284 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 285 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 285 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 286 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 286 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 287 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 287 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&scmi_clk IMX95_CLK_BUSWAKEUP>;
clock-names = "dma";
+
+ dma-channel@42220000 {
+ reg = <0x42220000 0x8000>;
+ interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42228000 {
+ reg = <0x42228000 0x8000>;
+ interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42230000 {
+ reg = <0x42230000 0x8000>;
+ interrupts = <GIC_SPI 257 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42238000 {
+ reg = <0x42238000 0x8000>;
+ interrupts = <GIC_SPI 257 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42240000 {
+ reg = <0x42240000 0x8000>;
+ interrupts = <GIC_SPI 258 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42248000 {
+ reg = <0x42248000 0x8000>;
+ interrupts = <GIC_SPI 258 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42250000 {
+ reg = <0x42250000 0x8000>;
+ interrupts = <GIC_SPI 259 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42258000 {
+ reg = <0x42258000 0x8000>;
+ interrupts = <GIC_SPI 259 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42260000 {
+ reg = <0x42260000 0x8000>;
+ interrupts = <GIC_SPI 260 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42268000 {
+ reg = <0x42268000 0x8000>;
+ interrupts = <GIC_SPI 260 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42270000 {
+ reg = <0x42270000 0x8000>;
+ interrupts = <GIC_SPI 261 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42278000 {
+ reg = <0x42278000 0x8000>;
+ interrupts = <GIC_SPI 261 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42280000 {
+ reg = <0x42280000 0x8000>;
+ interrupts = <GIC_SPI 262 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42288000 {
+ reg = <0x42288000 0x8000>;
+ interrupts = <GIC_SPI 262 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42290000 {
+ reg = <0x42290000 0x8000>;
+ interrupts = <GIC_SPI 263 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42298000 {
+ reg = <0x42298000 0x8000>;
+ interrupts = <GIC_SPI 263 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@422a0000 {
+ reg = <0x422a0000 0x8000>;
+ interrupts = <GIC_SPI 264 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@422a8000 {
+ reg = <0x422a8000 0x8000>;
+ interrupts = <GIC_SPI 264 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@422b0000 {
+ reg = <0x422b0000 0x8000>;
+ interrupts = <GIC_SPI 265 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@422b8000 {
+ reg = <0x422b8000 0x8000>;
+ interrupts = <GIC_SPI 265 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@422c0000 {
+ reg = <0x422c0000 0x8000>;
+ interrupts = <GIC_SPI 266 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@422c8000 {
+ reg = <0x422c8000 0x8000>;
+ interrupts = <GIC_SPI 266 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@422d0000 {
+ reg = <0x422d0000 0x8000>;
+ interrupts = <GIC_SPI 267 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@422d8000 {
+ reg = <0x422d8000 0x8000>;
+ interrupts = <GIC_SPI 267 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@422e0000 {
+ reg = <0x422e0000 0x8000>;
+ interrupts = <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@422e8000 {
+ reg = <0x422e8000 0x8000>;
+ interrupts = <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@422f0000 {
+ reg = <0x422f0000 0x8000>;
+ interrupts = <GIC_SPI 269 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@422f8000 {
+ reg = <0x422f8000 0x8000>;
+ interrupts = <GIC_SPI 269 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42300000 {
+ reg = <0x42300000 0x8000>;
+ interrupts = <GIC_SPI 270 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42308000 {
+ reg = <0x42308000 0x8000>;
+ interrupts = <GIC_SPI 270 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42310000 {
+ reg = <0x42310000 0x8000>;
+ interrupts = <GIC_SPI 271 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42318000 {
+ reg = <0x42318000 0x8000>;
+ interrupts = <GIC_SPI 271 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42320000 {
+ reg = <0x42320000 0x8000>;
+ interrupts = <GIC_SPI 272 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42328000 {
+ reg = <0x42328000 0x8000>;
+ interrupts = <GIC_SPI 272 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42330000 {
+ reg = <0x42330000 0x8000>;
+ interrupts = <GIC_SPI 273 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42338000 {
+ reg = <0x42338000 0x8000>;
+ interrupts = <GIC_SPI 273 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42340000 {
+ reg = <0x42340000 0x8000>;
+ interrupts = <GIC_SPI 274 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42348000 {
+ reg = <0x42348000 0x8000>;
+ interrupts = <GIC_SPI 274 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42350000 {
+ reg = <0x42350000 0x8000>;
+ interrupts = <GIC_SPI 275 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42358000 {
+ reg = <0x42358000 0x8000>;
+ interrupts = <GIC_SPI 275 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42360000 {
+ reg = <0x42360000 0x8000>;
+ interrupts = <GIC_SPI 276 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42368000 {
+ reg = <0x42368000 0x8000>;
+ interrupts = <GIC_SPI 276 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42370000 {
+ reg = <0x42370000 0x8000>;
+ interrupts = <GIC_SPI 277 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42378000 {
+ reg = <0x42378000 0x8000>;
+ interrupts = <GIC_SPI 277 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42380000 {
+ reg = <0x42380000 0x8000>;
+ interrupts = <GIC_SPI 278 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42388000 {
+ reg = <0x42388000 0x8000>;
+ interrupts = <GIC_SPI 278 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42390000 {
+ reg = <0x42390000 0x8000>;
+ interrupts = <GIC_SPI 279 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42398000 {
+ reg = <0x42398000 0x8000>;
+ interrupts = <GIC_SPI 279 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@423a0000 {
+ reg = <0x423a0000 0x8000>;
+ interrupts = <GIC_SPI 280 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@423a8000 {
+ reg = <0x423a8000 0x8000>;
+ interrupts = <GIC_SPI 280 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@423b0000 {
+ reg = <0x423b0000 0x8000>;
+ interrupts = <GIC_SPI 281 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@423b8000 {
+ reg = <0x423b8000 0x8000>;
+ interrupts = <GIC_SPI 281 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@423c0000 {
+ reg = <0x423c0000 0x8000>;
+ interrupts = <GIC_SPI 282 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@423c8000 {
+ reg = <0x423c8000 0x8000>;
+ interrupts = <GIC_SPI 282 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@423d0000 {
+ reg = <0x423d0000 0x8000>;
+ interrupts = <GIC_SPI 283 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@423d8000 {
+ reg = <0x423d8000 0x8000>;
+ interrupts = <GIC_SPI 283 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@423e0000 {
+ reg = <0x423e0000 0x8000>;
+ interrupts = <GIC_SPI 284 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@423e8000 {
+ reg = <0x423e8000 0x8000>;
+ interrupts = <GIC_SPI 284 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@423f0000 {
+ reg = <0x423f0000 0x8000>;
+ interrupts = <GIC_SPI 285 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@423f8000 {
+ reg = <0x423f8000 0x8000>;
+ interrupts = <GIC_SPI 285 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42400000 {
+ reg = <0x42400000 0x8000>;
+ interrupts = <GIC_SPI 286 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42408000 {
+ reg = <0x42408000 0x8000>;
+ interrupts = <GIC_SPI 286 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42410000 {
+ reg = <0x42410000 0x8000>;
+ interrupts = <GIC_SPI 287 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dma-channel@42418000 {
+ reg = <0x42418000 0x8000>;
+ interrupts = <GIC_SPI 287 IRQ_TYPE_LEVEL_HIGH>;
+ };
};
mu7: mailbox@42430000 {
--
2.34.1
^ permalink raw reply [flat|nested] 8+ messages in thread