Skip to content

Commit

Permalink
dmaengine: imx-sdma - update the residue calculation for cyclic channels
Browse files Browse the repository at this point in the history
The calculation of the DMA transaction residue supports only fixed
size data transfers. This implementation is not covering all
operations (e.g. data receiving) when we need to know the exact amount
of bytes transferred.

The loop channels handling was changed to clear the buffer
descriptor errors and use the bd->mode.count to calculate the
residue.

Tested-by: Peter Senna Tschudin <peter.senna@collabora.com>
Acked-by: Peter Senna Tschudin <peter.senna@collabora.com>
Reviewed-by: Vinod Koul <vinod.koul@intel.com>
Signed-off-by: Nandor Han <nandor.han@ge.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Nandor Han authored and Greg Kroah-Hartman committed Aug 31, 2016
1 parent 15f30f5 commit 5881826
Showing 1 changed file with 18 additions and 2 deletions.
20 changes: 18 additions & 2 deletions drivers/dma/imx-sdma.c
Original file line number Diff line number Diff line change
Expand Up @@ -651,6 +651,8 @@ static void sdma_event_disable(struct sdma_channel *sdmac, unsigned int event)
static void sdma_update_channel_loop(struct sdma_channel *sdmac)
{
struct sdma_buffer_descriptor *bd;
int error = 0;
enum dma_status old_status = sdmac->status;

/*
* loop mode. Iterate over descriptors, re-setup them and
Expand All @@ -662,10 +664,20 @@ static void sdma_update_channel_loop(struct sdma_channel *sdmac)
if (bd->mode.status & BD_DONE)
break;

if (bd->mode.status & BD_RROR)
if (bd->mode.status & BD_RROR) {
bd->mode.status &= ~BD_RROR;
sdmac->status = DMA_ERROR;
error = -EIO;
}

/*
* We use bd->mode.count to calculate the residue, since contains
* the number of bytes present in the current buffer descriptor.
*/

sdmac->chn_real_count = bd->mode.count;
bd->mode.status |= BD_DONE;
bd->mode.count = sdmac->period_len;

/*
* The callback is called from the interrupt context in order
Expand All @@ -679,6 +691,9 @@ static void sdma_update_channel_loop(struct sdma_channel *sdmac)

sdmac->buf_tail++;
sdmac->buf_tail %= sdmac->num_bd;

if (error)
sdmac->status = old_status;
}
}

Expand Down Expand Up @@ -1349,7 +1364,8 @@ static enum dma_status sdma_tx_status(struct dma_chan *chan,
u32 residue;

if (sdmac->flags & IMX_DMA_SG_LOOP)
residue = (sdmac->num_bd - sdmac->buf_tail) * sdmac->period_len;
residue = (sdmac->num_bd - sdmac->buf_tail) *
sdmac->period_len - sdmac->chn_real_count;
else
residue = sdmac->chn_count - sdmac->chn_real_count;

Expand Down

0 comments on commit 5881826

Please sign in to comment.