All of lore.kernel.org
 help / color / mirror / Atom feed
From: Serge Semin <Sergey.Semin@baikalelectronics.ru>
To: Mark Brown <broonie@kernel.org>
Cc: Serge Semin <Sergey.Semin@baikalelectronics.ru>,
	Serge Semin <fancer.lancer@gmail.com>,
	Alexey Malahov <Alexey.Malahov@baikalelectronics.ru>,
	Ramil Zaripov <Ramil.Zaripov@baikalelectronics.ru>,
	Pavel Parkhomenko <Pavel.Parkhomenko@baikalelectronics.ru>,
	Andy Shevchenko <andy.shevchenko@gmail.com>,
	Andy Shevchenko <andriy.shevchenko@linux.intel.com>,
	Lars Povlsen <lars.povlsen@microchip.com>,
	"wuxu . wu" <wuxu.wu@huawei.com>, Feng Tang <feng.tang@intel.com>,
	Rob Herring <robh+dt@kernel.org>, <linux-spi@vger.kernel.org>,
	<devicetree@vger.kernel.org>, <linux-kernel@vger.kernel.org>
Subject: [PATCH v3 09/21] spi: dw: Refactor IRQ-based SPI transfer procedure
Date: Fri, 2 Oct 2020 01:28:17 +0300	[thread overview]
Message-ID: <20201001222829.15977-10-Sergey.Semin@baikalelectronics.ru> (raw)
In-Reply-To: <20201001222829.15977-1-Sergey.Semin@baikalelectronics.ru>

Current IRQ-based SPI transfer execution procedure doesn't work well at
the final stage of the execution. If all the Tx data is sent out (written
to the Tx FIFO) but there is some data left to receive, the Tx FIFO Empty
IRQ will constantly happen until all of the requested inbound data is
received. Though for a short period of time, but it will make the system
less responsive. In order to fix that let's refactor the SPI transfer
execution procedure by taking the Rx FIFO Full IRQ into account. We'll read
and write SPI transfer data each time the IRQ happens as before. If all
the outbound data is sent out, we'll disable the Tx FIFO Empty IRQ. If
there is still some data to receive, we'll adjust the Rx FIFO Threshold
level, so the next IRQ would be raised at the moment of all incoming data
being available in the Rx FIFO.

Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru>
---
 drivers/spi/spi-dw-core.c | 33 ++++++++++++++++++++++++---------
 1 file changed, 24 insertions(+), 9 deletions(-)

diff --git a/drivers/spi/spi-dw-core.c b/drivers/spi/spi-dw-core.c
index 4baf72b121c2..74e8f0da2883 100644
--- a/drivers/spi/spi-dw-core.c
+++ b/drivers/spi/spi-dw-core.c
@@ -189,17 +189,30 @@ static irqreturn_t interrupt_transfer(struct dw_spi *dws)
 		return IRQ_HANDLED;
 	}
 
+	/*
+	 * Read data from the Rx FIFO every time we've got a chance executing
+	 * this method. If there is nothing left to receive, terminate the
+	 * procedure. Otherwise adjust the Rx FIFO Threshold level if it's a
+	 * final stage of the transfer. By doing so we'll get the next IRQ
+	 * right when the leftover incoming data is received.
+	 */
 	dw_reader(dws);
 	if (!dws->rx_len) {
 		spi_mask_intr(dws, 0xff);
 		spi_finalize_current_transfer(dws->master);
-		return IRQ_HANDLED;
+	} else if (dws->rx_len <= dw_readl(dws, DW_SPI_RXFTLR)) {
+		dw_writel(dws, DW_SPI_RXFTLR, dws->rx_len - 1);
 	}
+
+	/*
+	 * Send data out if Tx FIFO Empty IRQ is received. The IRQ will be
+	 * disabled after the data transmission is finished so not to
+	 * have the TXE IRQ flood at the final stage of the transfer.
+	 */
 	if (irq_status & SPI_INT_TXEI) {
-		spi_mask_intr(dws, SPI_INT_TXEI);
 		dw_writer(dws);
-		/* Enable TX irq always, it will be disabled when RX finished */
-		spi_umask_intr(dws, SPI_INT_TXEI);
+		if (!dws->tx_len)
+			spi_mask_intr(dws, SPI_INT_TXEI);
 	}
 
 	return IRQ_HANDLED;
