Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

dmaengine: qcom_bam_dma: Add descriptor flags

This patch adds support for end of transaction (EOT) and notify when done (NWD)
hardware descriptor flags.

The EOT flag requests that the peripheral assert an end of transaction interrupt
when that descriptor is complete. It also results in special signaling protocol
that is used between the attached peripheral and the core using the DMA
controller. Clients will specify DMA_PREP_INTERRUPT to enable this flag.

The NWD flag requests that the peripheral wait until the data has been fully
processed by the peripheral before moving on to the next descriptor. Clients
will specify DMA_PREP_FENCE to enable this flag.

Signed-off-by: Andy Gross <agross@codeaurora.org>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>

authored by

Andy Gross and committed by
Vinod Koul
89751d0a 43452fad

+18 -2
+18 -2
drivers/dma/qcom_bam_dma.c
··· 61 61 #define DESC_FLAG_INT BIT(15) 62 62 #define DESC_FLAG_EOT BIT(14) 63 63 #define DESC_FLAG_EOB BIT(13) 64 + #define DESC_FLAG_NWD BIT(12) 64 65 65 66 struct bam_async_desc { 66 67 struct virt_dma_desc vd; 67 68 68 69 u32 num_desc; 69 70 u32 xfer_len; 71 + 72 + /* transaction flags, EOT|EOB|NWD */ 73 + u16 flags; 74 + 70 75 struct bam_desc_hw *curr_desc; 71 76 72 77 enum dma_transfer_direction dir; ··· 495 490 if (!async_desc) 496 491 goto err_out; 497 492 493 + if (flags & DMA_PREP_FENCE) 494 + async_desc->flags |= DESC_FLAG_NWD; 495 + 496 + if (flags & DMA_PREP_INTERRUPT) 497 + async_desc->flags |= DESC_FLAG_EOT; 498 + else 499 + async_desc->flags |= DESC_FLAG_INT; 500 + 498 501 async_desc->num_desc = num_alloc; 499 502 async_desc->curr_desc = async_desc->desc; 500 503 async_desc->dir = direction; ··· 806 793 else 807 794 async_desc->xfer_len = async_desc->num_desc; 808 795 809 - /* set INT on last descriptor */ 810 - desc[async_desc->xfer_len - 1].flags |= DESC_FLAG_INT; 796 + /* set any special flags on the last descriptor */ 797 + if (async_desc->num_desc == async_desc->xfer_len) 798 + desc[async_desc->xfer_len - 1].flags = async_desc->flags; 799 + else 800 + desc[async_desc->xfer_len - 1].flags |= DESC_FLAG_INT; 811 801 812 802 if (bchan->tail + async_desc->xfer_len > MAX_DESCRIPTORS) { 813 803 u32 partial = MAX_DESCRIPTORS - bchan->tail;