|
@@ -385,98 +385,6 @@ msgdma_prep_memcpy(struct dma_chan *dchan, dma_addr_t dma_dst,
|
|
|
return &first->async_tx;
|
|
|
}
|
|
|
|
|
|
-/**
|
|
|
- * msgdma_prep_sg - prepare descriptors for a memory sg transaction
|
|
|
- * @dchan: DMA channel
|
|
|
- * @dst_sg: Destination scatter list
|
|
|
- * @dst_sg_len: Number of entries in destination scatter list
|
|
|
- * @src_sg: Source scatter list
|
|
|
- * @src_sg_len: Number of entries in source scatter list
|
|
|
- * @flags: transfer ack flags
|
|
|
- *
|
|
|
- * Return: Async transaction descriptor on success and NULL on failure
|
|
|
- */
|
|
|
-static struct dma_async_tx_descriptor *
|
|
|
-msgdma_prep_sg(struct dma_chan *dchan, struct scatterlist *dst_sg,
|
|
|
- unsigned int dst_sg_len, struct scatterlist *src_sg,
|
|
|
- unsigned int src_sg_len, unsigned long flags)
|
|
|
-{
|
|
|
- struct msgdma_device *mdev = to_mdev(dchan);
|
|
|
- struct msgdma_sw_desc *new, *first = NULL;
|
|
|
- void *desc = NULL;
|
|
|
- size_t len, dst_avail, src_avail;
|
|
|
- dma_addr_t dma_dst, dma_src;
|
|
|
- u32 desc_cnt = 0, i;
|
|
|
- struct scatterlist *sg;
|
|
|
-
|
|
|
- for_each_sg(src_sg, sg, src_sg_len, i)
|
|
|
- desc_cnt += DIV_ROUND_UP(sg_dma_len(sg), MSGDMA_MAX_TRANS_LEN);
|
|
|
-
|
|
|
- spin_lock_bh(&mdev->lock);
|
|
|
- if (desc_cnt > mdev->desc_free_cnt) {
|
|
|
- spin_unlock_bh(&mdev->lock);
|
|
|
- dev_dbg(mdev->dev, "mdev %p descs are not available\n", mdev);
|
|
|
- return NULL;
|
|
|
- }
|
|
|
- mdev->desc_free_cnt -= desc_cnt;
|
|
|
- spin_unlock_bh(&mdev->lock);
|
|
|
-
|
|
|
- dst_avail = sg_dma_len(dst_sg);
|
|
|
- src_avail = sg_dma_len(src_sg);
|
|
|
-
|
|
|
- /* Run until we are out of scatterlist entries */
|
|
|
- while (true) {
|
|
|
- /* Allocate and populate the descriptor */
|
|
|
- new = msgdma_get_descriptor(mdev);
|
|
|
-
|
|
|
- desc = &new->hw_desc;
|
|
|
- len = min_t(size_t, src_avail, dst_avail);
|
|
|
- len = min_t(size_t, len, MSGDMA_MAX_TRANS_LEN);
|
|
|
- if (len == 0)
|
|
|
- goto fetch;
|
|
|
- dma_dst = sg_dma_address(dst_sg) + sg_dma_len(dst_sg) -
|
|
|
- dst_avail;
|
|
|
- dma_src = sg_dma_address(src_sg) + sg_dma_len(src_sg) -
|
|
|
- src_avail;
|
|
|
-
|
|
|
- msgdma_desc_config(desc, dma_dst, dma_src, len,
|
|
|
- MSGDMA_DESC_STRIDE_RW);
|
|
|
- dst_avail -= len;
|
|
|
- src_avail -= len;
|
|
|
-
|
|
|
- if (!first)
|
|
|
- first = new;
|
|
|
- else
|
|
|
- list_add_tail(&new->node, &first->tx_list);
|
|
|
-fetch:
|
|
|
- /* Fetch the next dst scatterlist entry */
|
|
|
- if (dst_avail == 0) {
|
|
|
- if (dst_sg_len == 0)
|
|
|
- break;
|
|
|
- dst_sg = sg_next(dst_sg);
|
|
|
- if (dst_sg == NULL)
|
|
|
- break;
|
|
|
- dst_sg_len--;
|
|
|
- dst_avail = sg_dma_len(dst_sg);
|
|
|
- }
|
|
|
- /* Fetch the next src scatterlist entry */
|
|
|
- if (src_avail == 0) {
|
|
|
- if (src_sg_len == 0)
|
|
|
- break;
|
|
|
- src_sg = sg_next(src_sg);
|
|
|
- if (src_sg == NULL)
|
|
|
- break;
|
|
|
- src_sg_len--;
|
|
|
- src_avail = sg_dma_len(src_sg);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- msgdma_desc_config_eod(desc);
|
|
|
- first->async_tx.flags = flags;
|
|
|
-
|
|
|
- return &first->async_tx;
|
|
|
-}
|
|
|
-
|
|
|
/**
|
|
|
* msgdma_prep_slave_sg - prepare descriptors for a slave sg transaction
|
|
|
*
|
|
@@ -943,7 +851,6 @@ static int msgdma_probe(struct platform_device *pdev)
|
|
|
/* Set DMA capabilities */
|
|
|
dma_cap_zero(dma_dev->cap_mask);
|
|
|
dma_cap_set(DMA_MEMCPY, dma_dev->cap_mask);
|
|
|
- dma_cap_set(DMA_SG, dma_dev->cap_mask);
|
|
|
dma_cap_set(DMA_SLAVE, dma_dev->cap_mask);
|
|
|
|
|
|
dma_dev->src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_4_BYTES);
|
|
@@ -962,7 +869,6 @@ static int msgdma_probe(struct platform_device *pdev)
|
|
|
|
|
|
dma_dev->copy_align = DMAENGINE_ALIGN_4_BYTES;
|
|
|
dma_dev->device_prep_dma_memcpy = msgdma_prep_memcpy;
|
|
|
- dma_dev->device_prep_dma_sg = msgdma_prep_sg;
|
|
|
dma_dev->device_prep_slave_sg = msgdma_prep_slave_sg;
|
|
|
dma_dev->device_config = msgdma_dma_config;
|
|
|
|