@@ -620,6 +620,45 @@ static struct axi_dmac_sg *axi_dmac_fill_linear_sg(struct axi_dmac_chan *chan,
620
620
return sg ;
621
621
}
622
622
623
+ static struct dma_async_tx_descriptor *
624
+ axi_dmac_prep_peripheral_dma_vec (struct dma_chan * c , const struct dma_vec * vecs ,
625
+ size_t nb , enum dma_transfer_direction direction ,
626
+ unsigned long flags )
627
+ {
628
+ struct axi_dmac_chan * chan = to_axi_dmac_chan (c );
629
+ struct axi_dmac_desc * desc ;
630
+ unsigned int num_sgs = 0 ;
631
+ struct axi_dmac_sg * dsg ;
632
+ size_t i ;
633
+
634
+ if (direction != chan -> direction )
635
+ return NULL ;
636
+
637
+ for (i = 0 ; i < nb ; i ++ )
638
+ num_sgs += DIV_ROUND_UP (vecs [i ].len , chan -> max_length );
639
+
640
+ desc = axi_dmac_alloc_desc (chan , num_sgs );
641
+ if (!desc )
642
+ return NULL ;
643
+
644
+ dsg = desc -> sg ;
645
+
646
+ for (i = 0 ; i < nb ; i ++ ) {
647
+ if (!axi_dmac_check_addr (chan , vecs [i ].addr ) ||
648
+ !axi_dmac_check_len (chan , vecs [i ].len )) {
649
+ kfree (desc );
650
+ return NULL ;
651
+ }
652
+
653
+ dsg = axi_dmac_fill_linear_sg (chan , direction , vecs [i ].addr , 1 ,
654
+ vecs [i ].len , dsg );
655
+ }
656
+
657
+ desc -> cyclic = false;
658
+
659
+ return vchan_tx_prep (& chan -> vchan , & desc -> vdesc , flags );
660
+ }
661
+
623
662
static struct dma_async_tx_descriptor * axi_dmac_prep_slave_sg (
624
663
struct dma_chan * c , struct scatterlist * sgl ,
625
664
unsigned int sg_len , enum dma_transfer_direction direction ,
@@ -1061,6 +1100,7 @@ static int axi_dmac_probe(struct platform_device *pdev)
1061
1100
dma_dev -> device_tx_status = dma_cookie_status ;
1062
1101
dma_dev -> device_issue_pending = axi_dmac_issue_pending ;
1063
1102
dma_dev -> device_prep_slave_sg = axi_dmac_prep_slave_sg ;
1103
+ dma_dev -> device_prep_peripheral_dma_vec = axi_dmac_prep_peripheral_dma_vec ;
1064
1104
dma_dev -> device_prep_dma_cyclic = axi_dmac_prep_dma_cyclic ;
1065
1105
dma_dev -> device_prep_interleaved_dma = axi_dmac_prep_interleaved ;
1066
1106
dma_dev -> device_terminate_all = axi_dmac_terminate_all ;
0 commit comments