From patchwork Sun Jul 22 21:20:09 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Andreas_F=C3=A4rber?= X-Patchwork-Id: 142516 Delivered-To: patch@linaro.org Received: by 2002:a2e:9754:0:0:0:0:0 with SMTP id f20-v6csp5356812ljj; Sun, 22 Jul 2018 14:20:35 -0700 (PDT) X-Google-Smtp-Source: AAOMgpfeU7Iqvtmnn4het6Wr8B3nqiEhscPOis2/mOvi8JJ5oiXtaXbIYq4WTcalF8FRruNOqMbM X-Received: by 2002:a17:902:bd44:: with SMTP id b4-v6mr10462244plx.144.1532294435664; Sun, 22 Jul 2018 14:20:35 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1532294435; cv=none; d=google.com; s=arc-20160816; b=PKAJRLCVOY5pZc/4kWHhmvUIdwDFmOb/JZyKYwkTpHxEUIid2iemj3Hir+eb0ZkKWL xEeQQTfu+S9MtofckZUkeKHfG3P3SafnC4agDHgp9JKhxrq+xBlHpd9meNNx6TrLJjKB ChSmLnMPIT5MfjlG5fn7Ul3GESy6NkxgGCpki62QxGNWYfMrIlnr/uP/h994c50gX8UV iKEDjEkkEFjyNuJnqM1p0TSf13fxQMPM8+glbwN6q88VBSwVCnUMiWO4zSEKz1SA23Zh vzB6KWXELwaJVgKiwEHvqAnPKkesnLKKyB6LMV4B64A/eYdI7SzOndh6ZoB31uPsRH4o 52ew== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=pRNjCloX34FJypPfhznajCFlLsFlSMebc/RSMW2RPMg=; b=Ff99VRy08ybGMJ2LRZSwXAXln6J2MMDS25GwNu3CMDYkuYpg9dsmUYso/FdoqbD6yY Hsbo+DIKqf5Bk/Fz2zebfMJ+FJxFRCIDqGwuYn1Ol4Nr2JVLZL4uv18TcqMzlhbpTF49 mSH43BKnTGrbGspW2n/uXwDOx8nKQqolT95I7B+aYcQpdRU/hrGWppq4/XyaFV5oE70z fVlnRhD7gA/6xWs9X0MpCFO7GYpTRTARhCvA6J87zj4NPePKFv595zyfNFFvmEfhUWnx 1tbkv9LRw5SB9f1KPgGCB+t7tNzMKZr/1jO3SH39+8JrCmRMe/K5pFgikhyj5oOFMBj8 VrTA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id k23-v6si7074765pgl.633.2018.07.22.14.20.35; Sun, 22 Jul 2018 14:20:35 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2387920AbeGVWSd (ORCPT + 31 others); Sun, 22 Jul 2018 18:18:33 -0400 Received: from mx2.suse.de ([195.135.220.15]:38830 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S2387797AbeGVWS0 (ORCPT ); Sun, 22 Jul 2018 18:18:26 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id 02F20AFE1; Sun, 22 Jul 2018 21:20:24 +0000 (UTC) From: =?utf-8?q?Andreas_F=C3=A4rber?= To: linux-mips@linux-mips.org Cc: Ralf Baechle , Paul Burton , James Hogan , linux-kernel@vger.kernel.org, Ionela Voinescu , =?utf-8?q?Andreas_F=C3=A4rber?= , Mark Brown , linux-spi@vger.kernel.org Subject: [PATCH 14/15] spi: img-spfi: Finish every transfer cleanly Date: Sun, 22 Jul 2018 23:20:09 +0200 Message-Id: <20180722212010.3979-15-afaerber@suse.de> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20180722212010.3979-1-afaerber@suse.de> References: <20180722212010.3979-1-afaerber@suse.de> MIME-Version: 1.0 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Ionela Voinescu Before this change, the interrupt status bit that signaled the end of a transfer was cleared in the wait_all_done function. That functionality triggered issues for DMA duplex transactions where the wait function was called twice, in both the TX and RX callbacks. In order to fix the issue, clear all interrupt data bits at the end of a PIO transfer or at the end of both TX and RX duplex transfers, if the transfer is not a pending transfer (command waiting for data). After that, the status register is checked for new incoming data or new data requests to be signaled. If SPFI finished cleanly, no new interrupt data bits should be set. Signed-off-by: Ionela Voinescu Signed-off-by: Andreas Färber --- drivers/spi/spi-img-spfi.c | 49 +++++++++++++++++++++++++++++++++------------- 1 file changed, 35 insertions(+), 14 deletions(-) -- 2.16.4 diff --git a/drivers/spi/spi-img-spfi.c b/drivers/spi/spi-img-spfi.c index 8ad6c75d0af5..a1244234daa5 100644 --- a/drivers/spi/spi-img-spfi.c +++ b/drivers/spi/spi-img-spfi.c @@ -83,6 +83,14 @@ #define SPFI_INTERRUPT_SDE BIT(1) #define SPFI_INTERRUPT_SDTRIG BIT(0) +#define SPFI_INTERRUPT_DATA_BITS (SPFI_INTERRUPT_SDHF |\ + SPFI_INTERRUPT_SDFUL |\ + SPFI_INTERRUPT_GDEX32BIT |\ + SPFI_INTERRUPT_GDHF |\ + SPFI_INTERRUPT_GDFUL |\ + SPFI_INTERRUPT_ALLDONETRIG |\ + SPFI_INTERRUPT_GDEX8BIT) + /* * There are four parallel FIFOs of 16 bytes each. The word buffer * (*_32BIT_VALID_DATA) accesses all four FIFOs at once, resulting in an @@ -144,6 +152,23 @@ static inline void spfi_reset(struct img_spfi *spfi) spfi_writel(spfi, 0, SPFI_CONTROL); } +static inline void spfi_finish(struct img_spfi *spfi) +{ + if (!(spfi->complete)) + return; + + /* Clear data bits as all transfers(TX and RX) have finished */ + spfi_writel(spfi, SPFI_INTERRUPT_DATA_BITS, SPFI_INTERRUPT_CLEAR); + if (spfi_readl(spfi, SPFI_INTERRUPT_STATUS) & SPFI_INTERRUPT_DATA_BITS) { + dev_err(spfi->dev, "SPFI did not finish transfer cleanly.\n"); + spfi_reset(spfi); + } + /* Disable SPFI for it not to interfere with pending transactions */ + spfi_writel(spfi, + spfi_readl(spfi, SPFI_CONTROL) & ~SPFI_CONTROL_SPFI_EN, + SPFI_CONTROL); +} + static int spfi_wait_all_done(struct img_spfi *spfi) { unsigned long timeout = jiffies + msecs_to_jiffies(50); @@ -152,19 +177,9 @@ static int spfi_wait_all_done(struct img_spfi *spfi) return 0; while (time_before(jiffies, timeout)) { - u32 status = spfi_readl(spfi, SPFI_INTERRUPT_STATUS); - - if (status & SPFI_INTERRUPT_ALLDONETRIG) { - spfi_writel(spfi, SPFI_INTERRUPT_ALLDONETRIG, - SPFI_INTERRUPT_CLEAR); - /* - * Disable SPFI for it not to interfere with - * pending transactions - */ - spfi_writel(spfi, spfi_readl(spfi, SPFI_CONTROL) - & ~SPFI_CONTROL_SPFI_EN, SPFI_CONTROL); + if (spfi_readl(spfi, SPFI_INTERRUPT_STATUS) & + SPFI_INTERRUPT_ALLDONETRIG) return 0; - } cpu_relax(); } @@ -296,6 +311,8 @@ static int img_spfi_start_pio(struct spi_master *master, } ret = spfi_wait_all_done(spfi); + spfi_finish(spfi); + if (ret < 0) return ret; @@ -311,8 +328,10 @@ static void img_spfi_dma_rx_cb(void *data) spin_lock_irqsave(&spfi->lock, flags); spfi->rx_dma_busy = false; - if (!spfi->tx_dma_busy) + if (!spfi->tx_dma_busy) { + spfi_finish(spfi); spi_finalize_current_transfer(spfi->master); + } spin_unlock_irqrestore(&spfi->lock, flags); } @@ -325,8 +344,10 @@ static void img_spfi_dma_tx_cb(void *data) spin_lock_irqsave(&spfi->lock, flags); spfi->tx_dma_busy = false; - if (!spfi->rx_dma_busy) + if (!spfi->rx_dma_busy) { + spfi_finish(spfi); spi_finalize_current_transfer(spfi->master); + } spin_unlock_irqrestore(&spfi->lock, flags); }