| From 7b126c5fbddf179c7d2c2393100329aa45cd8ac4 Mon Sep 17 00:00:00 2001 |
| From: Fugang Duan <fugang.duan@nxp.com> |
| Date: Fri, 9 Aug 2019 15:14:08 +0800 |
| Subject: [PATCH] dmaengine: fsl-edma: calculate the real count for slave sg |
| |
| Calculate the rela count for current slave sg after eDMA stop. |
| |
| Signed-off-by: Fugang Duan <fugang.duan@nxp.com> |
| --- |
| drivers/dma/fsl-edma-common.c | 11 ++++++++++- |
| drivers/dma/fsl-edma-common.h | 2 ++ |
| drivers/dma/fsl-edma.c | 1 + |
| 3 files changed, 13 insertions(+), 1 deletion(-) |
| |
| --- a/drivers/dma/fsl-edma-common.c |
| +++ b/drivers/dma/fsl-edma-common.c |
| @@ -305,6 +305,11 @@ static size_t fsl_edma_desc_residue(stru |
| return len; |
| } |
| |
| +void fsl_edma_get_realcnt(struct fsl_edma_chan *fsl_chan) |
| +{ |
| + fsl_chan->chn_real_count = fsl_edma_desc_residue(fsl_chan, NULL, true); |
| +} |
| + |
| enum dma_status fsl_edma_tx_status(struct dma_chan *chan, |
| dma_cookie_t cookie, struct dma_tx_state *txstate) |
| { |
| @@ -314,8 +319,12 @@ enum dma_status fsl_edma_tx_status(struc |
| unsigned long flags; |
| |
| status = dma_cookie_status(chan, cookie, txstate); |
| - if (status == DMA_COMPLETE) |
| + if (status == DMA_COMPLETE) { |
| + spin_lock_irqsave(&fsl_chan->vchan.lock, flags); |
| + txstate->residue = fsl_chan->chn_real_count; |
| + spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags); |
| return status; |
| + } |
| |
| if (!txstate) |
| return fsl_chan->status; |
| --- a/drivers/dma/fsl-edma-common.h |
| +++ b/drivers/dma/fsl-edma-common.h |
| @@ -126,6 +126,7 @@ struct fsl_edma_chan { |
| u32 dma_dev_size; |
| enum dma_data_direction dma_dir; |
| char chan_name[16]; |
| + u32 chn_real_count; |
| }; |
| |
| struct fsl_edma_desc { |
| @@ -229,6 +230,7 @@ int fsl_edma_pause(struct dma_chan *chan |
| int fsl_edma_resume(struct dma_chan *chan); |
| int fsl_edma_slave_config(struct dma_chan *chan, |
| struct dma_slave_config *cfg); |
| +void fsl_edma_get_realcnt(struct fsl_edma_chan *fsl_chan); |
| enum dma_status fsl_edma_tx_status(struct dma_chan *chan, |
| dma_cookie_t cookie, struct dma_tx_state *txstate); |
| struct dma_async_tx_descriptor *fsl_edma_prep_dma_cyclic( |
| --- a/drivers/dma/fsl-edma.c |
| +++ b/drivers/dma/fsl-edma.c |
| @@ -53,6 +53,7 @@ static irqreturn_t fsl_edma_tx_handler(i |
| } |
| |
| if (!fsl_chan->edesc->iscyclic) { |
| + fsl_edma_get_realcnt(fsl_chan); |
| list_del(&fsl_chan->edesc->vdesc.node); |
| vchan_cookie_complete(&fsl_chan->edesc->vdesc); |
| fsl_chan->edesc = NULL; |