@@ -338,10 +351,6 @@ static int dw_spi_transfer_one(struct spi_controller *master,
 	/* For poll mode just disable all interrupts */
 	spi_mask_intr(dws, 0xff);
 
-	/*
-	 * Interrupt mode
-	 * we only need set the TXEI IRQ, as TX/RX always happen syncronizely
-	 */
 	if (dws->dma_mapped) {
 		ret = dws->dma_ops->dma_setup(dws, transfer);
 		if (ret < 0) {
@@ -349,12 +358,18 @@ static int dw_spi_transfer_one(struct spi_controller *master,
 			return ret;
 		}
 	} else {
+		/*
+		 * Originally Tx and Rx data lengths match. Rx FIFO Threshold level
+		 * will be adjusted at the final stage of the IRQ-based SPI transfer
+		 * execution so not to lose the leftover of the incoming data.
+		 */
 		txlevel = min_t(u16, dws->fifo_len / 2, dws->tx_len);
 		dw_writel(dws, DW_SPI_TXFTLR, txlevel);
+		dw_writel(dws, DW_SPI_RXFTLR, txlevel - 1);
 
 		/* Set the interrupt mask */
 		imask |= SPI_INT_TXEI | SPI_INT_TXOI |
-			 SPI_INT_RXUI | SPI_INT_RXOI;
+			 SPI_INT_RXUI | SPI_INT_RXOI | SPI_INT_RXFI;
 		spi_umask_intr(dws, imask);
 
 		dws->transfer_handler = interrupt_transfer;
-- 
2.27.0


  parent reply	other threads:[~2020-10-01 22:30 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-10-01 22:28 [PATCH v3 00/21] spi: dw: Add full Baikal-T1 SPI Controllers support Serge Semin
2020-10-01 22:28 ` [PATCH v3 01/21] spi: dw: Use an explicit set_cs assignment Serge Semin
2020-10-01 22:28 ` [PATCH v3 02/21] spi: dw: Add DWC SSI capability Serge Semin
2020-10-02 10:19   ` Andy Shevchenko
2020-10-02 17:18     ` Serge Semin
2020-10-02 18:26       ` Andy Shevchenko
2020-10-02 19:46         ` Serge Semin
2020-10-02 20:08           ` Serge Semin
2020-10-02 20:12             ` Serge Semin
2020-10-01 22:28 ` [PATCH v3 03/21] spi: dw: Detach SPI device specific CR0 config method Serge Semin
2020-10-02 10:22   ` Andy Shevchenko
2020-10-02 17:47     ` Serge Semin
2020-10-02 18:24       ` Andy Shevchenko
2020-10-02 19:56         ` Serge Semin
2020-10-01 22:28 ` [PATCH v3 04/21] spi: dw: Update SPI bus speed in a config function Serge Semin
2020-10-01 22:28 ` [PATCH v3 05/21] spi: dw: Simplify the SPI bus speed config procedure Serge Semin
2020-10-01 22:28 ` [PATCH v3 06/21] spi: dw: Update Rx sample delay in the config function Serge Semin
2020-10-01 22:28 ` [PATCH v3 07/21] spi: dw: Add DW SPI controller config structure Serge Semin
2020-10-01 22:28 ` [PATCH v3 08/21] spi: dw: Refactor data IO procedure Serge Semin
2020-10-01 22:28 ` Serge Semin [this message]
2020-10-01 22:28 ` [PATCH v3 10/21] spi: dw: Perform IRQ setup in a dedicated function Serge Semin
2020-10-01 22:28 ` [PATCH v3 11/21] spi: dw: Unmask IRQs after enabling the chip Serge Semin
2020-10-01 22:28 ` [PATCH v3 12/21] spi: dw: Discard chip enabling on DMA setup error Serge Semin
2020-10-01 22:28 ` [PATCH v3 13/21] spi: dw: De-assert chip-select on reset Serge Semin
2020-10-01 22:28 ` [PATCH v3 14/21] spi: dw: Explicitly de-assert CS on SPI transfer completion Serge Semin
2020-10-01 22:28 ` [PATCH v3 15/21] spi: dw: Move num-of retries parameter to the header file Serge Semin
2020-10-01 22:28 ` [PATCH v3 16/21] spi: dw: Add generic DW SSI status-check method Serge Semin
2020-10-01 22:28 ` [PATCH v3 17/21] spi: dw: Add memory operations support Serge Semin
2020-10-01 22:28 ` [PATCH v3 18/21] spi: dw: Introduce max mem-ops SPI bus frequency setting Serge Semin
2020-10-01 22:28 ` [PATCH v3 19/21] spi: dw: Add poll-based SPI transfers support Serge Semin
2020-10-01 22:28 ` [PATCH v3 20/21] dt-bindings: spi: dw: Add Baikal-T1 SPI Controllers Serge Semin
2020-10-01 22:28 ` [PATCH v3 21/21] spi: dw: Add Baikal-T1 SPI Controller glue driver Serge Semin
2020-10-02 10:24 ` [PATCH v3 00/21] spi: dw: Add full Baikal-T1 SPI Controllers support Andy Shevchenko
2020-10-02 12:55   ` Mark Brown
2020-10-02 18:26     ` Andy Shevchenko

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20201001222829.15977-10-Sergey.Semin@baikalelectronics.ru \
    --to=sergey.semin@baikalelectronics.ru \
    --cc=Alexey.Malahov@baikalelectronics.ru \
    --cc=Pavel.Parkhomenko@baikalelectronics.ru \
    --cc=Ramil.Zaripov@baikalelectronics.ru \
    --cc=andriy.shevchenko@linux.intel.com \
    --cc=andy.shevchenko@gmail.com \
    --cc=broonie@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=fancer.lancer@gmail.com \
    --cc=feng.tang@intel.com \
    --cc=lars.povlsen@microchip.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-spi@vger.kernel.org \
    --cc=robh+dt@kernel.org \
    --cc=wuxu.wu@huawei.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.