From patchwork Mon Apr 16 15:40:21 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Sylwester Nawrocki/Kernel \\(PLT\\) /SRPOL/Staff Engineer/Samsung Electronics" X-Patchwork-Id: 10343351 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 8AB9660542 for ; Mon, 16 Apr 2018 15:44:46 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7969B2823D for ; Mon, 16 Apr 2018 15:44:46 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6D7452851A; Mon, 16 Apr 2018 15:44:46 +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=-2.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 3BFD12823D for ; Mon, 16 Apr 2018 15:44:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:References: In-reply-to:Message-id:Date:Subject:To:From:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=B7hGXINSd4hBbFMx6yVeUfmLh9cPb9JtYEzhjD0lg+Q=; b=Lml7/6vGrquZPOQma/Ne6Tdlzo vscAjZYRicBXBjQvr3jBTEuo+FDzkkMai2AgNAvbe3ugYiHQkWFGK5St37vq7/QqRHx4ewKAsnRZw Ox8KgSTwbL/Mu7pdU/+n5Hlh+UJuQPiQf+/+aMVJep8Du0ZgwL27MFjvsefpqJOJZjXS5p1QfOrAb rh1p0HQse7cBx3k1082PSfBP+G2sKgBV7A08DQM9Vac5MIiSc3+0Oq4eBrt2rTYtFnZ4zpcgFGTSF WeTJL0Xc/qI+Aek+U3XmoVCFE7c9IAj4RRHwfHOwpOoT59OF1z+CFF8J8Ty2FB9H5LYxWLmLrg1jm epH3XPNQ==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1f86J1-0007CL-HI; Mon, 16 Apr 2018 15:44:35 +0000 Received: from mailout4.samsung.com ([203.254.224.34]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1f86Gr-00061R-Ca for linux-arm-kernel@lists.infradead.org; Mon, 16 Apr 2018 15:42:41 +0000 Received: from epcas1p3.samsung.com (unknown [182.195.41.47]) by mailout4.samsung.com (KnoxPortal) with ESMTP id 20180416154209epoutp04a3bf52bbc4ff37cc4e2d534eaff28bc1~l9Oi8yB4T3185031850epoutp04N; Mon, 16 Apr 2018 15:42:09 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout4.samsung.com 20180416154209epoutp04a3bf52bbc4ff37cc4e2d534eaff28bc1~l9Oi8yB4T3185031850epoutp04N DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1523893329; bh=/ppuRWksEsEQFaWwOZ4/OQ3MREzZHZi3U0YJYJ8YgS4=; h=From:To:Cc:Subject:Date:In-reply-to:References:From; b=nW/gBWtfkUQHGQUccEU79kGEm+mWYeRqAIrwwf9WfS0YeJ+qWlIK9s+BtqxxSGqM+ CO33UvnEYjc838gqgZN/UMOqP5IZpZr4U40F9Npybdj5s6AeaqY7N2bHo8lt/bu9we 8pNaQzY6r4NLzOT+7eSs2Vg4lNoqxxSAy1+ajuvM= Received: from epsmges1p1.samsung.com (unknown [182.195.42.53]) by epcas1p4.samsung.com (KnoxPortal) with ESMTP id 20180416154209epcas1p41e72bbc18ff8ed992cb0204c9ca8882b~l9Oiz3AYb2416624166epcas1p46; Mon, 16 Apr 2018 15:42:09 +0000 (GMT) Received: from epcas1p4.samsung.com ( [182.195.41.48]) by epsmges1p1.samsung.com (Symantec Messaging Gateway) with SMTP id 90.D6.04078.154C4DA5; Tue, 17 Apr 2018 00:42:09 +0900 (KST) Received: from epsmgms2p1new.samsung.com (unknown [182.195.42.142]) by epcas1p1.samsung.com (KnoxPortal) with ESMTP id 20180416154208epcas1p1774dd679e3564be916901a180315943b~l9OiMRSsa1555615556epcas1p1h; Mon, 16 Apr 2018 15:42:08 +0000 (GMT) X-AuditID: b6c32a35-139ff70000000fee-48-5ad4c451ff1c Received: from epmmp2 ( [203.254.227.17]) by epsmgms2p1new.samsung.com (Symantec Messaging Gateway) with SMTP id C7.E1.03849.054C4DA5; Tue, 17 Apr 2018 00:42:08 +0900 (KST) Received: from AMDC3061.digital.local ([106.116.147.40]) by mmp2.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTPA id <0P7A004PTBJEDK00@mmp2.samsung.com>; Tue, 17 Apr 2018 00:42:08 +0900 (KST) From: Sylwester Nawrocki To: broonie@kernel.org Subject: [PATCH 6/6] spi: spi-s3c64xx: Allow higher transfer lengths in polling IO mode Date: Mon, 16 Apr 2018 17:40:21 +0200 Message-id: <20180416154021.25626-6-s.nawrocki@samsung.com> X-Mailer: git-send-email 2.14.2 In-reply-to: <20180416154021.25626-1-s.nawrocki@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrEIsWRmVeSWpSXmKPExsWy7bCmgW7gkStRBnO+clks/vGcyWLjjPWs FlMfPmGz6H/8mtni/PkN7BabHl9jtZhxfh+TRePHm+wWa4/cZbc4/Kad1YHL4/qST8wem1Z1 snlsXlLv0bdlFaPH501yAaxRXDYpqTmZZalF+nYJXBnr/v1lKnioXHH91hqmBsbv0l2MnBwS AiYSk089YO9i5OIQEtjBKPH3znxWCOc7o8T/7a9ZYapmvprACJHYwCixe28DVMsvRonFR/az gFSxCRhK9B7tYwSxRQTEJG7P6WQGKWIWaGKSaH2wDmyUsECkxJ4fe8BsFgFViT0f5rCB2LwC 1hLdG/8zQqyTl3i/4D6YzSlgI3H870mwQRICC9gktu+eAbSNA8hxkfi/XxWiXlji1fEt7BBh aYlLR20hwtUSnW1d7BCtLYwSf6ZdYoNIWEscPn4R7AZmAT6Jd197WCF6eSU62oQgSjwkzl7b wwJhO0q0nz7IAvFwP6NEb98B9gmMUgsYGVYxiqUWFOempxYbFhjqFSfmFpfmpesl5+duYgTH rJbpDsYp53wOMQpwMCrx8ErsuBIlxJpYVlyZe4hRgoNZSYR3/iGgEG9KYmVValF+fFFpTmrx IUZpDhYlcd6nPmeihATSE0tSs1NTC1KLYLJMHJxSDYyqX3aGvp2wRTq9T+GZWsmdbdqyjP+t qgOKjnDF/609rZb1fpG3ImMSE/s0O83d3xaXu6hN/hx1U0JMLOpJUjcbkzX/ta+HPnrdODD/ V/lxQyWeOTz3BRbzXljTrX4vNj83xd5Ia7rfMafvGdJGsm9j+n8zrtkUscO7Kz5IftW0HANP 2RMblZRYijMSDbWYi4oTAd0Dhc/VAgAA X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFprNLMWRmVeSWpSXmKPExsVy+t9jQd2AI1eiDK49k7VY/OM5k8XGGetZ LaY+fMJm0f/4NbPF+fMb2C02Pb7GajHj/D4mi8aPN9kt1h65y25x+E07qwOXx/Uln5g9Nq3q ZPPYvKTeo2/LKkaPz5vkAlijuGxSUnMyy1KL9O0SuDLW/fvLVPBQueL6rTVMDYzfpbsYOTkk BEwkZr6awNjFyMUhJLCOUWL57K9sEM4vRomH93sZQarYBAwleo/2gdkiAmISt+d0MoMUMQs0 MUm8//yZGSQhLBAp8e/OQrAiFgFViT0f5rCB2LwC1hLdG/8zQqyTl3i/4D6YzSlgI3H870mw XiGgmitLX7NOYORZwMiwilEytaA4Nz232KjAMC+1XK84Mbe4NC9dLzk/dxMjMMi2Hdbq28F4 f0n8IUYBDkYlHl6JHVeihFgTy4orcw8xSnAwK4nwzj8EFOJNSaysSi3Kjy8qzUktPsQozcGi JM57O+9YpJBAemJJanZqakFqEUyWiYNTqoHRRPpeoU1jgP45hef35tXuaEgxT+fZ/1ZR8+1U ge8THddP7jw1TfrmxVKGpu7fZ3Wf5N9ec6wp0fIbk6WAoPDnjAWFuREa7zyS4tuzOKrnlXno PnhmpBQf6Bl3/Zq55QztmJdCMhKbX3P+mNtQWv3I0Dkg8q+rtmdKx+IcpZxXniaZn98mTlNi Kc5INNRiLipOBADoMeC3LgIAAA== X-CMS-MailID: 20180416154208epcas1p1774dd679e3564be916901a180315943b X-Msg-Generator: CA CMS-TYPE: 101P X-CMS-RootMailID: 20180416154208epcas1p1774dd679e3564be916901a180315943b X-RootMTR: 20180416154208epcas1p1774dd679e3564be916901a180315943b References: <20180416154021.25626-1-s.nawrocki@samsung.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20180416_084221_650757_589D6CA2 X-CRM114-Status: GOOD ( 19.84 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linux-samsung-soc@vger.kernel.org, Sylwester Nawrocki , b.zolnierkie@samsung.com, krzk@kernel.org, linux-spi@vger.kernel.org, kgene@kernel.org, andi@etezian.org, linux-arm-kernel@lists.infradead.org, m.szyprowski@samsung.com MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP Some variants of the SPI controller have no DMA support, in such case SPI transfers longer than the FIFO length are not currently properly handled by the driver. Fix it by doing multiple transfers in the s3c64xx_spi_transfer_one() function if the SPI transfer length exceeds the FIFO size. Signed-off-by: Sylwester Nawrocki --- drivers/spi/spi-s3c64xx.c | 108 ++++++++++++++++++++++++++++++---------------- 1 file changed, 71 insertions(+), 37 deletions(-) diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c index 2723fa6bed8b..b2e8ed354dac 100644 --- a/drivers/spi/spi-s3c64xx.c +++ b/drivers/spi/spi-s3c64xx.c @@ -349,7 +349,7 @@ static bool s3c64xx_spi_can_dma(struct spi_master *master, } static void s3c64xx_enable_datapath(struct s3c64xx_spi_driver_data *sdd, - struct spi_transfer *xfer, int dma_mode) + struct spi_transfer *xfer, bool dma_mode) { void __iomem *regs = sdd->regs; u32 modecfg, chcfg; @@ -634,11 +634,15 @@ static int s3c64xx_spi_transfer_one(struct spi_master *master, struct spi_transfer *xfer) { struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master); + const unsigned int fifo_len = (FIFO_LVL_MASK(sdd) >> 1) + 1; + const void *tx_buf = NULL; + void *rx_buf = NULL; + int target_len = 0, origin_len = 0; + bool use_dma = false; int status; u32 speed; u8 bpw; unsigned long flags; - int use_dma; reinit_completion(&sdd->xfer_completion); @@ -653,48 +657,78 @@ static int s3c64xx_spi_transfer_one(struct spi_master *master, s3c64xx_spi_config(sdd); } - /* Polling method for xfers not bigger than FIFO capacity */ - use_dma = 0; - if (!is_polling(sdd) && - (sdd->rx_dma.ch && sdd->tx_dma.ch && - (xfer->len > ((FIFO_LVL_MASK(sdd) >> 1) + 1)))) - use_dma = 1; + if (!is_polling(sdd) && (xfer->len > fifo_len) && + sdd->rx_dma.ch && sdd->tx_dma.ch) { + use_dma = true; - spin_lock_irqsave(&sdd->lock, flags); + } else if (is_polling(sdd) && xfer->len > fifo_len) { + tx_buf = xfer->tx_buf; + rx_buf = xfer->rx_buf; + origin_len = xfer->len; - /* Pending only which is to be done */ - sdd->state &= ~RXBUSY; - sdd->state &= ~TXBUSY; + target_len = xfer->len; + if (xfer->len > fifo_len) + xfer->len = fifo_len; + } + + do { + spin_lock_irqsave(&sdd->lock, flags); - s3c64xx_enable_datapath(sdd, xfer, use_dma); + /* Pending only which is to be done */ + sdd->state &= ~RXBUSY; + sdd->state &= ~TXBUSY; - /* Start the signals */ - s3c64xx_spi_set_cs(spi, true); + s3c64xx_enable_datapath(sdd, xfer, use_dma); - spin_unlock_irqrestore(&sdd->lock, flags); + /* Start the signals */ + s3c64xx_spi_set_cs(spi, true); - if (use_dma) - status = wait_for_dma(sdd, xfer); - else - status = wait_for_pio(sdd, xfer); - - if (status) { - dev_err(&spi->dev, "I/O Error: rx-%d tx-%d res:rx-%c tx-%c len-%d\n", - xfer->rx_buf ? 1 : 0, xfer->tx_buf ? 1 : 0, - (sdd->state & RXBUSY) ? 'f' : 'p', - (sdd->state & TXBUSY) ? 'f' : 'p', - xfer->len); - - if (use_dma) { - if (xfer->tx_buf != NULL - && (sdd->state & TXBUSY)) - dmaengine_terminate_all(sdd->tx_dma.ch); - if (xfer->rx_buf != NULL - && (sdd->state & RXBUSY)) - dmaengine_terminate_all(sdd->rx_dma.ch); + spin_unlock_irqrestore(&sdd->lock, flags); + + if (use_dma) + status = wait_for_dma(sdd, xfer); + else + status = wait_for_pio(sdd, xfer); + + if (status) { + dev_err(&spi->dev, + "I/O Error: rx-%d tx-%d res:rx-%c tx-%c len-%d\n", + xfer->rx_buf ? 1 : 0, xfer->tx_buf ? 1 : 0, + (sdd->state & RXBUSY) ? 'f' : 'p', + (sdd->state & TXBUSY) ? 'f' : 'p', + xfer->len); + + if (use_dma) { + if (xfer->tx_buf && (sdd->state & TXBUSY)) + dmaengine_terminate_all(sdd->tx_dma.ch); + if (xfer->rx_buf && (sdd->state & RXBUSY)) + dmaengine_terminate_all(sdd->rx_dma.ch); + } + } else { + flush_fifo(sdd); } - } else { - flush_fifo(sdd); + + if (target_len > 0) { + target_len -= xfer->len; + + if (xfer->tx_buf) + xfer->tx_buf += xfer->len; + + if (xfer->rx_buf) + xfer->rx_buf += xfer->len; + + if (target_len > fifo_len) + xfer->len = fifo_len; + else + xfer->len = target_len; + } + } while (target_len > 0); + + if (origin_len) { + /* Restore original xfer buffers and length */ + xfer->tx_buf = tx_buf; + xfer->rx_buf = rx_buf; + xfer->len = origin_len; } return status;