From patchwork Wed Sep 6 07:05:03 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dirk Behme X-Patchwork-Id: 9940017 X-Patchwork-Delegate: geert@linux-m68k.org Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id CB283602CC for ; Wed, 6 Sep 2017 07:05:21 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id BB61628AFA for ; Wed, 6 Sep 2017 07:05:21 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B03C228AFC; Wed, 6 Sep 2017 07:05:21 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 34A1128B04 for ; Wed, 6 Sep 2017 07:05:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751365AbdIFHFU (ORCPT ); Wed, 6 Sep 2017 03:05:20 -0400 Received: from smtp6-v.fe.bosch.de ([139.15.237.11]:57114 "EHLO smtp6-v.fe.bosch.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751880AbdIFHFO (ORCPT ); Wed, 6 Sep 2017 03:05:14 -0400 Received: from vsmta13.fe.internet.bosch.com (unknown [10.4.98.53]) by imta24.fe.bosch.de (Postfix) with ESMTP id 2265CD80230; Wed, 6 Sep 2017 09:04:44 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=de.bosch.com; s=2015-01-21; t=1504681484; bh=bnJlX5T3TB7ah7g65K1hjzsLH4EyNbpElOYrWxHUJGs=; l=10; h=From:From:Reply-To:Sender; b=I6Gc3gNMPgDgShWyhaJlzozd2QzovifJjOimqv5JS4V8m+YdrGZg82HdnP9dXp8B2 ljiDkyUbhrVJGjwJxwKgw/+loAKLMiAmKGPmNhuMHExiSFggz8hSE+QzUo7xwLbwna riRsDNMDoSQmEfDVgF80wF2lzkxpzx4OGJiheJ7g= Received: from FE-HUB1000.de.bosch.com (vsgw24.fe.internet.bosch.com [10.4.98.24]) by vsmta13.fe.internet.bosch.com (Postfix) with ESMTP id 11C382E403DB; Wed, 6 Sep 2017 09:05:13 +0200 (CEST) Received: from HI-Z0EVG.hi.de.bosch.com (10.34.218.219) by FE-HUB1000.de.bosch.com (10.4.103.107) with Microsoft SMTP Server id 14.3.319.2; Wed, 6 Sep 2017 09:05:11 +0200 Received: from HI-Z0EVG.hi.de.bosch.com (localhost [IPv6:::1]) by HI-Z0EVG.hi.de.bosch.com (Postfix) with ESMTP id C2EF71B46B11; Wed, 6 Sep 2017 09:05:10 +0200 (CEST) From: Dirk Behme To: , , Geert Uytterhoeven CC: Ryo Kataoka , Hiromitsu Yamasaki , Dirk Behme Subject: [PATCH 4/8] spi: sh-msiof: Fix DMA completion Date: Wed, 6 Sep 2017 09:05:03 +0200 Message-ID: <20170906070507.26223-5-dirk.behme@de.bosch.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20170906070507.26223-1-dirk.behme@de.bosch.com> References: <20170906070507.26223-1-dirk.behme@de.bosch.com> MIME-Version: 1.0 X-TM-AS-MML: disable X-TM-AS-Product-Ver: IMSS-7.1.0.1679-8.0.0.1202-23304.006 X-TMASE-MatchedRID: WY68sLfT96/GLB36IdoHUkj2sPWKvtn0TI0NfY99MMnRLEyE6G4DRD5R eTebdoC/9XAVkK+FSNVVF51vxLbfWW5/NyTKlG694RtSDjG+z7DvJY9pBzgg1BS11FlOYRohlLL 7sycqCUbiKHIoXqxHzF/XESyifWQWfMalxiFMN0rJ5W6OZe5hhQ/i8FY2vTOBmyiLZetSf8mfop 0ytGwvXiq2rl3dzGQ1152bVG0sIQkDB9IGja9xAWtFg2A0B0IuunWSNEJCN7xtdcoc/jtPixwKy zxtTQcU6NUL0o/NhUzDxBAxQ17wK0ssnI7rFcYqbmjz1Rus2khfJnqmX+gNDX4DPSs1ZmHWgrfE fAe6N49pLddd9zGllg== Sender: linux-renesas-soc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-renesas-soc@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Ryo Kataoka When reception DMA completes before transmission DMA, next transmission DMA may not be able to start. This patch adds wait_for_completion_timeout() to both of reception DMA and transmission DMA. If the driver waits only for the Rx DMA completion, the Tx DMA completion thread of DMA Engine may be still processing. Signed-off-by: Ryo Kataoka [reword commit message] Signed-off-by: Hiromitsu Yamasaki [adjust context] Signed-off-by: Dirk Behme --- drivers/spi/spi-sh-msiof.c | 53 +++++++++++++++++++++++++++++++--------------- 1 file changed, 36 insertions(+), 17 deletions(-) diff --git a/drivers/spi/spi-sh-msiof.c b/drivers/spi/spi-sh-msiof.c index 24b49d3ca9a8..660b03ed6770 100644 --- a/drivers/spi/spi-sh-msiof.c +++ b/drivers/spi/spi-sh-msiof.c @@ -52,6 +52,7 @@ struct sh_msiof_spi_priv { struct platform_device *pdev; struct sh_msiof_spi_info *info; struct completion done; + struct completion done_dma_tx, done_dma_rx; unsigned int tx_fifo_size; unsigned int rx_fifo_size; unsigned int min_div; @@ -621,7 +622,8 @@ static int sh_msiof_slave_abort(struct spi_master *master) return 0; } -static int sh_msiof_wait_for_completion(struct sh_msiof_spi_priv *p) +static int sh_msiof_wait_for_completion(struct sh_msiof_spi_priv *p, + const void *tx, void *rx) { if (spi_controller_is_slave(p->master)) { if (wait_for_completion_interruptible(&p->done) || @@ -630,10 +632,22 @@ static int sh_msiof_wait_for_completion(struct sh_msiof_spi_priv *p) return -EINTR; } } else { - if (!wait_for_completion_timeout(&p->done, HZ)) { - dev_err(&p->pdev->dev, "timeout\n"); - return -ETIMEDOUT; + if (tx) { + if (!wait_for_completion_timeout(&p->done_dma_tx, + HZ)) { + dev_err(&p->pdev->dev, "Tx DMA timeout\n"); + return -ETIMEDOUT; + } } + if (rx) { + if (!wait_for_completion_timeout(&p->done_dma_rx, + HZ)) { + dev_err(&p->pdev->dev, "Rx DMA timeout\n"); + return -ETIMEDOUT; + } + } + + sh_msiof_write(p, IER, 0); } return 0; @@ -680,7 +694,7 @@ static int sh_msiof_spi_txrx_once(struct sh_msiof_spi_priv *p, } /* wait for tx fifo to be emptied / rx fifo to be filled */ - ret = sh_msiof_wait_for_completion(p); + ret = sh_msiof_wait_for_completion(p, tx_buf, rx_buf); if (ret) goto stop_reset; @@ -707,12 +721,18 @@ static int sh_msiof_spi_txrx_once(struct sh_msiof_spi_priv *p, return ret; } -static void sh_msiof_dma_complete(void *arg) +static void sh_msiof_tx_dma_complete(void *arg) { struct sh_msiof_spi_priv *p = arg; - sh_msiof_write(p, IER, 0); - complete(&p->done); + complete(&p->done_dma_tx); +} + +static void sh_msiof_rx_dma_complete(void *arg) +{ + struct sh_msiof_spi_priv *p = arg; + + complete(&p->done_dma_rx); } static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx, @@ -732,7 +752,7 @@ static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx, if (!desc_rx) return -EAGAIN; - desc_rx->callback = sh_msiof_dma_complete; + desc_rx->callback = sh_msiof_rx_dma_complete; desc_rx->callback_param = p; cookie = dmaengine_submit(desc_rx); if (dma_submit_error(cookie)) @@ -751,13 +771,8 @@ static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx, goto no_dma_tx; } - if (rx) { - /* No callback */ - desc_tx->callback = NULL; - } else { - desc_tx->callback = sh_msiof_dma_complete; - desc_tx->callback_param = p; - } + desc_tx->callback = sh_msiof_tx_dma_complete; + desc_tx->callback_param = p; cookie = dmaengine_submit(desc_tx); if (dma_submit_error(cookie)) { ret = cookie; @@ -774,6 +789,8 @@ static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx, sh_msiof_write(p, IER, ier_bits); reinit_completion(&p->done); + reinit_completion(&p->done_dma_tx); + reinit_completion(&p->done_dma_rx); p->slave_aborted = false; /* Now start DMA */ @@ -789,7 +806,7 @@ static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx, } /* wait for tx fifo to be emptied / rx fifo to be filled */ - ret = sh_msiof_wait_for_completion(p); + ret = sh_msiof_wait_for_completion(p, tx, rx); if (ret) goto stop_reset; @@ -1258,6 +1275,8 @@ static int sh_msiof_spi_probe(struct platform_device *pdev) p->min_div = chipdata->min_div; init_completion(&p->done); + init_completion(&p->done_dma_tx); + init_completion(&p->done_dma_rx); p->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(p->clk)) {