Loading Documentation/driver-api/dmaengine/client.rst +9 −0 Original line number Diff line number Diff line Loading @@ -80,6 +80,10 @@ The details of these operations are: - slave_sg: DMA a list of scatter gather buffers from/to a peripheral - peripheral_dma_vec: DMA an array of scatter gather buffers from/to a peripheral. Similar to slave_sg, but uses an array of dma_vec structures instead of a scatterlist. - dma_cyclic: Perform a cyclic DMA operation from/to a peripheral till the operation is explicitly stopped. Loading @@ -102,6 +106,11 @@ The details of these operations are: unsigned int sg_len, enum dma_data_direction direction, unsigned long flags); struct dma_async_tx_descriptor *dmaengine_prep_peripheral_dma_vec( struct dma_chan *chan, const struct dma_vec *vecs, size_t nents, enum dma_data_direction direction, unsigned long flags); struct dma_async_tx_descriptor *dmaengine_prep_dma_cyclic( struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len, size_t period_len, enum dma_data_direction direction); Loading Documentation/driver-api/dmaengine/provider.rst +10 −0 Original line number Diff line number Diff line Loading @@ -433,6 +433,12 @@ supported. - residue: Provides the residue bytes of the transfer for those that support residue. - ``device_prep_peripheral_dma_vec`` - Similar to ``device_prep_slave_sg``, but it takes a pointer to a array of ``dma_vec`` structures, which (in the long run) will replace scatterlists. - ``device_issue_pending`` - Takes the first transaction descriptor in the pending queue, Loading Loading @@ -544,6 +550,10 @@ dma_cookie_t - Not really relevant any more since the introduction of ``virt-dma`` that abstracts it away. dma_vec - A small structure that contains a DMA address and length. DMA_CTRL_ACK - If clear, the descriptor cannot be reused by provider until the Loading drivers/dma/dma-axi-dmac.c +40 −0 Original line number Diff line number Diff line Loading @@ -620,6 +620,45 @@ static struct axi_dmac_sg *axi_dmac_fill_linear_sg(struct axi_dmac_chan *chan, return sg; } static struct dma_async_tx_descriptor * axi_dmac_prep_peripheral_dma_vec(struct dma_chan *c, const struct dma_vec *vecs, size_t nb, enum dma_transfer_direction direction, unsigned long flags) { struct axi_dmac_chan *chan = to_axi_dmac_chan(c); struct axi_dmac_desc *desc; unsigned int num_sgs = 0; struct axi_dmac_sg *dsg; size_t i; if (direction != chan->direction) return NULL; for (i = 0; i < nb; i++) num_sgs += DIV_ROUND_UP(vecs[i].len, chan->max_length); desc = axi_dmac_alloc_desc(chan, num_sgs); if (!desc) return NULL; dsg = desc->sg; for (i = 0; i < nb; i++) { if (!axi_dmac_check_addr(chan, vecs[i].addr) || !axi_dmac_check_len(chan, vecs[i].len)) { kfree(desc); return NULL; } dsg = axi_dmac_fill_linear_sg(chan, direction, vecs[i].addr, 1, vecs[i].len, dsg); } desc->cyclic = false; return vchan_tx_prep(&chan->vchan, &desc->vdesc, flags); } static struct dma_async_tx_descriptor *axi_dmac_prep_slave_sg( struct dma_chan *c, struct scatterlist *sgl, unsigned int sg_len, enum dma_transfer_direction direction, Loading Loading @@ -1061,6 +1100,7 @@ static int axi_dmac_probe(struct platform_device *pdev) dma_dev->device_tx_status = dma_cookie_status; dma_dev->device_issue_pending = axi_dmac_issue_pending; dma_dev->device_prep_slave_sg = axi_dmac_prep_slave_sg; dma_dev->device_prep_peripheral_dma_vec = axi_dmac_prep_peripheral_dma_vec; dma_dev->device_prep_dma_cyclic = axi_dmac_prep_dma_cyclic; dma_dev->device_prep_interleaved_dma = axi_dmac_prep_interleaved; dma_dev->device_terminate_all = axi_dmac_terminate_all; Loading include/linux/dmaengine.h +33 −0 Original line number Diff line number Diff line Loading @@ -160,6 +160,16 @@ struct dma_interleaved_template { struct data_chunk sgl[]; }; /** * struct dma_vec - DMA vector * @addr: Bus address of the start of the vector * @len: Length in bytes of the DMA vector */ struct dma_vec { dma_addr_t addr; size_t len; }; /** * enum dma_ctrl_flags - DMA flags to augment operation preparation, * control completion, and communicate status. Loading Loading @@ -910,6 +920,10 @@ struct dma_device { struct dma_async_tx_descriptor *(*device_prep_dma_interrupt)( struct dma_chan *chan, unsigned long flags); struct dma_async_tx_descriptor *(*device_prep_peripheral_dma_vec)( struct dma_chan *chan, const struct dma_vec *vecs, size_t nents, enum dma_transfer_direction direction, unsigned long flags); struct dma_async_tx_descriptor *(*device_prep_slave_sg)( struct dma_chan *chan, struct scatterlist *sgl, unsigned int sg_len, enum dma_transfer_direction direction, Loading Loading @@ -973,6 +987,25 @@ static inline struct dma_async_tx_descriptor *dmaengine_prep_slave_single( dir, flags, NULL); } /** * dmaengine_prep_peripheral_dma_vec() - Prepare a DMA scatter-gather descriptor * @chan: The channel to be used for this descriptor * @vecs: The array of DMA vectors that should be transferred * @nents: The number of DMA vectors in the array * @dir: Specifies the direction of the data transfer * @flags: DMA engine flags */ static inline struct dma_async_tx_descriptor *dmaengine_prep_peripheral_dma_vec( struct dma_chan *chan, const struct dma_vec *vecs, size_t nents, enum dma_transfer_direction dir, unsigned long flags) { if (!chan || !chan->device || !chan->device->device_prep_peripheral_dma_vec) return NULL; return chan->device->device_prep_peripheral_dma_vec(chan, vecs, nents, dir, flags); } static inline struct dma_async_tx_descriptor *dmaengine_prep_slave_sg( struct dma_chan *chan, struct scatterlist *sgl, unsigned int sg_len, enum dma_transfer_direction dir, unsigned long flags) Loading Loading
Documentation/driver-api/dmaengine/client.rst +9 −0 Original line number Diff line number Diff line Loading @@ -80,6 +80,10 @@ The details of these operations are: - slave_sg: DMA a list of scatter gather buffers from/to a peripheral - peripheral_dma_vec: DMA an array of scatter gather buffers from/to a peripheral. Similar to slave_sg, but uses an array of dma_vec structures instead of a scatterlist. - dma_cyclic: Perform a cyclic DMA operation from/to a peripheral till the operation is explicitly stopped. Loading @@ -102,6 +106,11 @@ The details of these operations are: unsigned int sg_len, enum dma_data_direction direction, unsigned long flags); struct dma_async_tx_descriptor *dmaengine_prep_peripheral_dma_vec( struct dma_chan *chan, const struct dma_vec *vecs, size_t nents, enum dma_data_direction direction, unsigned long flags); struct dma_async_tx_descriptor *dmaengine_prep_dma_cyclic( struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len, size_t period_len, enum dma_data_direction direction); Loading
Documentation/driver-api/dmaengine/provider.rst +10 −0 Original line number Diff line number Diff line Loading @@ -433,6 +433,12 @@ supported. - residue: Provides the residue bytes of the transfer for those that support residue. - ``device_prep_peripheral_dma_vec`` - Similar to ``device_prep_slave_sg``, but it takes a pointer to a array of ``dma_vec`` structures, which (in the long run) will replace scatterlists. - ``device_issue_pending`` - Takes the first transaction descriptor in the pending queue, Loading Loading @@ -544,6 +550,10 @@ dma_cookie_t - Not really relevant any more since the introduction of ``virt-dma`` that abstracts it away. dma_vec - A small structure that contains a DMA address and length. DMA_CTRL_ACK - If clear, the descriptor cannot be reused by provider until the Loading
drivers/dma/dma-axi-dmac.c +40 −0 Original line number Diff line number Diff line Loading @@ -620,6 +620,45 @@ static struct axi_dmac_sg *axi_dmac_fill_linear_sg(struct axi_dmac_chan *chan, return sg; } static struct dma_async_tx_descriptor * axi_dmac_prep_peripheral_dma_vec(struct dma_chan *c, const struct dma_vec *vecs, size_t nb, enum dma_transfer_direction direction, unsigned long flags) { struct axi_dmac_chan *chan = to_axi_dmac_chan(c); struct axi_dmac_desc *desc; unsigned int num_sgs = 0; struct axi_dmac_sg *dsg; size_t i; if (direction != chan->direction) return NULL; for (i = 0; i < nb; i++) num_sgs += DIV_ROUND_UP(vecs[i].len, chan->max_length); desc = axi_dmac_alloc_desc(chan, num_sgs); if (!desc) return NULL; dsg = desc->sg; for (i = 0; i < nb; i++) { if (!axi_dmac_check_addr(chan, vecs[i].addr) || !axi_dmac_check_len(chan, vecs[i].len)) { kfree(desc); return NULL; } dsg = axi_dmac_fill_linear_sg(chan, direction, vecs[i].addr, 1, vecs[i].len, dsg); } desc->cyclic = false; return vchan_tx_prep(&chan->vchan, &desc->vdesc, flags); } static struct dma_async_tx_descriptor *axi_dmac_prep_slave_sg( struct dma_chan *c, struct scatterlist *sgl, unsigned int sg_len, enum dma_transfer_direction direction, Loading Loading @@ -1061,6 +1100,7 @@ static int axi_dmac_probe(struct platform_device *pdev) dma_dev->device_tx_status = dma_cookie_status; dma_dev->device_issue_pending = axi_dmac_issue_pending; dma_dev->device_prep_slave_sg = axi_dmac_prep_slave_sg; dma_dev->device_prep_peripheral_dma_vec = axi_dmac_prep_peripheral_dma_vec; dma_dev->device_prep_dma_cyclic = axi_dmac_prep_dma_cyclic; dma_dev->device_prep_interleaved_dma = axi_dmac_prep_interleaved; dma_dev->device_terminate_all = axi_dmac_terminate_all; Loading
include/linux/dmaengine.h +33 −0 Original line number Diff line number Diff line Loading @@ -160,6 +160,16 @@ struct dma_interleaved_template { struct data_chunk sgl[]; }; /** * struct dma_vec - DMA vector * @addr: Bus address of the start of the vector * @len: Length in bytes of the DMA vector */ struct dma_vec { dma_addr_t addr; size_t len; }; /** * enum dma_ctrl_flags - DMA flags to augment operation preparation, * control completion, and communicate status. Loading Loading @@ -910,6 +920,10 @@ struct dma_device { struct dma_async_tx_descriptor *(*device_prep_dma_interrupt)( struct dma_chan *chan, unsigned long flags); struct dma_async_tx_descriptor *(*device_prep_peripheral_dma_vec)( struct dma_chan *chan, const struct dma_vec *vecs, size_t nents, enum dma_transfer_direction direction, unsigned long flags); struct dma_async_tx_descriptor *(*device_prep_slave_sg)( struct dma_chan *chan, struct scatterlist *sgl, unsigned int sg_len, enum dma_transfer_direction direction, Loading Loading @@ -973,6 +987,25 @@ static inline struct dma_async_tx_descriptor *dmaengine_prep_slave_single( dir, flags, NULL); } /** * dmaengine_prep_peripheral_dma_vec() - Prepare a DMA scatter-gather descriptor * @chan: The channel to be used for this descriptor * @vecs: The array of DMA vectors that should be transferred * @nents: The number of DMA vectors in the array * @dir: Specifies the direction of the data transfer * @flags: DMA engine flags */ static inline struct dma_async_tx_descriptor *dmaengine_prep_peripheral_dma_vec( struct dma_chan *chan, const struct dma_vec *vecs, size_t nents, enum dma_transfer_direction dir, unsigned long flags) { if (!chan || !chan->device || !chan->device->device_prep_peripheral_dma_vec) return NULL; return chan->device->device_prep_peripheral_dma_vec(chan, vecs, nents, dir, flags); } static inline struct dma_async_tx_descriptor *dmaengine_prep_slave_sg( struct dma_chan *chan, struct scatterlist *sgl, unsigned int sg_len, enum dma_transfer_direction dir, unsigned long flags) Loading