From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752332AbcHHOLe (ORCPT ); Mon, 8 Aug 2016 10:11:34 -0400 Received: from mx0a-00176a03.pphosted.com ([67.231.149.52]:63470 "EHLO mx0a-00176a03.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750916AbcHHOLd (ORCPT ); Mon, 8 Aug 2016 10:11:33 -0400 From: Nandor Han To: =Dan Williams , Vinod Koul , Greg Kroah-Hartman , Jiri Slaby Cc: Nandor Han , dmaengine@vger.kernel.org, linux-serial@vger.kernel.org, linux-kernel@vger.kernel.org, Peter Senna Tschudin Subject: [PATCH 2/4] dmaengine: imx-sdma - update the residue calculation for cyclic channels Date: Mon, 8 Aug 2016 15:38:26 +0300 Message-Id: <0e47cf5eb88ef63f844f310bfbd836264f65ccdf.1470656658.git.nandor.han@ge.com> X-Mailer: git-send-email 2.8.3 In-Reply-To: References: In-Reply-To: References: X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:,, definitions=2016-08-08_10:,, signatures=0 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 spamscore=0 suspectscore=0 malwarescore=0 phishscore=0 adultscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1604210000 definitions=main-1608080143 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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 Acked-by: Peter Senna Tschudin Reviewed-by: Vinod Koul Signed-off-by: Nandor Han --- drivers/dma/imx-sdma.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index aa35a77..3cb4738 100644 --- a/drivers/dma/imx-sdma.c +++ b/drivers/dma/imx-sdma.c @@ -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 @@ -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 @@ -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; } } @@ -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; -- 2.8.3