Hi Dylan, > -----Original Message----- > From: dgreid@xxxxxxxxxx [mailto:dgreid@xxxxxxxxxx] On Behalf Of Dylan > Reid > Sent: Wednesday, October 02, 2013 1:34 PM > To: Chanho Park > Cc: Padmavathi Venna; linux-samsung-soc@xxxxxxxxxxxxxxx; linux-arm- > kernel@xxxxxxxxxxxxxxxxxxx; padma.kvr@xxxxxxxxx; kgene.kim@xxxxxxxxxxx; > arnd@xxxxxxxx; Sangbeom Kim; vinod.koul@xxxxxxxxx; Mark Brown; Olof > Johansson > Subject: Re: [PATCH 1/3] dmaengine: pl330: Set residue in tx_status > callback. > > On Thu, Sep 12, 2013 at 4:40 AM, Chanho Park <chanho61.park@xxxxxxxxxxx> > wrote: > > Hi Padmavathi, > > > >> -----Original Message----- > >> From: linux-arm-kernel [mailto:linux-arm-kernel- > >> bounces@xxxxxxxxxxxxxxxxxxx] On Behalf Of Padmavathi Venna > >> Sent: Wednesday, September 11, 2013 3:08 PM > >> To: linux-samsung-soc@xxxxxxxxxxxxxxx; linux-arm- > >> kernel@xxxxxxxxxxxxxxxxxxx; padma.v@xxxxxxxxxxx; padma.kvr@xxxxxxxxx > >> Cc: kgene.kim@xxxxxxxxxxx; arnd@xxxxxxxx; sbkim73@xxxxxxxxxxx; > >> vinod.koul@xxxxxxxxx; broonie@xxxxxxxxxx; dgreid@xxxxxxxxxxxx; > >> olofj@xxxxxxxxxxxx > >> Subject: [PATCH 1/3] dmaengine: pl330: Set residue in tx_status > callback. > >> > >> From: Dylan Reid <dgreid@xxxxxxxxxxxx> > >> > >> Fill txstate.residue with the amount of bytes remaining in the > >> current transfer if the transfer is not complete. This will be of > >> particular use to i2s DMA transfers, providing more accurate hw_ptr > values to ASoC. > >> > >> Signed-off-by: Dylan Reid <dgreid@xxxxxxxxxxxx> > >> Reviewed-by: Olof Johansson <olofj@xxxxxxxxxxxx> > >> Signed-off-by: Padmavathi Venna <padma.v@xxxxxxxxxxx> > >> --- > >> drivers/dma/pl330.c | 55 > >> ++++++++++++++++++++++++++++++++++++++++++++++++++- > >> 1 files changed, 54 insertions(+), 1 deletions(-) > >> > >> diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index > >> 593827b..7ab9136 100644 > >> --- a/drivers/dma/pl330.c > >> +++ b/drivers/dma/pl330.c > >> @@ -2476,11 +2476,64 @@ static void pl330_free_chan_resources(struct > >> dma_chan *chan) > >> spin_unlock_irqrestore(&pch->lock, flags); } > >> > >> +static inline int > >> +pl330_src_addr_in_desc(struct dma_pl330_desc *desc, unsigned int sar) > { > >> + return ((desc->px.src_addr <= sar) && > >> + (sar <= (desc->px.src_addr + desc->px.bytes))); } > >> + > >> +static inline int > >> +pl330_dst_addr_in_desc(struct dma_pl330_desc *desc, unsigned int dar) > { > >> + return ((desc->px.dst_addr <= dar) && > >> + (dar <= (desc->px.dst_addr + desc->px.bytes))); } > >> + > >> +static unsigned int pl330_tx_residue(struct dma_chan *chan) { > >> + struct dma_pl330_chan *pch = to_pchan(chan); > >> + void __iomem *regs = pch->dmac->pif.base; > >> + struct pl330_thread *thrd = pch->pl330_chid; > >> + struct dma_pl330_desc *desc; > >> + unsigned int sar, dar; > >> + unsigned int residue = 0; > >> + unsigned long flags; > >> + > >> + sar = readl(regs + SA(thrd->id)); > >> + dar = readl(regs + DA(thrd->id)); > >> + > >> + spin_lock_irqsave(&pch->lock, flags); > >> + > >> + /* Find the desc related to the current buffer. */ > >> + list_for_each_entry(desc, &pch->work_list, node) { > >> + if (desc->rqcfg.src_inc && pl330_src_addr_in_desc(desc, > >> sar)) { > >> + residue = desc->px.bytes - (sar - > > desc->px.src_addr); > >> + goto found_unlock; > >> + } > >> + if (desc->rqcfg.dst_inc && pl330_dst_addr_in_desc(desc, > >> dar)) { > >> + residue = desc->px.bytes - (dar - > > desc->px.dst_addr); > >> + goto found_unlock; > >> + } > >> + } > >> + > >> +found_unlock: > >> + spin_unlock_irqrestore(&pch->lock, flags); > >> + > >> + return residue; > >> +} > >> + > >> static enum dma_status > >> pl330_tx_status(struct dma_chan *chan, dma_cookie_t cookie, > >> struct dma_tx_state *txstate) { > >> - return dma_cookie_status(chan, cookie, txstate); > >> + enum dma_status ret; > >> + > >> + ret = dma_cookie_status(chan, cookie, txstate); > >> + if (ret != DMA_SUCCESS) /* Not complete, check amount left. */ > >> + dma_set_residue(txstate, pl330_tx_residue(chan)); > >> + > >> + return ret; > > > > Why didn't you use a cookie value to track the request? > > The cookie is assigned when each transfer is submitted. > > If you save the value in the desc, we can find the request easily. > > If there are several cyclic desc in the work list, is there a better way > to find the "current" one? The chan struct tracks the last completed and > last submitted cookies, but these will be the first and last > respectively as long as the cyclic transfer is active. Is there an > "active" cookie stored somewhere that I missed? Assume there are three cookies. If you want to get the second cookie not latest cookie, your way can be also correct in such case? I think tx_status API is to get dma status of the given cookie. You are only considering a cyclic case. > > Looking for the first buffer with status == BUSY is an improvement I'll > make. Any way to avoid looking through the list? > > Thanks, > > Dylan > > > > > Thanks, > > > > Best Regards, > > Chanho Park > > -- To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html