On Mon, Feb 17, 2014 at 3:14 PM, Lars-Peter Clausen <lars@xxxxxxxxxx> wrote: > On 02/17/2014 10:42 AM, Srikanth Thokala wrote: >> >> On Mon, Feb 17, 2014 at 3:05 PM, Lars-Peter Clausen <lars@xxxxxxxxxx> >> wrote: >>> >>> On 02/17/2014 10:29 AM, Srikanth Thokala wrote: >>>> >>>> >>>> On Mon, Feb 17, 2014 at 2:13 PM, Vinod Koul <vinod.koul@xxxxxxxxx> >>>> wrote: >>>>> >>>>> >>>>> On Sat, Feb 15, 2014 at 05:30:17PM +0530, Srikanth Thokala wrote: >>>>>> >>>>>> >>>>>> The current implementation of interleaved DMA API support multiple >>>>>> frames only when the memory is contiguous by incrementing src_start/ >>>>>> dst_start members of interleaved template. >>>>>> >>>>>> But, when the memory is non-contiguous it will restrict slave device >>>>>> to not submit multiple frames in a batch. This patch handles this >>>>>> issue by allowing the slave device to send array of interleaved dma >>>>>> templates each having a different memory location. >>>>> >>>>> >>>>> This seems to be missing the numbers of templates you are sending, >>>>> wouldnt this >>>>> require sending ARRAY_SiZE too? >>>>> >>>>> And why send double pointer? >>>> >>>> >>>> >>>> Array size is not required, when we pass the double pointer. The last >>>> element would be >>>> pointed to NULL and we could get the number of templates from this >>>> condition. >>>> Here is an example snippet, >>>> >>>> In slave device driver, >>>> >>>> struct dma_interleaved_template **xts; >>>> >>>> xts = kcalloc(frm_cnt+1, sizeof(struct >>>> dma_interleaved_template *), GFP_KERNEL); >>>> /* Error check for xts */ >>>> for (i = 0; i < frm_cnt; i++) { >>>> xts[i] = kmalloc(sizeof(struct >>>> dma_interleaved_template), GFP_KERNEL); >>>> /* Error check for xts[i] */ >>>> } >>>> xts[i] = NULL; >>>> >>>> In DMA engine driver, we could get the number of frames by, >>>> >>>> for (; xts[frmno] != NULL; frmno++); >>>> >>>> I felt this way is simpler than adding an extra argument to the API. >>>> Please let me know >>>> your opinion and suggest me a better way. >>> >>> >>> >>> I think Vinod's suggestion of passing in an array of >>> interleaved_templates >>> and the size of the array is better than what you are currently doing. >> >> >> Ok, Lars. I will update with this in my v4. Thanks. >> >>> >>> Btw. you also need to update the current implementations and users of the >>> API accordingly. >> >> >> Yes, I have updated them in this patch. > > > But you didn't update them accordingly to your proposed semantics. The > caller didn't NULL terminate the array and the drivers did blindly assume > there will always be exactly one transfer. Ok, got it. I will correct in v4. Thanks for pointing this. Srikanth > > >> >> Thanks >> Srikanth >> >> >>> >>> >>>> >>>>> >>>>> -- >>>>> ~Vinod >>>>> >>>>>> >>>>>> Signed-off-by: Srikanth Thokala <sthokal@xxxxxxxxxx> >>>>>> --- >>>>>> Documentation/dmaengine.txt | 2 +- >>>>>> drivers/dma/imx-dma.c | 3 ++- >>>>>> drivers/dma/sirf-dma.c | 3 ++- >>>>>> drivers/media/platform/m2m-deinterlace.c | 2 +- >>>>>> include/linux/dmaengine.h | 6 +++--- >>>>>> 5 files changed, 9 insertions(+), 7 deletions(-) >>>>>> >>>>>> diff --git a/Documentation/dmaengine.txt b/Documentation/dmaengine.txt >>>>>> index 879b6e3..c642614 100644 >>>>>> --- a/Documentation/dmaengine.txt >>>>>> +++ b/Documentation/dmaengine.txt >>>>>> @@ -94,7 +94,7 @@ The slave DMA usage consists of following steps: >>>>>> size_t period_len, enum dma_data_direction direction); >>>>>> >>>>>> struct dma_async_tx_descriptor >>>>>> *(*device_prep_interleaved_dma)( >>>>>> - struct dma_chan *chan, struct dma_interleaved_template >>>>>> *xt, >>>>>> + struct dma_chan *chan, struct dma_interleaved_template >>>>>> **xts, >>>>>> unsigned long flags); >>>>>> >>>>>> The peripheral driver is expected to have mapped the scatterlist >>>>>> for >>>>>> diff --git a/drivers/dma/imx-dma.c b/drivers/dma/imx-dma.c >>>>>> index 6f9ac20..e2c52ce 100644 >>>>>> --- a/drivers/dma/imx-dma.c >>>>>> +++ b/drivers/dma/imx-dma.c >>>>>> @@ -954,12 +954,13 @@ static struct dma_async_tx_descriptor >>>>>> *imxdma_prep_dma_memcpy( >>>>>> } >>>>>> >>>>>> static struct dma_async_tx_descriptor *imxdma_prep_dma_interleaved( >>>>>> - struct dma_chan *chan, struct dma_interleaved_template *xt, >>>>>> + struct dma_chan *chan, struct dma_interleaved_template **xts, >>>>>> unsigned long flags) >>>>>> { >>>>>> struct imxdma_channel *imxdmac = to_imxdma_chan(chan); >>>>>> struct imxdma_engine *imxdma = imxdmac->imxdma; >>>>>> struct imxdma_desc *desc; >>>>>> + struct dma_interleaved_template *xt = *xts; >>>>>> >>>>>> dev_dbg(imxdma->dev, "%s channel: %d src_start=0x%llx >>>>>> dst_start=0x%llx\n" >>>>>> " src_sgl=%s dst_sgl=%s numf=%zu frame_size=%zu\n", >>>>>> __func__, >>>>>> diff --git a/drivers/dma/sirf-dma.c b/drivers/dma/sirf-dma.c >>>>>> index d4d3a31..b6a150b 100644 >>>>>> --- a/drivers/dma/sirf-dma.c >>>>>> +++ b/drivers/dma/sirf-dma.c >>>>>> @@ -509,12 +509,13 @@ sirfsoc_dma_tx_status(struct dma_chan *chan, >>>>>> dma_cookie_t cookie, >>>>>> } >>>>>> >>>>>> static struct dma_async_tx_descriptor >>>>>> *sirfsoc_dma_prep_interleaved( >>>>>> - struct dma_chan *chan, struct dma_interleaved_template *xt, >>>>>> + struct dma_chan *chan, struct dma_interleaved_template **xts, >>>>>> unsigned long flags) >>>>>> { >>>>>> struct sirfsoc_dma *sdma = dma_chan_to_sirfsoc_dma(chan); >>>>>> struct sirfsoc_dma_chan *schan = >>>>>> dma_chan_to_sirfsoc_dma_chan(chan); >>>>>> struct sirfsoc_dma_desc *sdesc = NULL; >>>>>> + struct dma_interleaved_template *xt = *xts; >>>>>> unsigned long iflags; >>>>>> int ret; >>>>>> >>>>>> diff --git a/drivers/media/platform/m2m-deinterlace.c >>>>>> b/drivers/media/platform/m2m-deinterlace.c >>>>>> index 6bb86b5..468110a 100644 >>>>>> --- a/drivers/media/platform/m2m-deinterlace.c >>>>>> +++ b/drivers/media/platform/m2m-deinterlace.c >>>>>> @@ -343,7 +343,7 @@ static void deinterlace_issue_dma(struct >>>>>> deinterlace_ctx *ctx, int op, >>>>>> ctx->xt->dst_sgl = true; >>>>>> flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT; >>>>>> >>>>>> - tx = dmadev->device_prep_interleaved_dma(chan, ctx->xt, flags); >>>>>> + tx = dmadev->device_prep_interleaved_dma(chan, &ctx->xt, flags); >>>>>> if (tx == NULL) { >>>>>> v4l2_warn(&pcdev->v4l2_dev, "DMA interleaved prep >>>>>> error\n"); >>>>>> return; >>>>>> diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h >>>>>> index c5c92d5..2f77a9a 100644 >>>>>> --- a/include/linux/dmaengine.h >>>>>> +++ b/include/linux/dmaengine.h >>>>>> @@ -675,7 +675,7 @@ struct dma_device { >>>>>> size_t period_len, enum dma_transfer_direction >>>>>> direction, >>>>>> unsigned long flags, void *context); >>>>>> struct dma_async_tx_descriptor >>>>>> *(*device_prep_interleaved_dma)( >>>>>> - struct dma_chan *chan, struct dma_interleaved_template >>>>>> *xt, >>>>>> + struct dma_chan *chan, struct dma_interleaved_template >>>>>> **xts, >>>>>> unsigned long flags); >>>>>> int (*device_control)(struct dma_chan *chan, enum dma_ctrl_cmd >>>>>> cmd, >>>>>> unsigned long arg); >>>>>> @@ -752,10 +752,10 @@ static inline struct dma_async_tx_descriptor >>>>>> *dmaengine_prep_dma_cyclic( >>>>>> } >>>>>> >>>>>> static inline struct dma_async_tx_descriptor >>>>>> *dmaengine_prep_interleaved_dma( >>>>>> - struct dma_chan *chan, struct dma_interleaved_template >>>>>> *xt, >>>>>> + struct dma_chan *chan, struct dma_interleaved_template >>>>>> **xts, >>>>>> unsigned long flags) >>>>>> { >>>>>> - return chan->device->device_prep_interleaved_dma(chan, xt, >>>>>> flags); >>>>>> + return chan->device->device_prep_interleaved_dma(chan, xts, >>>>>> flags); >>>>>> } >>>>>> >>>>>> static inline int dma_get_slave_caps(struct dma_chan *chan, struct >>>>>> dma_slave_caps *caps) >>>>>> -- >>>>>> 1.7.9.5 >>>>>> >>>>>> -- >>>>>> To unsubscribe from this list: send the line "unsubscribe dmaengine" >>>>>> in >>>>>> the body of a message to majordomo@xxxxxxxxxxxxxxx >>>>>> More majordomo info at http://vger.kernel.org/majordomo-info.html >>>>> >>>>> >>>>> >>>>> -- >>>>> -- >>>>> To unsubscribe from this list: send the line "unsubscribe linux-kernel" >>>>> in >>>>> the body of a message to majordomo@xxxxxxxxxxxxxxx >>>>> More majordomo info at http://vger.kernel.org/majordomo-info.html >>>>> Please read the FAQ at http://www.tux.org/lkml/ >>> >>> >>> >>> -- >>> To unsubscribe from this list: send the line "unsubscribe linux-kernel" >>> in >>> the body of a message to majordomo@xxxxxxxxxxxxxxx >>> More majordomo info at http://vger.kernel.org/majordomo-info.html >>> Please read the FAQ at http://www.tux.org/lkml/ > > > -- > To unsubscribe from this list: send the line "unsubscribe linux-kernel" in > the body of a message to majordomo@xxxxxxxxxxxxxxx > More majordomo info at http://vger.kernel.org/majordomo-info.html > Please read the FAQ at http://www.tux.org/lkml/ -- To unsubscribe from this list: send the line "unsubscribe dmaengine" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html