From patchwork Thu Nov 13 10:52:41 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ludovic Desroches X-Patchwork-Id: 5295071 Return-Path: X-Original-To: patchwork-dmaengine@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 5F6369F2F1 for ; Thu, 13 Nov 2014 10:54:09 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 17841201ED for ; Thu, 13 Nov 2014 10:54:07 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id F022C200F2 for ; Thu, 13 Nov 2014 10:54:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932565AbaKMKyF (ORCPT ); Thu, 13 Nov 2014 05:54:05 -0500 Received: from eusmtp01.atmel.com ([212.144.249.243]:30983 "EHLO eusmtp01.atmel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932364AbaKMKyE (ORCPT ); Thu, 13 Nov 2014 05:54:04 -0500 Received: from ibiza.corp.atmel.com (10.161.101.13) by eusmtp01.atmel.com (10.161.101.31) with Microsoft SMTP Server id 14.2.347.0; Thu, 13 Nov 2014 11:53:57 +0100 From: Ludovic Desroches To: , , CC: , , , Ludovic Desroches Subject: [PATCH 3/7] dmaengine: at_xdmac: fix software lockup at_xdmac_tx_status() Date: Thu, 13 Nov 2014 11:52:41 +0100 Message-ID: <1415875965-6905-4-git-send-email-ludovic.desroches@atmel.com> X-Mailer: git-send-email 2.0.3 In-Reply-To: <1415875965-6905-1-git-send-email-ludovic.desroches@atmel.com> References: <1415875965-6905-1-git-send-email-ludovic.desroches@atmel.com> MIME-Version: 1.0 Sender: dmaengine-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: dmaengine@vger.kernel.org X-Spam-Status: No, score=-7.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Cyrille Pitchen According to the Atmel eXtended DMA controller datasheet, requesting a DMA transfer flush for a channel is only revelant when this transfer is source peripheral synchronized. So we have to check this condition before requesting a channel flush by writing the channel bit into the Global channel SoftWare Flush (GSWF) register then waiting for flush to complete by monitoring the end of Flush Interrupt Status (FIS) bit in the Channel Interrupt Status (CIS) register. Indeed, for non source peripheral synchronized transfer, writing the channel bit into the GSWF register does nothing. Especially, the FIS bit is never set into the CIS register. The former code looped forever waiting for this bit to be set. Signed-off-by: Cyrille Pitchen Signed-off-by: Ludovic Desroches --- drivers/dma/at_xdmac.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c index fcecbad..fa9d75a 100644 --- a/drivers/dma/at_xdmac.c +++ b/drivers/dma/at_xdmac.c @@ -879,7 +879,7 @@ at_xdmac_tx_status(struct dma_chan *chan, dma_cookie_t cookie, struct list_head *descs_list; enum dma_status ret; int residue; - u32 cur_nda; + u32 cur_nda, mask, value; u8 dwidth = at_xdmac_get_dwidth(atchan->cfg[AT_XDMAC_CUR_CFG]); ret = dma_cookie_status(chan, cookie, txstate); @@ -903,10 +903,17 @@ at_xdmac_tx_status(struct dma_chan *chan, dma_cookie_t cookie, } residue = desc->xfer_size; - /* Flush FIFO. */ - at_xdmac_write(atxdmac, AT_XDMAC_GSWF, atchan->mask); - while (!(at_xdmac_chan_read(atchan, AT_XDMAC_CIS) & AT_XDMAC_CIS_FIS)) - cpu_relax(); + /* + * Flush FIFO: only relevant when the transfer is source peripheral + * synchronized. + */ + mask = AT_XDMAC_CC_TYPE | AT_XDMAC_CC_DSYNC; + value = AT_XDMAC_CC_TYPE_PER_TRAN | AT_XDMAC_CC_DSYNC_PER2MEM; + if ((atchan->cfg[AT_XDMAC_CUR_CFG] & mask) == value) { + at_xdmac_write(atxdmac, AT_XDMAC_GSWF, atchan->mask); + while (!(at_xdmac_chan_read(atchan, AT_XDMAC_CIS) & AT_XDMAC_CIS_FIS)) + cpu_relax(); + } cur_nda = at_xdmac_chan_read(atchan, AT_XDMAC_CNDA) & 0xfffffffc; /*