Loading Documentation/devicetree/bindings/dma/fsl-qdma.txt 0 → 100644 +57 −0 Original line number Original line Diff line number Diff line NXP Layerscape SoC qDMA Controller ================================== This device follows the generic DMA bindings defined in dma/dma.txt. Required properties: - compatible: Must be one of "fsl,ls1021a-qdma": for LS1021A Board "fsl,ls1043a-qdma": for ls1043A Board "fsl,ls1046a-qdma": for ls1046A Board - reg: Should contain the register's base address and length. - interrupts: Should contain a reference to the interrupt used by this device. - interrupt-names: Should contain interrupt names: "qdma-queue0": the block0 interrupt "qdma-queue1": the block1 interrupt "qdma-queue2": the block2 interrupt "qdma-queue3": the block3 interrupt "qdma-error": the error interrupt - fsl,dma-queues: Should contain number of queues supported. - dma-channels: Number of DMA channels supported - block-number: the virtual block number - block-offset: the offset of different virtual block - status-sizes: status queue size of per virtual block - queue-sizes: command queue size of per virtual block, the size number based on queues Optional properties: - dma-channels: Number of DMA channels supported by the controller. - big-endian: If present registers and hardware scatter/gather descriptors of the qDMA are implemented in big endian mode, otherwise in little mode. Examples: qdma: dma-controller@8390000 { compatible = "fsl,ls1021a-qdma"; reg = <0x0 0x8388000 0x0 0x1000>, /* Controller regs */ <0x0 0x8389000 0x0 0x1000>, /* Status regs */ <0x0 0x838a000 0x0 0x2000>; /* Block regs */ interrupts = <GIC_SPI 185 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>; interrupt-names = "qdma-error", "qdma-queue0", "qdma-queue1"; dma-channels = <8>; block-number = <2>; block-offset = <0x1000>; fsl,dma-queues = <2>; status-sizes = <64>; queue-sizes = <64 64>; big-endian; }; DMA clients must use the format described in dma/dma.txt file. drivers/dma/Kconfig +14 −0 Original line number Original line Diff line number Diff line Loading @@ -218,6 +218,20 @@ config FSL_EDMA multiplexing capability for DMA request sources(slot). multiplexing capability for DMA request sources(slot). This module can be found on Freescale Vybrid and LS-1 SoCs. This module can be found on Freescale Vybrid and LS-1 SoCs. config FSL_QDMA tristate "NXP Layerscape qDMA engine support" depends on ARM || ARM64 select DMA_ENGINE select DMA_VIRTUAL_CHANNELS select DMA_ENGINE_RAID select ASYNC_TX_ENABLE_CHANNEL_SWITCH help Support the NXP Layerscape qDMA engine with command queue and legacy mode. Channel virtualization is supported through enqueuing of DMA jobs to, or dequeuing DMA jobs from, different work queues. This module can be found on NXP Layerscape SoCs. The qdma driver only work on SoCs with a DPAA hardware block. config FSL_RAID config FSL_RAID tristate "Freescale RAID engine Support" tristate "Freescale RAID engine Support" depends on FSL_SOC && !ASYNC_TX_ENABLE_CHANNEL_SWITCH depends on FSL_SOC && !ASYNC_TX_ENABLE_CHANNEL_SWITCH Loading drivers/dma/Makefile +1 −0 Original line number Original line Diff line number Diff line Loading @@ -33,6 +33,7 @@ obj-$(CONFIG_EP93XX_DMA) += ep93xx_dma.o obj-$(CONFIG_FSL_DMA) += fsldma.o obj-$(CONFIG_FSL_DMA) += fsldma.o obj-$(CONFIG_FSL_EDMA) += fsl-edma.o fsl-edma-common.o obj-$(CONFIG_FSL_EDMA) += fsl-edma.o fsl-edma-common.o obj-$(CONFIG_MCF_EDMA) += mcf-edma.o fsl-edma-common.o obj-$(CONFIG_MCF_EDMA) += mcf-edma.o fsl-edma-common.o obj-$(CONFIG_FSL_QDMA) += fsl-qdma.o obj-$(CONFIG_FSL_RAID) += fsl_raid.o obj-$(CONFIG_FSL_RAID) += fsl_raid.o obj-$(CONFIG_HSU_DMA) += hsu/ obj-$(CONFIG_HSU_DMA) += hsu/ obj-$(CONFIG_IMG_MDC_DMA) += img-mdc-dma.o obj-$(CONFIG_IMG_MDC_DMA) += img-mdc-dma.o Loading drivers/dma/fsl-edma-common.c +63 −7 Original line number Original line Diff line number Diff line Loading @@ -6,6 +6,7 @@ #include <linux/dmapool.h> #include <linux/dmapool.h> #include <linux/module.h> #include <linux/module.h> #include <linux/slab.h> #include <linux/slab.h> #include <linux/dma-mapping.h> #include "fsl-edma-common.h" #include "fsl-edma-common.h" Loading Loading @@ -173,12 +174,62 @@ int fsl_edma_resume(struct dma_chan *chan) } } EXPORT_SYMBOL_GPL(fsl_edma_resume); EXPORT_SYMBOL_GPL(fsl_edma_resume); static void fsl_edma_unprep_slave_dma(struct fsl_edma_chan *fsl_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, fsl_chan->dma_dir, 0); fsl_chan->dma_dir = DMA_NONE; } 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; enum dma_data_direction dma_dir; phys_addr_t addr = 0; u32 size = 0; switch (dir) { case DMA_MEM_TO_DEV: dma_dir = DMA_FROM_DEVICE; addr = fsl_chan->cfg.dst_addr; size = fsl_chan->cfg.dst_maxburst; break; case DMA_DEV_TO_MEM: dma_dir = DMA_TO_DEVICE; addr = fsl_chan->cfg.src_addr; size = fsl_chan->cfg.src_maxburst; break; default: dma_dir = DMA_NONE; break; } /* Already mapped for this config? */ if (fsl_chan->dma_dir == dma_dir) return true; fsl_edma_unprep_slave_dma(fsl_chan); fsl_chan->dma_dev_addr = dma_map_resource(dev, addr, size, dma_dir, 0); if (dma_mapping_error(dev, fsl_chan->dma_dev_addr)) return false; fsl_chan->dma_dev_size = size; fsl_chan->dma_dir = dma_dir; return true; } int fsl_edma_slave_config(struct dma_chan *chan, int fsl_edma_slave_config(struct dma_chan *chan, struct dma_slave_config *cfg) struct dma_slave_config *cfg) { { struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan); struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan); memcpy(&fsl_chan->cfg, cfg, sizeof(*cfg)); memcpy(&fsl_chan->cfg, cfg, sizeof(*cfg)); fsl_edma_unprep_slave_dma(fsl_chan); return 0; return 0; } } Loading Loading @@ -339,9 +390,7 @@ static struct fsl_edma_desc *fsl_edma_alloc_desc(struct fsl_edma_chan *fsl_chan, struct fsl_edma_desc *fsl_desc; struct fsl_edma_desc *fsl_desc; int i; int i; fsl_desc = kzalloc(sizeof(*fsl_desc) + fsl_desc = kzalloc(struct_size(fsl_desc, tcd, sg_len), GFP_NOWAIT); sizeof(struct fsl_edma_sw_tcd) * sg_len, GFP_NOWAIT); if (!fsl_desc) if (!fsl_desc) return NULL; return NULL; Loading Loading @@ -378,6 +427,9 @@ struct dma_async_tx_descriptor *fsl_edma_prep_dma_cyclic( if (!is_slave_direction(direction)) if (!is_slave_direction(direction)) return NULL; return NULL; if (!fsl_edma_prep_slave_dma(fsl_chan, direction)) return NULL; sg_len = buf_len / period_len; sg_len = buf_len / period_len; fsl_desc = fsl_edma_alloc_desc(fsl_chan, sg_len); fsl_desc = fsl_edma_alloc_desc(fsl_chan, sg_len); if (!fsl_desc) if (!fsl_desc) Loading Loading @@ -409,11 +461,11 @@ struct dma_async_tx_descriptor *fsl_edma_prep_dma_cyclic( if (direction == DMA_MEM_TO_DEV) { if (direction == DMA_MEM_TO_DEV) { src_addr = dma_buf_next; src_addr = dma_buf_next; dst_addr = fsl_chan->cfg.dst_addr; dst_addr = fsl_chan->dma_dev_addr; soff = fsl_chan->cfg.dst_addr_width; soff = fsl_chan->cfg.dst_addr_width; doff = 0; doff = 0; } else { } else { src_addr = fsl_chan->cfg.src_addr; src_addr = fsl_chan->dma_dev_addr; dst_addr = dma_buf_next; dst_addr = dma_buf_next; soff = 0; soff = 0; doff = fsl_chan->cfg.src_addr_width; doff = fsl_chan->cfg.src_addr_width; Loading Loading @@ -444,6 +496,9 @@ struct dma_async_tx_descriptor *fsl_edma_prep_slave_sg( if (!is_slave_direction(direction)) if (!is_slave_direction(direction)) return NULL; return NULL; if (!fsl_edma_prep_slave_dma(fsl_chan, direction)) return NULL; fsl_desc = fsl_edma_alloc_desc(fsl_chan, sg_len); fsl_desc = fsl_edma_alloc_desc(fsl_chan, sg_len); if (!fsl_desc) if (!fsl_desc) return NULL; return NULL; Loading @@ -468,11 +523,11 @@ struct dma_async_tx_descriptor *fsl_edma_prep_slave_sg( if (direction == DMA_MEM_TO_DEV) { if (direction == DMA_MEM_TO_DEV) { src_addr = sg_dma_address(sg); src_addr = sg_dma_address(sg); dst_addr = fsl_chan->cfg.dst_addr; dst_addr = fsl_chan->dma_dev_addr; soff = fsl_chan->cfg.dst_addr_width; soff = fsl_chan->cfg.dst_addr_width; doff = 0; doff = 0; } else { } else { src_addr = fsl_chan->cfg.src_addr; src_addr = fsl_chan->dma_dev_addr; dst_addr = sg_dma_address(sg); dst_addr = sg_dma_address(sg); soff = 0; soff = 0; doff = fsl_chan->cfg.src_addr_width; doff = fsl_chan->cfg.src_addr_width; Loading Loading @@ -555,6 +610,7 @@ void fsl_edma_free_chan_resources(struct dma_chan *chan) fsl_edma_chan_mux(fsl_chan, 0, false); fsl_edma_chan_mux(fsl_chan, 0, false); fsl_chan->edesc = NULL; fsl_chan->edesc = NULL; vchan_get_all_descriptors(&fsl_chan->vchan, &head); vchan_get_all_descriptors(&fsl_chan->vchan, &head); fsl_edma_unprep_slave_dma(fsl_chan); spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags); spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags); vchan_dma_desc_free_list(&fsl_chan->vchan, &head); vchan_dma_desc_free_list(&fsl_chan->vchan, &head); Loading drivers/dma/fsl-edma-common.h +4 −0 Original line number Original line Diff line number Diff line Loading @@ -6,6 +6,7 @@ #ifndef _FSL_EDMA_COMMON_H_ #ifndef _FSL_EDMA_COMMON_H_ #define _FSL_EDMA_COMMON_H_ #define _FSL_EDMA_COMMON_H_ #include <linux/dma-direction.h> #include "virt-dma.h" #include "virt-dma.h" #define EDMA_CR_EDBG BIT(1) #define EDMA_CR_EDBG BIT(1) Loading Loading @@ -120,6 +121,9 @@ struct fsl_edma_chan { struct dma_slave_config cfg; struct dma_slave_config cfg; u32 attr; u32 attr; struct dma_pool *tcd_pool; struct dma_pool *tcd_pool; dma_addr_t dma_dev_addr; u32 dma_dev_size; enum dma_data_direction dma_dir; }; }; struct fsl_edma_desc { struct fsl_edma_desc { Loading Loading
Documentation/devicetree/bindings/dma/fsl-qdma.txt 0 → 100644 +57 −0 Original line number Original line Diff line number Diff line NXP Layerscape SoC qDMA Controller ================================== This device follows the generic DMA bindings defined in dma/dma.txt. Required properties: - compatible: Must be one of "fsl,ls1021a-qdma": for LS1021A Board "fsl,ls1043a-qdma": for ls1043A Board "fsl,ls1046a-qdma": for ls1046A Board - reg: Should contain the register's base address and length. - interrupts: Should contain a reference to the interrupt used by this device. - interrupt-names: Should contain interrupt names: "qdma-queue0": the block0 interrupt "qdma-queue1": the block1 interrupt "qdma-queue2": the block2 interrupt "qdma-queue3": the block3 interrupt "qdma-error": the error interrupt - fsl,dma-queues: Should contain number of queues supported. - dma-channels: Number of DMA channels supported - block-number: the virtual block number - block-offset: the offset of different virtual block - status-sizes: status queue size of per virtual block - queue-sizes: command queue size of per virtual block, the size number based on queues Optional properties: - dma-channels: Number of DMA channels supported by the controller. - big-endian: If present registers and hardware scatter/gather descriptors of the qDMA are implemented in big endian mode, otherwise in little mode. Examples: qdma: dma-controller@8390000 { compatible = "fsl,ls1021a-qdma"; reg = <0x0 0x8388000 0x0 0x1000>, /* Controller regs */ <0x0 0x8389000 0x0 0x1000>, /* Status regs */ <0x0 0x838a000 0x0 0x2000>; /* Block regs */ interrupts = <GIC_SPI 185 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>; interrupt-names = "qdma-error", "qdma-queue0", "qdma-queue1"; dma-channels = <8>; block-number = <2>; block-offset = <0x1000>; fsl,dma-queues = <2>; status-sizes = <64>; queue-sizes = <64 64>; big-endian; }; DMA clients must use the format described in dma/dma.txt file.
drivers/dma/Kconfig +14 −0 Original line number Original line Diff line number Diff line Loading @@ -218,6 +218,20 @@ config FSL_EDMA multiplexing capability for DMA request sources(slot). multiplexing capability for DMA request sources(slot). This module can be found on Freescale Vybrid and LS-1 SoCs. This module can be found on Freescale Vybrid and LS-1 SoCs. config FSL_QDMA tristate "NXP Layerscape qDMA engine support" depends on ARM || ARM64 select DMA_ENGINE select DMA_VIRTUAL_CHANNELS select DMA_ENGINE_RAID select ASYNC_TX_ENABLE_CHANNEL_SWITCH help Support the NXP Layerscape qDMA engine with command queue and legacy mode. Channel virtualization is supported through enqueuing of DMA jobs to, or dequeuing DMA jobs from, different work queues. This module can be found on NXP Layerscape SoCs. The qdma driver only work on SoCs with a DPAA hardware block. config FSL_RAID config FSL_RAID tristate "Freescale RAID engine Support" tristate "Freescale RAID engine Support" depends on FSL_SOC && !ASYNC_TX_ENABLE_CHANNEL_SWITCH depends on FSL_SOC && !ASYNC_TX_ENABLE_CHANNEL_SWITCH Loading
drivers/dma/Makefile +1 −0 Original line number Original line Diff line number Diff line Loading @@ -33,6 +33,7 @@ obj-$(CONFIG_EP93XX_DMA) += ep93xx_dma.o obj-$(CONFIG_FSL_DMA) += fsldma.o obj-$(CONFIG_FSL_DMA) += fsldma.o obj-$(CONFIG_FSL_EDMA) += fsl-edma.o fsl-edma-common.o obj-$(CONFIG_FSL_EDMA) += fsl-edma.o fsl-edma-common.o obj-$(CONFIG_MCF_EDMA) += mcf-edma.o fsl-edma-common.o obj-$(CONFIG_MCF_EDMA) += mcf-edma.o fsl-edma-common.o obj-$(CONFIG_FSL_QDMA) += fsl-qdma.o obj-$(CONFIG_FSL_RAID) += fsl_raid.o obj-$(CONFIG_FSL_RAID) += fsl_raid.o obj-$(CONFIG_HSU_DMA) += hsu/ obj-$(CONFIG_HSU_DMA) += hsu/ obj-$(CONFIG_IMG_MDC_DMA) += img-mdc-dma.o obj-$(CONFIG_IMG_MDC_DMA) += img-mdc-dma.o Loading
drivers/dma/fsl-edma-common.c +63 −7 Original line number Original line Diff line number Diff line Loading @@ -6,6 +6,7 @@ #include <linux/dmapool.h> #include <linux/dmapool.h> #include <linux/module.h> #include <linux/module.h> #include <linux/slab.h> #include <linux/slab.h> #include <linux/dma-mapping.h> #include "fsl-edma-common.h" #include "fsl-edma-common.h" Loading Loading @@ -173,12 +174,62 @@ int fsl_edma_resume(struct dma_chan *chan) } } EXPORT_SYMBOL_GPL(fsl_edma_resume); EXPORT_SYMBOL_GPL(fsl_edma_resume); static void fsl_edma_unprep_slave_dma(struct fsl_edma_chan *fsl_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, fsl_chan->dma_dir, 0); fsl_chan->dma_dir = DMA_NONE; } 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; enum dma_data_direction dma_dir; phys_addr_t addr = 0; u32 size = 0; switch (dir) { case DMA_MEM_TO_DEV: dma_dir = DMA_FROM_DEVICE; addr = fsl_chan->cfg.dst_addr; size = fsl_chan->cfg.dst_maxburst; break; case DMA_DEV_TO_MEM: dma_dir = DMA_TO_DEVICE; addr = fsl_chan->cfg.src_addr; size = fsl_chan->cfg.src_maxburst; break; default: dma_dir = DMA_NONE; break; } /* Already mapped for this config? */ if (fsl_chan->dma_dir == dma_dir) return true; fsl_edma_unprep_slave_dma(fsl_chan); fsl_chan->dma_dev_addr = dma_map_resource(dev, addr, size, dma_dir, 0); if (dma_mapping_error(dev, fsl_chan->dma_dev_addr)) return false; fsl_chan->dma_dev_size = size; fsl_chan->dma_dir = dma_dir; return true; } int fsl_edma_slave_config(struct dma_chan *chan, int fsl_edma_slave_config(struct dma_chan *chan, struct dma_slave_config *cfg) struct dma_slave_config *cfg) { { struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan); struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan); memcpy(&fsl_chan->cfg, cfg, sizeof(*cfg)); memcpy(&fsl_chan->cfg, cfg, sizeof(*cfg)); fsl_edma_unprep_slave_dma(fsl_chan); return 0; return 0; } } Loading Loading @@ -339,9 +390,7 @@ static struct fsl_edma_desc *fsl_edma_alloc_desc(struct fsl_edma_chan *fsl_chan, struct fsl_edma_desc *fsl_desc; struct fsl_edma_desc *fsl_desc; int i; int i; fsl_desc = kzalloc(sizeof(*fsl_desc) + fsl_desc = kzalloc(struct_size(fsl_desc, tcd, sg_len), GFP_NOWAIT); sizeof(struct fsl_edma_sw_tcd) * sg_len, GFP_NOWAIT); if (!fsl_desc) if (!fsl_desc) return NULL; return NULL; Loading Loading @@ -378,6 +427,9 @@ struct dma_async_tx_descriptor *fsl_edma_prep_dma_cyclic( if (!is_slave_direction(direction)) if (!is_slave_direction(direction)) return NULL; return NULL; if (!fsl_edma_prep_slave_dma(fsl_chan, direction)) return NULL; sg_len = buf_len / period_len; sg_len = buf_len / period_len; fsl_desc = fsl_edma_alloc_desc(fsl_chan, sg_len); fsl_desc = fsl_edma_alloc_desc(fsl_chan, sg_len); if (!fsl_desc) if (!fsl_desc) Loading Loading @@ -409,11 +461,11 @@ struct dma_async_tx_descriptor *fsl_edma_prep_dma_cyclic( if (direction == DMA_MEM_TO_DEV) { if (direction == DMA_MEM_TO_DEV) { src_addr = dma_buf_next; src_addr = dma_buf_next; dst_addr = fsl_chan->cfg.dst_addr; dst_addr = fsl_chan->dma_dev_addr; soff = fsl_chan->cfg.dst_addr_width; soff = fsl_chan->cfg.dst_addr_width; doff = 0; doff = 0; } else { } else { src_addr = fsl_chan->cfg.src_addr; src_addr = fsl_chan->dma_dev_addr; dst_addr = dma_buf_next; dst_addr = dma_buf_next; soff = 0; soff = 0; doff = fsl_chan->cfg.src_addr_width; doff = fsl_chan->cfg.src_addr_width; Loading Loading @@ -444,6 +496,9 @@ struct dma_async_tx_descriptor *fsl_edma_prep_slave_sg( if (!is_slave_direction(direction)) if (!is_slave_direction(direction)) return NULL; return NULL; if (!fsl_edma_prep_slave_dma(fsl_chan, direction)) return NULL; fsl_desc = fsl_edma_alloc_desc(fsl_chan, sg_len); fsl_desc = fsl_edma_alloc_desc(fsl_chan, sg_len); if (!fsl_desc) if (!fsl_desc) return NULL; return NULL; Loading @@ -468,11 +523,11 @@ struct dma_async_tx_descriptor *fsl_edma_prep_slave_sg( if (direction == DMA_MEM_TO_DEV) { if (direction == DMA_MEM_TO_DEV) { src_addr = sg_dma_address(sg); src_addr = sg_dma_address(sg); dst_addr = fsl_chan->cfg.dst_addr; dst_addr = fsl_chan->dma_dev_addr; soff = fsl_chan->cfg.dst_addr_width; soff = fsl_chan->cfg.dst_addr_width; doff = 0; doff = 0; } else { } else { src_addr = fsl_chan->cfg.src_addr; src_addr = fsl_chan->dma_dev_addr; dst_addr = sg_dma_address(sg); dst_addr = sg_dma_address(sg); soff = 0; soff = 0; doff = fsl_chan->cfg.src_addr_width; doff = fsl_chan->cfg.src_addr_width; Loading Loading @@ -555,6 +610,7 @@ void fsl_edma_free_chan_resources(struct dma_chan *chan) fsl_edma_chan_mux(fsl_chan, 0, false); fsl_edma_chan_mux(fsl_chan, 0, false); fsl_chan->edesc = NULL; fsl_chan->edesc = NULL; vchan_get_all_descriptors(&fsl_chan->vchan, &head); vchan_get_all_descriptors(&fsl_chan->vchan, &head); fsl_edma_unprep_slave_dma(fsl_chan); spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags); spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags); vchan_dma_desc_free_list(&fsl_chan->vchan, &head); vchan_dma_desc_free_list(&fsl_chan->vchan, &head); Loading
drivers/dma/fsl-edma-common.h +4 −0 Original line number Original line Diff line number Diff line Loading @@ -6,6 +6,7 @@ #ifndef _FSL_EDMA_COMMON_H_ #ifndef _FSL_EDMA_COMMON_H_ #define _FSL_EDMA_COMMON_H_ #define _FSL_EDMA_COMMON_H_ #include <linux/dma-direction.h> #include "virt-dma.h" #include "virt-dma.h" #define EDMA_CR_EDBG BIT(1) #define EDMA_CR_EDBG BIT(1) Loading Loading @@ -120,6 +121,9 @@ struct fsl_edma_chan { struct dma_slave_config cfg; struct dma_slave_config cfg; u32 attr; u32 attr; struct dma_pool *tcd_pool; struct dma_pool *tcd_pool; dma_addr_t dma_dev_addr; u32 dma_dev_size; enum dma_data_direction dma_dir; }; }; struct fsl_edma_desc { struct fsl_edma_desc { Loading