All of lore.kernel.org
 help / color / mirror / Atom feed
From: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Jiri Slaby <jirislaby@kernel.org>
Cc: linux-serial@vger.kernel.org, linux-kernel@vger.kernel.org,
	"Jan Kundrát" <jan.kundrat@cesnet.cz>,
	"Mark Brown" <broonie@kernel.org>,
	"Andy Shevchenko" <andy.shevchenko@gmail.com>,
	linux-spi@vger.kernel.org,
	"Thomas Petazzoni" <thomas.petazzoni@bootlin.com>
Subject: [PATCH v2] serial: max310x: rework RX interrupt handling
Date: Thu,  1 Oct 2020 09:44:15 +0200	[thread overview]
Message-ID: <20201001074415.349739-1-thomas.petazzoni@bootlin.com> (raw)

Currently, the RX interrupt logic uses the RXEMPTY interrupt, with the
RXEMPTYINV bit set, which means we get an RX interrupt as soon as the
RX FIFO is non-empty.

However, with the MAX310X having a FIFO of 128 bytes, this makes very
poor use of the FIFO: we trigger an interrupt as soon as the RX FIFO
has one byte, which means a lot of interrupts, each only collecting a
few bytes from the FIFO, causing a significant CPU load.

Instead this commit relies on two other RX interrupt events:

 - MAX310X_IRQ_RXFIFO_BIT, which triggers when the RX FIFO has reached
   a certain threshold, which we define to be half of the FIFO
   size. This ensure we get an interrupt before the RX FIFO fills up.

 - MAX310X_LSR_RXTO_BIT, which triggers when the RX FIFO has received
   some bytes, and then no more bytes are received for a certain
   time. Arbitrarily, this time is defined to the time is takes to
   receive 4 characters.

On a Microchip SAMA5D3 platform that is receiving 20 bytes every 16ms
over one MAX310X UART, this patch has allowed to reduce the CPU
consumption of the interrupt handler thread from ~25% to 6-7%.

Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
---
Changes since v1:
- Fix missing space when closing a comment
---
 drivers/tty/serial/max310x.c | 29 ++++++++++++++++++++++++-----
 1 file changed, 24 insertions(+), 5 deletions(-)

diff --git a/drivers/tty/serial/max310x.c b/drivers/tty/serial/max310x.c
index 8434bd5a8ec7..21130af106bb 100644
--- a/drivers/tty/serial/max310x.c
+++ b/drivers/tty/serial/max310x.c
@@ -1056,9 +1056,9 @@ static int max310x_startup(struct uart_port *port)
 	max310x_port_update(port, MAX310X_MODE1_REG,
 			    MAX310X_MODE1_TRNSCVCTRL_BIT, 0);
 
-	/* Configure MODE2 register & Reset FIFOs*/
-	val = MAX310X_MODE2_RXEMPTINV_BIT | MAX310X_MODE2_FIFORST_BIT;
-	max310x_port_write(port, MAX310X_MODE2_REG, val);
+	/* Reset FIFOs */
+	max310x_port_write(port, MAX310X_MODE2_REG,
+			   MAX310X_MODE2_FIFORST_BIT);
 	max310x_port_update(port, MAX310X_MODE2_REG,
 			    MAX310X_MODE2_FIFORST_BIT, 0);
 
@@ -1086,8 +1086,27 @@ static int max310x_startup(struct uart_port *port)
 	/* Clear IRQ status register */
 	max310x_port_read(port, MAX310X_IRQSTS_REG);
 
-	/* Enable RX, TX, CTS change interrupts */
-	val = MAX310X_IRQ_RXEMPTY_BIT | MAX310X_IRQ_TXEMPTY_BIT;
+	/*
+	 * Let's ask for an interrupt after a timeout equivalent to
+	 * the receiving time of 4 characters after the last character
+	 * has been received.
+	 */
+	max310x_port_write(port, MAX310X_RXTO_REG, 4);
+
+	/*
+	 * Make sure we also get RX interrupts when the RX FIFO is
+	 * filling up quickly, so get an interrupt when half of the RX
+	 * FIFO has been filled in.
+	 */
+	max310x_port_write(port, MAX310X_FIFOTRIGLVL_REG,
+			   MAX310X_FIFOTRIGLVL_RX(MAX310X_FIFO_SIZE / 2));
+
+	/* Enable RX timeout interrupt in LSR */
+	max310x_port_write(port, MAX310X_LSR_IRQEN_REG,
+			   MAX310X_LSR_RXTO_BIT);
+
+	/* Enable LSR, RX FIFO trigger, CTS change interrupts */
+	val = MAX310X_IRQ_LSR_BIT  | MAX310X_IRQ_RXFIFO_BIT | MAX310X_IRQ_TXEMPTY_BIT;
 	max310x_port_write(port, MAX310X_IRQEN_REG, val | MAX310X_IRQ_CTS_BIT);
 
 	return 0;
-- 
2.26.2


             reply	other threads:[~2020-10-01  7:44 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-10-01  7:44 Thomas Petazzoni [this message]
2020-10-01 11:35 ` [PATCH v2] serial: max310x: rework RX interrupt handling Andy Shevchenko
2020-10-28 16:20 ` Jan Kundrát
2020-10-28 17:06   ` Thomas Petazzoni
2020-10-28 17:14     ` Thomas Petazzoni

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=20201001074415.349739-1-thomas.petazzoni@bootlin.com \
    --to=thomas.petazzoni@bootlin.com \
    --cc=andy.shevchenko@gmail.com \
    --cc=broonie@kernel.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=jan.kundrat@cesnet.cz \
    --cc=jirislaby@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-serial@vger.kernel.org \
    --cc=linux-spi@vger.kernel.org \
    /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.