linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/24] LPUART fixes and improvements
@ 2019-07-29 19:52 Andrey Smirnov
  2019-07-29 19:52 ` [PATCH 01/24] tty: serial: fsl_lpuart: fix framing error handling when using DMA Andrey Smirnov
                   ` (24 more replies)
  0 siblings, 25 replies; 31+ messages in thread
From: Andrey Smirnov @ 2019-07-29 19:52 UTC (permalink / raw)
  To: linux-serial
  Cc: Andrey Smirnov, Stefan Agner, Bhuvanchandra DV, Chris Healy,
	Cory Tusar, Lucas Stach, Greg Kroah-Hartman, Jiri Slaby,
	linux-imx, linux-kernel

Everyone:

This series contains fixes/improvements to LPUART dirver I came up
with recently as well as fixes picked up from Toradex and NXP Vybrid
repos.

Feedback is welcome!

Thanks,
Andrey Smirnov

Andrey Smirnov (22):
  tty: serial: fsl_lpuart: Flush HW FIFOs in .flush_buffer
  tty: serial: fsl_lpuart: Simplify RX/TX IRQ handlers
  tty: serial: fsl_lpuart: Fix bogus indentation
  tty: serial: fsl_lpuart: Drop unnecessary sg_set_buf() call
  tty: serial: fsl_lpuart: Drop unnecessary uart_write_wakeup()
  tty: serial: fsl_lpuart: Fix issue in software flow control
  tty: serial: fls_lpuart: Split shared TX IRQ handler into two
  tty: serial: fsl_lpuart: Drop no-op bit opearation
  tty: serial: fsl_lpuart: Drop unnecessary extra parenthesis
  tty: serial: fsl_lpuart: Clear CSTOPB unconditionally
  tty: serial: fsl_lpuart: Use appropriate lpuart32_* I/O funcs
  tty: serial: fsl_lpuart: Introduce lpuart_wait_bit_set()
  tty: serial: fsl_lpuart: Use cpu_relax() instead of barrier()
  tty: serial: fsl_lpuart: Introduce lpuart_stopped_or_empty()
  tty: serial: fsl_lpuart: Drop unnecessary lpuart*_stop_tx()
  tty: serial: fsl_lpuart: Introduce lpuart_dma_shutdown()
  tty: serial: fsl_lpuart: Introduce lpuart_tx_dma_startup()
  tty: serial: fsl_lpuart: Introduce lpuart_rx_dma_startup()
  tty: serial: fsl_lpuart: Introduce lpuart32_configure()
  tty: serial: fsl_lpuart: Introduce lpuart*_setup_watermark_enable()
  tty: serial: fsl_lpuart: Don't enable TIE in .startup() or .resume()
  tty: serial: fsl_lpuart: Ignore TX/RX interrupts if DMA is enabled

Stefan Agner (2):
  tty: serial: fsl_lpuart: fix framing error handling when using DMA
  tty: serial: fsl_lpuart: flush receive FIFO after overruns

 drivers/tty/serial/fsl_lpuart.c | 495 +++++++++++++++++---------------
 1 file changed, 261 insertions(+), 234 deletions(-)

-- 
2.21.0


^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH 01/24] tty: serial: fsl_lpuart: fix framing error handling when using DMA
  2019-07-29 19:52 [PATCH 00/24] LPUART fixes and improvements Andrey Smirnov
@ 2019-07-29 19:52 ` Andrey Smirnov
  2019-07-29 19:52 ` [PATCH 02/24] tty: serial: fsl_lpuart: flush receive FIFO after overruns Andrey Smirnov
                   ` (23 subsequent siblings)
  24 siblings, 0 replies; 31+ messages in thread
From: Andrey Smirnov @ 2019-07-29 19:52 UTC (permalink / raw)
  To: linux-serial
  Cc: Stefan Agner, Max Krummenacher, Andrey Smirnov, Stefan Agner,
	Bhuvanchandra DV, Chris Healy, Cory Tusar, Lucas Stach,
	Greg Kroah-Hartman, Jiri Slaby, linux-imx, linux-kernel

From: Stefan Agner <stefan.agner@toradex.com>

When using DMA framing error get cleared properly. However, due
to the additional read from the data register, an underflow in
the receive FIFO buffer occurs (the FIFO pointer gets out of
sync).

Clear the FIFO in case an underflow has occurred. Also disable the
receiver during this operation and when reading the data register to
minimize potential interference.

Signed-off-by: Stefan Agner <stefan.agner@toradex.com>
Acked-by: Max Krummenacher <max.krummenacher@toradex.com>
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
Cc: Stefan Agner <stefan@agner.ch>
Cc: Bhuvanchandra DV <bhuvanchandra.dv@toradex.com>
Cc: Chris Healy <cphealy@gmail.com>
Cc: Cory Tusar <cory.tusar@zii.aero>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Jiri Slaby <jslaby@suse.com>
Cc: linux-imx@nxp.com
Cc: linux-serial@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/tty/serial/fsl_lpuart.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
index 92dad2b4ec36..586b3513a6b0 100644
--- a/drivers/tty/serial/fsl_lpuart.c
+++ b/drivers/tty/serial/fsl_lpuart.c
@@ -982,6 +982,13 @@ static void lpuart_copy_rx_to_tty(struct lpuart_port *sport)
 		unsigned char sr = readb(sport->port.membase + UARTSR1);
 
 		if (sr & (UARTSR1_PE | UARTSR1_FE)) {
+			unsigned char cr2;
+
+			/* Disable receiver during this operation... */
+			cr2 = readb(sport->port.membase + UARTCR2);
+			cr2 &= ~UARTCR2_RE;
+			writeb(cr2, sport->port.membase + UARTCR2);
+
 			/* Read DR to clear the error flags */
 			readb(sport->port.membase + UARTDR);
 
@@ -989,6 +996,25 @@ static void lpuart_copy_rx_to_tty(struct lpuart_port *sport)
 				sport->port.icount.parity++;
 			else if (sr & UARTSR1_FE)
 				sport->port.icount.frame++;
+			/*
+			 * At this point parity/framing error is
+			 * cleared However, since the DMA already read
+			 * the data register and we had to read it
+			 * again after reading the status register to
+			 * properly clear the flags, the FIFO actually
+			 * underflowed... This requires a clearing of
+			 * the FIFO...
+			 */
+			if (readb(sport->port.membase + UARTSFIFO) &
+			    UARTSFIFO_RXUF) {
+				writeb(UARTSFIFO_RXUF,
+				       sport->port.membase + UARTSFIFO);
+				writeb(UARTCFIFO_RXFLUSH,
+				       sport->port.membase + UARTCFIFO);
+			}
+
+			cr2 |= UARTCR2_RE;
+			writeb(cr2, sport->port.membase + UARTCR2);
 		}
 	}
 
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 02/24] tty: serial: fsl_lpuart: flush receive FIFO after overruns
  2019-07-29 19:52 [PATCH 00/24] LPUART fixes and improvements Andrey Smirnov
  2019-07-29 19:52 ` [PATCH 01/24] tty: serial: fsl_lpuart: fix framing error handling when using DMA Andrey Smirnov
@ 2019-07-29 19:52 ` Andrey Smirnov
  2019-07-29 19:52 ` [PATCH 03/24] tty: serial: fsl_lpuart: Flush HW FIFOs in .flush_buffer Andrey Smirnov
                   ` (22 subsequent siblings)
  24 siblings, 0 replies; 31+ messages in thread
From: Andrey Smirnov @ 2019-07-29 19:52 UTC (permalink / raw)
  To: linux-serial
  Cc: Stefan Agner, Max Krummenacher, Stefan Agner, Bhuvanchandra DV,
	Chris Healy, Cory Tusar, Lucas Stach, Greg Kroah-Hartman,
	Jiri Slaby, linux-imx, linux-kernel

From: Stefan Agner <stefan.agner@toradex.com>

After overruns the FIFO pointers become misaligned. This
typically shows by characters still being stuck in the FIFO
despite the empty flag being asserted. After the first
assertion of the overrun flag the empty flag still seems to
indicate FIFO state correctly and all data can be read.
However, after another overrun assertion the FIFO seems to
be off by one such that the last received character is still
in the FIFO (despite the empty flag being asserted).

Flushing the receive FIFO reinitializes pointers. Hence it
is recommended to flush the FIFO after overruns, see also:
https://community.nxp.com/thread/321175

Hence, on assertion of the overrun flag read the remaining
data from the FIFO and flush buffers.

Signed-off-by: Stefan Agner <stefan.agner@toradex.com>
Acked-by: Max Krummenacher <max.krummenacher@toradex.com>
Cc: Stefan Agner <stefan@agner.ch>
Cc: Bhuvanchandra DV <bhuvanchandra.dv@toradex.com>
Cc: Chris Healy <cphealy@gmail.com>
Cc: Cory Tusar <cory.tusar@zii.aero>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Jiri Slaby <jslaby@suse.com>
Cc: linux-imx@nxp.com
Cc: linux-serial@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/tty/serial/fsl_lpuart.c | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
index 586b3513a6b0..edb1a9425fac 100644
--- a/drivers/tty/serial/fsl_lpuart.c
+++ b/drivers/tty/serial/fsl_lpuart.c
@@ -798,7 +798,7 @@ static irqreturn_t lpuart_txint(int irq, void *dev_id)
 static irqreturn_t lpuart_rxint(int irq, void *dev_id)
 {
 	struct lpuart_port *sport = dev_id;
-	unsigned int flg, ignored = 0;
+	unsigned int flg, ignored = 0, overrun = 0;
 	struct tty_port *port = &sport->port.state->port;
 	unsigned long flags;
 	unsigned char rx, sr;
@@ -825,7 +825,7 @@ static irqreturn_t lpuart_rxint(int irq, void *dev_id)
 				sport->port.icount.frame++;
 
 			if (sr & UARTSR1_OR)
-				sport->port.icount.overrun++;
+				overrun++;
 
 			if (sr & sport->port.ignore_status_mask) {
 				if (++ignored > 100)
@@ -852,6 +852,17 @@ static irqreturn_t lpuart_rxint(int irq, void *dev_id)
 	}
 
 out:
+	if (overrun) {
+		sport->port.icount.overrun += overrun;
+
+		/*
+		 * Overruns cause FIFO pointers to become missaligned.
+		 * Flushing the receive FIFO reinitializes the pointers.
+		 */
+		writeb(UARTCFIFO_RXFLUSH, sport->port.membase + UARTCFIFO);
+		writeb(UARTSFIFO_RXOF, sport->port.membase + UARTSFIFO);
+	}
+
 	spin_unlock_irqrestore(&sport->port.lock, flags);
 
 	tty_flip_buffer_push(port);
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 03/24] tty: serial: fsl_lpuart: Flush HW FIFOs in .flush_buffer
  2019-07-29 19:52 [PATCH 00/24] LPUART fixes and improvements Andrey Smirnov
  2019-07-29 19:52 ` [PATCH 01/24] tty: serial: fsl_lpuart: fix framing error handling when using DMA Andrey Smirnov
  2019-07-29 19:52 ` [PATCH 02/24] tty: serial: fsl_lpuart: flush receive FIFO after overruns Andrey Smirnov
@ 2019-07-29 19:52 ` Andrey Smirnov
  2019-07-29 19:52 ` [PATCH 04/24] tty: serial: fsl_lpuart: Simplify RX/TX IRQ handlers Andrey Smirnov
                   ` (21 subsequent siblings)
  24 siblings, 0 replies; 31+ messages in thread
From: Andrey Smirnov @ 2019-07-29 19:52 UTC (permalink / raw)
  To: linux-serial
  Cc: Andrey Smirnov, Fugang Duan, Stefan Agner, Bhuvanchandra DV,
	Chris Healy, Cory Tusar, Lucas Stach, Greg Kroah-Hartman,
	Jiri Slaby, linux-imx, linux-kernel

Switching baud rate might cause bogus data to appear in HW
FIFO. Add code to do a HW FIFO flush to .flush_buffer callback to
avoid that.

Signed-off-by: Fugang Duan <fugang.duan@nxp.com>
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
Cc: Stefan Agner <stefan@agner.ch>
Cc: Bhuvanchandra DV <bhuvanchandra.dv@toradex.com>
Cc: Chris Healy <cphealy@gmail.com>
Cc: Cory Tusar <cory.tusar@zii.aero>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Jiri Slaby <jslaby@suse.com>
Cc: linux-imx@nxp.com
Cc: linux-serial@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/tty/serial/fsl_lpuart.c | 23 +++++++++++++++++------
 1 file changed, 17 insertions(+), 6 deletions(-)

diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
index edb1a9425fac..56423ad02f0f 100644
--- a/drivers/tty/serial/fsl_lpuart.c
+++ b/drivers/tty/serial/fsl_lpuart.c
@@ -517,9 +517,16 @@ static int lpuart_dma_tx_request(struct uart_port *port)
 	return 0;
 }
 
+static bool lpuart_is_32(struct lpuart_port *sport)
+{
+	return sport->port.iotype == UPIO_MEM32 ||
+	       sport->port.iotype ==  UPIO_MEM32BE;
+}
+
 static void lpuart_flush_buffer(struct uart_port *port)
 {
 	struct lpuart_port *sport = container_of(port, struct lpuart_port, port);
+	u32 val;
 
 	if (sport->lpuart_dma_tx_use) {
 		if (sport->dma_tx_in_progress) {
@@ -529,6 +536,16 @@ static void lpuart_flush_buffer(struct uart_port *port)
 		}
 		dmaengine_terminate_all(sport->dma_tx_chan);
 	}
+
+	if (lpuart_is_32(sport)) {
+		val = lpuart32_read(&sport->port, UARTFIFO);
+		val |= UARTFIFO_TXFLUSH | UARTFIFO_RXFLUSH;
+		lpuart32_write(&sport->port, val, UARTFIFO);
+	} else {
+		val = readb(sport->port.membase + UARTPFIFO);
+		val |= UARTCFIFO_TXFLUSH | UARTCFIFO_RXFLUSH;
+		writeb(val, sport->port.membase + UARTCFIFO);
+	}
 }
 
 #if defined(CONFIG_CONSOLE_POLL)
@@ -753,12 +770,6 @@ static unsigned int lpuart32_tx_empty(struct uart_port *port)
 	return 0;
 }
 
-static bool lpuart_is_32(struct lpuart_port *sport)
-{
-	return sport->port.iotype == UPIO_MEM32 ||
-	       sport->port.iotype ==  UPIO_MEM32BE;
-}
-
 static irqreturn_t lpuart_txint(int irq, void *dev_id)
 {
 	struct lpuart_port *sport = dev_id;
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 04/24] tty: serial: fsl_lpuart: Simplify RX/TX IRQ handlers
  2019-07-29 19:52 [PATCH 00/24] LPUART fixes and improvements Andrey Smirnov
                   ` (2 preceding siblings ...)
  2019-07-29 19:52 ` [PATCH 03/24] tty: serial: fsl_lpuart: Flush HW FIFOs in .flush_buffer Andrey Smirnov
@ 2019-07-29 19:52 ` Andrey Smirnov
  2019-07-29 19:52 ` [PATCH 05/24] tty: serial: fsl_lpuart: Fix bogus indentation Andrey Smirnov
                   ` (20 subsequent siblings)
  24 siblings, 0 replies; 31+ messages in thread
From: Andrey Smirnov @ 2019-07-29 19:52 UTC (permalink / raw)
  To: linux-serial
  Cc: Andrey Smirnov, Stefan Agner, Bhuvanchandra DV, Chris Healy,
	Cory Tusar, Lucas Stach, Greg Kroah-Hartman, Jiri Slaby,
	linux-imx, linux-kernel

It appears that lpuart_rxint, lpuart_txint and lpuart32_rxint were
modelled after identical function found in UART driver for
i.MX. However, while said functions are used as individual IRQ
handlers in i.MX driver (in case of i.MX1), it is not the case for
LPUART. Given that, there's no need for us to restrict the prototype
of the handler to irqreturn_t foo(int, void *) and we can drop all of
uneened boilerplate code by changing it void foo(struct lpuart_port *).

Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
Cc: Stefan Agner <stefan@agner.ch>
Cc: Bhuvanchandra DV <bhuvanchandra.dv@toradex.com>
Cc: Chris Healy <cphealy@gmail.com>
Cc: Cory Tusar <cory.tusar@zii.aero>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Jiri Slaby <jslaby@suse.com>
Cc: linux-imx@nxp.com
Cc: linux-serial@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/tty/serial/fsl_lpuart.c | 20 +++++++-------------
 1 file changed, 7 insertions(+), 13 deletions(-)

diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
index 56423ad02f0f..3e38970a444e 100644
--- a/drivers/tty/serial/fsl_lpuart.c
+++ b/drivers/tty/serial/fsl_lpuart.c
@@ -770,9 +770,8 @@ static unsigned int lpuart32_tx_empty(struct uart_port *port)
 	return 0;
 }
 
-static irqreturn_t lpuart_txint(int irq, void *dev_id)
+static void lpuart_txint(struct lpuart_port *sport)
 {
-	struct lpuart_port *sport = dev_id;
 	struct circ_buf *xmit = &sport->port.state->xmit;
 	unsigned long flags;
 
@@ -803,12 +802,10 @@ static irqreturn_t lpuart_txint(int irq, void *dev_id)
 
 out:
 	spin_unlock_irqrestore(&sport->port.lock, flags);
-	return IRQ_HANDLED;
 }
 
-static irqreturn_t lpuart_rxint(int irq, void *dev_id)
+static void lpuart_rxint(struct lpuart_port *sport)
 {
-	struct lpuart_port *sport = dev_id;
 	unsigned int flg, ignored = 0, overrun = 0;
 	struct tty_port *port = &sport->port.state->port;
 	unsigned long flags;
@@ -877,12 +874,10 @@ static irqreturn_t lpuart_rxint(int irq, void *dev_id)
 	spin_unlock_irqrestore(&sport->port.lock, flags);
 
 	tty_flip_buffer_push(port);
-	return IRQ_HANDLED;
 }
 
-static irqreturn_t lpuart32_rxint(int irq, void *dev_id)
+static void lpuart32_rxint(struct lpuart_port *sport)
 {
-	struct lpuart_port *sport = dev_id;
 	unsigned int flg, ignored = 0;
 	struct tty_port *port = &sport->port.state->port;
 	unsigned long flags;
@@ -941,7 +936,6 @@ static irqreturn_t lpuart32_rxint(int irq, void *dev_id)
 	spin_unlock_irqrestore(&sport->port.lock, flags);
 
 	tty_flip_buffer_push(port);
-	return IRQ_HANDLED;
 }
 
 static irqreturn_t lpuart_int(int irq, void *dev_id)
@@ -952,10 +946,10 @@ static irqreturn_t lpuart_int(int irq, void *dev_id)
 	sts = readb(sport->port.membase + UARTSR1);
 
 	if (sts & UARTSR1_RDRF)
-		lpuart_rxint(irq, dev_id);
+		lpuart_rxint(sport);
 
 	if (sts & UARTSR1_TDRE)
-		lpuart_txint(irq, dev_id);
+		lpuart_txint(sport);
 
 	return IRQ_HANDLED;
 }
@@ -970,10 +964,10 @@ static irqreturn_t lpuart32_int(int irq, void *dev_id)
 	rxcount = rxcount >> UARTWATER_RXCNT_OFF;
 
 	if ((sts & UARTSTAT_RDRF || rxcount > 0) && !sport->lpuart_dma_rx_use)
-		lpuart32_rxint(irq, dev_id);
+		lpuart32_rxint(sport);
 
 	if ((sts & UARTSTAT_TDRE) && !sport->lpuart_dma_tx_use)
-		lpuart_txint(irq, dev_id);
+		lpuart_txint(sport);
 
 	lpuart32_write(&sport->port, sts, UARTSTAT);
 	return IRQ_HANDLED;
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 05/24] tty: serial: fsl_lpuart: Fix bogus indentation
  2019-07-29 19:52 [PATCH 00/24] LPUART fixes and improvements Andrey Smirnov
                   ` (3 preceding siblings ...)
  2019-07-29 19:52 ` [PATCH 04/24] tty: serial: fsl_lpuart: Simplify RX/TX IRQ handlers Andrey Smirnov
@ 2019-07-29 19:52 ` Andrey Smirnov
  2019-07-29 19:52 ` [PATCH 06/24] tty: serial: fsl_lpuart: Drop unnecessary sg_set_buf() call Andrey Smirnov
                   ` (19 subsequent siblings)
  24 siblings, 0 replies; 31+ messages in thread
From: Andrey Smirnov @ 2019-07-29 19:52 UTC (permalink / raw)
  To: linux-serial
  Cc: Andrey Smirnov, Stefan Agner, Bhuvanchandra DV, Chris Healy,
	Cory Tusar, Lucas Stach, Greg Kroah-Hartman, Jiri Slaby,
	linux-imx, linux-kernel

Fix bogus indentation in rx_dma_timer_init().

Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
Cc: Stefan Agner <stefan@agner.ch>
Cc: Bhuvanchandra DV <bhuvanchandra.dv@toradex.com>
Cc: Chris Healy <cphealy@gmail.com>
Cc: Cory Tusar <cory.tusar@zii.aero>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Jiri Slaby <jslaby@suse.com>
Cc: linux-imx@nxp.com
Cc: linux-serial@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/tty/serial/fsl_lpuart.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
index 3e38970a444e..1b3f2a87e558 100644
--- a/drivers/tty/serial/fsl_lpuart.c
+++ b/drivers/tty/serial/fsl_lpuart.c
@@ -1409,9 +1409,9 @@ static void lpuart32_setup_watermark(struct lpuart_port *sport)
 
 static void rx_dma_timer_init(struct lpuart_port *sport)
 {
-		timer_setup(&sport->lpuart_timer, lpuart_timer_func, 0);
-		sport->lpuart_timer.expires = jiffies + sport->dma_rx_timeout;
-		add_timer(&sport->lpuart_timer);
+	timer_setup(&sport->lpuart_timer, lpuart_timer_func, 0);
+	sport->lpuart_timer.expires = jiffies + sport->dma_rx_timeout;
+	add_timer(&sport->lpuart_timer);
 }
 
 static int lpuart_startup(struct uart_port *port)
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 06/24] tty: serial: fsl_lpuart: Drop unnecessary sg_set_buf() call
  2019-07-29 19:52 [PATCH 00/24] LPUART fixes and improvements Andrey Smirnov
                   ` (4 preceding siblings ...)
  2019-07-29 19:52 ` [PATCH 05/24] tty: serial: fsl_lpuart: Fix bogus indentation Andrey Smirnov
@ 2019-07-29 19:52 ` Andrey Smirnov
  2019-07-30 15:51   ` Greg Kroah-Hartman
  2019-07-29 19:52 ` [PATCH 07/24] tty: serial: fsl_lpuart: Drop unnecessary uart_write_wakeup() Andrey Smirnov
                   ` (18 subsequent siblings)
  24 siblings, 1 reply; 31+ messages in thread
From: Andrey Smirnov @ 2019-07-29 19:52 UTC (permalink / raw)
  To: linux-serial
  Cc: Andrey Smirnov, Stefan Agner, Bhuvanchandra DV, Chris Healy,
	Cory Tusar, Lucas Stach, Greg Kroah-Hartman, Jiri Slaby,
	linux-imx, linux-kernel

Sg_init_one() will already call sg_set_buf(), so another explicit call
right after it is unnecessary. Drop it.

Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
Cc: Stefan Agner <stefan@agner.ch>
Cc: Bhuvanchandra DV <bhuvanchandra.dv@toradex.com>
Cc: Chris Healy <cphealy@gmail.com>
Cc: Cory Tusar <cory.tusar@zii.aero>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Jiri Slaby <jslaby@suse.com>
Cc: linux-imx@nxp.com
Cc: linux-serial@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/tty/serial/fsl_lpuart.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
index 1b3f2a87e558..b600f591c8c2 100644
--- a/drivers/tty/serial/fsl_lpuart.c
+++ b/drivers/tty/serial/fsl_lpuart.c
@@ -1144,7 +1144,6 @@ static inline int lpuart_start_rx_dma(struct lpuart_port *sport)
 		return -ENOMEM;
 
 	sg_init_one(&sport->rx_sgl, ring->buf, sport->rx_dma_rng_buf_len);
-	sg_set_buf(&sport->rx_sgl, ring->buf, sport->rx_dma_rng_buf_len);
 	nent = dma_map_sg(sport->port.dev, &sport->rx_sgl, 1, DMA_FROM_DEVICE);
 
 	if (!nent) {
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 07/24] tty: serial: fsl_lpuart: Drop unnecessary uart_write_wakeup()
  2019-07-29 19:52 [PATCH 00/24] LPUART fixes and improvements Andrey Smirnov
                   ` (5 preceding siblings ...)
  2019-07-29 19:52 ` [PATCH 06/24] tty: serial: fsl_lpuart: Drop unnecessary sg_set_buf() call Andrey Smirnov
@ 2019-07-29 19:52 ` Andrey Smirnov
  2019-07-29 19:52 ` [PATCH 08/24] tty: serial: fsl_lpuart: Fix issue in software flow control Andrey Smirnov
                   ` (17 subsequent siblings)
  24 siblings, 0 replies; 31+ messages in thread
From: Andrey Smirnov @ 2019-07-29 19:52 UTC (permalink / raw)
  To: linux-serial
  Cc: Andrey Smirnov, Stefan Agner, Bhuvanchandra DV, Chris Healy,
	Cory Tusar, Lucas Stach, Greg Kroah-Hartman, Jiri Slaby,
	linux-imx, linux-kernel

Uart_write_wakeup() will already be called as a part of
lpuart*_transmit_buffer() call, so there doesn't seem to be a reason
to call it again right after.

It also appears that second uart_write_wakeup() might potentially
cause unwanted write wakeup when transmitting an x_char. See commit
5e42e9a30cda ("serial: imx: Fix x_char handling and tx flow control")
where this problem was fixed in a very similarly structured i.MX UART
driver.

Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
Cc: Stefan Agner <stefan@agner.ch>
Cc: Bhuvanchandra DV <bhuvanchandra.dv@toradex.com>
Cc: Chris Healy <cphealy@gmail.com>
Cc: Cory Tusar <cory.tusar@zii.aero>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Jiri Slaby <jslaby@suse.com>
Cc: linux-imx@nxp.com
Cc: linux-serial@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/tty/serial/fsl_lpuart.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
index b600f591c8c2..840dcbb27e5a 100644
--- a/drivers/tty/serial/fsl_lpuart.c
+++ b/drivers/tty/serial/fsl_lpuart.c
@@ -797,9 +797,6 @@ static void lpuart_txint(struct lpuart_port *sport)
 	else
 		lpuart_transmit_buffer(sport);
 
-	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
-		uart_write_wakeup(&sport->port);
-
 out:
 	spin_unlock_irqrestore(&sport->port.lock, flags);
 }
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 08/24] tty: serial: fsl_lpuart: Fix issue in software flow control
  2019-07-29 19:52 [PATCH 00/24] LPUART fixes and improvements Andrey Smirnov
                   ` (6 preceding siblings ...)
  2019-07-29 19:52 ` [PATCH 07/24] tty: serial: fsl_lpuart: Drop unnecessary uart_write_wakeup() Andrey Smirnov
@ 2019-07-29 19:52 ` Andrey Smirnov
  2019-07-29 19:52 ` [PATCH 09/24] tty: serial: fls_lpuart: Split shared TX IRQ handler into two Andrey Smirnov
                   ` (16 subsequent siblings)
  24 siblings, 0 replies; 31+ messages in thread
From: Andrey Smirnov @ 2019-07-29 19:52 UTC (permalink / raw)
  To: linux-serial
  Cc: Andrey Smirnov, Stefan Agner, Bhuvanchandra DV, Chris Healy,
	Cory Tusar, Lucas Stach, Greg Kroah-Hartman, Jiri Slaby,
	linux-imx, linux-kernel

Although I haven't observed this bug in practice, it seems that the
code for handling x_char of LPUART is pretty much identical to that of
i.MX. So the fix found in commit 7e2fb5aa8d81 ("serial: imx: Fix issue
in software flow control"):

    serial: imx: Fix issue in software flow control

    After send out x_char in UART driver, x_char needs to be cleared
    by UART driver itself, otherwise data in TXFIFO can no longer be
    sent out.
    Also tx counter needs to be increased to keep track of correct
    number of transmitted data.

    Signed-off-by: Jiada Wang <jiada_wang@mentor.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

should apply here as well.

Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
Cc: Stefan Agner <stefan@agner.ch>
Cc: Bhuvanchandra DV <bhuvanchandra.dv@toradex.com>
Cc: Chris Healy <cphealy@gmail.com>
Cc: Cory Tusar <cory.tusar@zii.aero>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Jiri Slaby <jslaby@suse.com>
Cc: linux-imx@nxp.com
Cc: linux-serial@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/tty/serial/fsl_lpuart.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
index 840dcbb27e5a..1fe9b1b29a46 100644
--- a/drivers/tty/serial/fsl_lpuart.c
+++ b/drivers/tty/serial/fsl_lpuart.c
@@ -781,6 +781,8 @@ static void lpuart_txint(struct lpuart_port *sport)
 			lpuart32_write(&sport->port, sport->port.x_char, UARTDATA);
 		else
 			writeb(sport->port.x_char, sport->port.membase + UARTDR);
+		sport->port.icount.tx++;
+		sport->port.x_char = 0;
 		goto out;
 	}
 
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 09/24] tty: serial: fls_lpuart: Split shared TX IRQ handler into two
  2019-07-29 19:52 [PATCH 00/24] LPUART fixes and improvements Andrey Smirnov
                   ` (7 preceding siblings ...)
  2019-07-29 19:52 ` [PATCH 08/24] tty: serial: fsl_lpuart: Fix issue in software flow control Andrey Smirnov
@ 2019-07-29 19:52 ` Andrey Smirnov
  2019-07-29 19:52 ` [PATCH 10/24] tty: serial: fsl_lpuart: Drop no-op bit opearation Andrey Smirnov
                   ` (15 subsequent siblings)
  24 siblings, 0 replies; 31+ messages in thread
From: Andrey Smirnov @ 2019-07-29 19:52 UTC (permalink / raw)
  To: linux-serial
  Cc: Andrey Smirnov, Stefan Agner, Bhuvanchandra DV, Chris Healy,
	Cory Tusar, Lucas Stach, Greg Kroah-Hartman, Jiri Slaby,
	linux-imx, linux-kernel

While sharing code for Tx interrupt handler between 8 and 32 bit
variant of the peripheral saves a bit of code duplication it also adds
quite a number of lpuart_is_32() checks which makes it harder to
understand. Move shared bits back into corresponding
lpuart*_transmit_buffer functions, split lpuart_txint into
lpuart_txint and lpuart32_txint so we can drop all extra
lpuart_is_32() check and make the code flow more linear.

Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
Cc: Stefan Agner <stefan@agner.ch>
Cc: Bhuvanchandra DV <bhuvanchandra.dv@toradex.com>
Cc: Chris Healy <cphealy@gmail.com>
Cc: Cory Tusar <cory.tusar@zii.aero>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Jiri Slaby <jslaby@suse.com>
Cc: linux-imx@nxp.com
Cc: linux-serial@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/tty/serial/fsl_lpuart.c | 61 +++++++++++++++++++--------------
 1 file changed, 35 insertions(+), 26 deletions(-)

diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
index 1fe9b1b29a46..f87ea889ff86 100644
--- a/drivers/tty/serial/fsl_lpuart.c
+++ b/drivers/tty/serial/fsl_lpuart.c
@@ -662,6 +662,18 @@ static inline void lpuart_transmit_buffer(struct lpuart_port *sport)
 {
 	struct circ_buf *xmit = &sport->port.state->xmit;
 
+	if (sport->port.x_char) {
+		writeb(sport->port.x_char, sport->port.membase + UARTDR);
+		sport->port.icount.tx++;
+		sport->port.x_char = 0;
+		return;
+	}
+
+	if (uart_circ_empty(xmit) || uart_tx_stopped(&sport->port)) {
+		lpuart_stop_tx(&sport->port);
+		return;
+	}
+
 	while (!uart_circ_empty(xmit) &&
 		(readb(sport->port.membase + UARTTCFIFO) < sport->txfifo_size)) {
 		writeb(xmit->buf[xmit->tail], sport->port.membase + UARTDR);
@@ -681,6 +693,18 @@ static inline void lpuart32_transmit_buffer(struct lpuart_port *sport)
 	struct circ_buf *xmit = &sport->port.state->xmit;
 	unsigned long txcnt;
 
+	if (sport->port.x_char) {
+		lpuart32_write(&sport->port, sport->port.x_char, UARTDATA);
+		sport->port.icount.tx++;
+		sport->port.x_char = 0;
+		return;
+	}
+
+	if (uart_circ_empty(xmit) || uart_tx_stopped(&sport->port)) {
+		lpuart32_stop_tx(&sport->port);
+		return;
+	}
+
 	txcnt = lpuart32_read(&sport->port, UARTWATER);
 	txcnt = txcnt >> UARTWATER_TXCNT_OFF;
 	txcnt &= UARTWATER_COUNT_MASK;
@@ -772,34 +796,10 @@ static unsigned int lpuart32_tx_empty(struct uart_port *port)
 
 static void lpuart_txint(struct lpuart_port *sport)
 {
-	struct circ_buf *xmit = &sport->port.state->xmit;
 	unsigned long flags;
 
 	spin_lock_irqsave(&sport->port.lock, flags);
-	if (sport->port.x_char) {
-		if (lpuart_is_32(sport))
-			lpuart32_write(&sport->port, sport->port.x_char, UARTDATA);
-		else
-			writeb(sport->port.x_char, sport->port.membase + UARTDR);
-		sport->port.icount.tx++;
-		sport->port.x_char = 0;
-		goto out;
-	}
-
-	if (uart_circ_empty(xmit) || uart_tx_stopped(&sport->port)) {
-		if (lpuart_is_32(sport))
-			lpuart32_stop_tx(&sport->port);
-		else
-			lpuart_stop_tx(&sport->port);
-		goto out;
-	}
-
-	if (lpuart_is_32(sport))
-		lpuart32_transmit_buffer(sport);
-	else
-		lpuart_transmit_buffer(sport);
-
-out:
+	lpuart_transmit_buffer(sport);
 	spin_unlock_irqrestore(&sport->port.lock, flags);
 }
 
@@ -875,6 +875,15 @@ static void lpuart_rxint(struct lpuart_port *sport)
 	tty_flip_buffer_push(port);
 }
 
+static void lpuart32_txint(struct lpuart_port *sport)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&sport->port.lock, flags);
+	lpuart32_transmit_buffer(sport);
+	spin_unlock_irqrestore(&sport->port.lock, flags);
+}
+
 static void lpuart32_rxint(struct lpuart_port *sport)
 {
 	unsigned int flg, ignored = 0;
@@ -966,7 +975,7 @@ static irqreturn_t lpuart32_int(int irq, void *dev_id)
 		lpuart32_rxint(sport);
 
 	if ((sts & UARTSTAT_TDRE) && !sport->lpuart_dma_tx_use)
-		lpuart_txint(sport);
+		lpuart32_txint(sport);
 
 	lpuart32_write(&sport->port, sts, UARTSTAT);
 	return IRQ_HANDLED;
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 10/24] tty: serial: fsl_lpuart: Drop no-op bit opearation
  2019-07-29 19:52 [PATCH 00/24] LPUART fixes and improvements Andrey Smirnov
                   ` (8 preceding siblings ...)
  2019-07-29 19:52 ` [PATCH 09/24] tty: serial: fls_lpuart: Split shared TX IRQ handler into two Andrey Smirnov
@ 2019-07-29 19:52 ` Andrey Smirnov
  2019-07-29 19:52 ` [PATCH 11/24] tty: serial: fsl_lpuart: Drop unnecessary extra parenthesis Andrey Smirnov
                   ` (14 subsequent siblings)
  24 siblings, 0 replies; 31+ messages in thread
From: Andrey Smirnov @ 2019-07-29 19:52 UTC (permalink / raw)
  To: linux-serial
  Cc: Andrey Smirnov, Stefan Agner, Bhuvanchandra DV, Chris Healy,
	Cory Tusar, Lucas Stach, Greg Kroah-Hartman, Jiri Slaby,
	linux-imx, linux-kernel

The check for termios->c_cflag & CRTSCTS ensure that if we reach else
branch, CRTSCTS in termios->c_cflag is already going to be
cleard. Doing so explicitly there is not necessary. Drop it.

Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
Cc: Stefan Agner <stefan@agner.ch>
Cc: Bhuvanchandra DV <bhuvanchandra.dv@toradex.com>
Cc: Chris Healy <cphealy@gmail.com>
Cc: Cory Tusar <cory.tusar@zii.aero>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Jiri Slaby <jslaby@suse.com>
Cc: linux-imx@nxp.com
Cc: linux-serial@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/tty/serial/fsl_lpuart.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
index f87ea889ff86..5181ba5d8f71 100644
--- a/drivers/tty/serial/fsl_lpuart.c
+++ b/drivers/tty/serial/fsl_lpuart.c
@@ -1651,12 +1651,10 @@ lpuart_set_termios(struct uart_port *port, struct ktermios *termios,
 	if (sport->port.rs485.flags & SER_RS485_ENABLED)
 		termios->c_cflag &= ~CRTSCTS;
 
-	if (termios->c_cflag & CRTSCTS) {
+	if (termios->c_cflag & CRTSCTS)
 		modem |= (UARTMODEM_RXRTSE | UARTMODEM_TXCTSE);
-	} else {
-		termios->c_cflag &= ~CRTSCTS;
+	else
 		modem &= ~(UARTMODEM_RXRTSE | UARTMODEM_TXCTSE);
-	}
 
 	if (termios->c_cflag & CSTOPB)
 		termios->c_cflag &= ~CSTOPB;
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 11/24] tty: serial: fsl_lpuart: Drop unnecessary extra parenthesis
  2019-07-29 19:52 [PATCH 00/24] LPUART fixes and improvements Andrey Smirnov
                   ` (9 preceding siblings ...)
  2019-07-29 19:52 ` [PATCH 10/24] tty: serial: fsl_lpuart: Drop no-op bit opearation Andrey Smirnov
@ 2019-07-29 19:52 ` Andrey Smirnov
  2019-07-29 19:52 ` [PATCH 12/24] tty: serial: fsl_lpuart: Clear CSTOPB unconditionally Andrey Smirnov
                   ` (13 subsequent siblings)
  24 siblings, 0 replies; 31+ messages in thread
From: Andrey Smirnov @ 2019-07-29 19:52 UTC (permalink / raw)
  To: linux-serial
  Cc: Andrey Smirnov, Stefan Agner, Bhuvanchandra DV, Chris Healy,
	Cory Tusar, Lucas Stach, Greg Kroah-Hartman, Jiri Slaby,
	linux-imx, linux-kernel

Drop unnecessary extra parenthesis in the driver.

Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
Cc: Stefan Agner <stefan@agner.ch>
Cc: Bhuvanchandra DV <bhuvanchandra.dv@toradex.com>
Cc: Chris Healy <cphealy@gmail.com>
Cc: Cory Tusar <cory.tusar@zii.aero>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Jiri Slaby <jslaby@suse.com>
Cc: linux-imx@nxp.com
Cc: linux-serial@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/tty/serial/fsl_lpuart.c | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
index 5181ba5d8f71..5a1e19733353 100644
--- a/drivers/tty/serial/fsl_lpuart.c
+++ b/drivers/tty/serial/fsl_lpuart.c
@@ -1443,7 +1443,7 @@ static int lpuart_startup(struct uart_port *port)
 	lpuart_setup_watermark(sport);
 
 	temp = readb(sport->port.membase + UARTCR2);
-	temp |= (UARTCR2_RIE | UARTCR2_TIE | UARTCR2_RE | UARTCR2_TE);
+	temp |= UARTCR2_RIE | UARTCR2_TIE | UARTCR2_RE | UARTCR2_TE;
 	writeb(temp, sport->port.membase + UARTCR2);
 
 	if (sport->dma_rx_chan && !lpuart_start_rx_dma(sport)) {
@@ -1652,7 +1652,7 @@ lpuart_set_termios(struct uart_port *port, struct ktermios *termios,
 		termios->c_cflag &= ~CRTSCTS;
 
 	if (termios->c_cflag & CRTSCTS)
-		modem |= (UARTMODEM_RXRTSE | UARTMODEM_TXCTSE);
+		modem |= UARTMODEM_RXRTSE | UARTMODEM_TXCTSE;
 	else
 		modem &= ~(UARTMODEM_RXRTSE | UARTMODEM_TXCTSE);
 
@@ -1663,7 +1663,7 @@ lpuart_set_termios(struct uart_port *port, struct ktermios *termios,
 	if ((termios->c_cflag & CSIZE) == CS7)
 		termios->c_cflag |= PARENB;
 
-	if ((termios->c_cflag & PARENB)) {
+	if (termios->c_cflag & PARENB) {
 		if (termios->c_cflag & CMSPAR) {
 			cr1 &= ~UARTCR1_PE;
 			if (termios->c_cflag & PARODD)
@@ -1702,7 +1702,7 @@ lpuart_set_termios(struct uart_port *port, struct ktermios *termios,
 
 	sport->port.read_status_mask = 0;
 	if (termios->c_iflag & INPCK)
-		sport->port.read_status_mask |=	(UARTSR1_FE | UARTSR1_PE);
+		sport->port.read_status_mask |= UARTSR1_FE | UARTSR1_PE;
 	if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK))
 		sport->port.read_status_mask |= UARTSR1_FE;
 
@@ -1816,7 +1816,7 @@ lpuart32_serial_setbrg(struct lpuart_port *sport, unsigned int baudrate)
 		tmp |= UARTBAUD_BOTHEDGE;
 
 	tmp &= ~(UARTBAUD_OSR_MASK << UARTBAUD_OSR_SHIFT);
-	tmp |= (((osr-1) & UARTBAUD_OSR_MASK) << UARTBAUD_OSR_SHIFT);
+	tmp |= ((osr-1) & UARTBAUD_OSR_MASK) << UARTBAUD_OSR_SHIFT;
 
 	tmp &= ~UARTBAUD_SBR_MASK;
 	tmp |= sbr & UARTBAUD_SBR_MASK;
@@ -1869,7 +1869,7 @@ lpuart32_set_termios(struct uart_port *port, struct ktermios *termios,
 	}
 
 	if (termios->c_cflag & CRTSCTS) {
-		modem |= (UARTMODEM_RXRTSE | UARTMODEM_TXCTSE);
+		modem |= UARTMODEM_RXRTSE | UARTMODEM_TXCTSE;
 	} else {
 		termios->c_cflag &= ~CRTSCTS;
 		modem &= ~(UARTMODEM_RXRTSE | UARTMODEM_TXCTSE);
@@ -1918,7 +1918,7 @@ lpuart32_set_termios(struct uart_port *port, struct ktermios *termios,
 
 	sport->port.read_status_mask = 0;
 	if (termios->c_iflag & INPCK)
-		sport->port.read_status_mask |=	(UARTSTAT_FE | UARTSTAT_PE);
+		sport->port.read_status_mask |= UARTSTAT_FE | UARTSTAT_PE;
 	if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK))
 		sport->port.read_status_mask |= UARTSTAT_FE;
 
@@ -2085,7 +2085,7 @@ lpuart_console_write(struct console *co, const char *s, unsigned int count)
 
 	/* first save CR2 and then disable interrupts */
 	cr2 = old_cr2 = readb(sport->port.membase + UARTCR2);
-	cr2 |= (UARTCR2_TE |  UARTCR2_RE);
+	cr2 |= UARTCR2_TE | UARTCR2_RE;
 	cr2 &= ~(UARTCR2_TIE | UARTCR2_TCIE | UARTCR2_RIE);
 	writeb(cr2, sport->port.membase + UARTCR2);
 
@@ -2116,7 +2116,7 @@ lpuart32_console_write(struct console *co, const char *s, unsigned int count)
 
 	/* first save CR2 and then disable interrupts */
 	cr = old_cr = lpuart32_read(&sport->port, UARTCTRL);
-	cr |= (UARTCTRL_TE |  UARTCTRL_RE);
+	cr |= UARTCTRL_TE | UARTCTRL_RE;
 	cr &= ~(UARTCTRL_TIE | UARTCTRL_TCIE | UARTCTRL_RIE);
 	lpuart32_write(&sport->port, cr, UARTCTRL);
 
@@ -2574,7 +2574,7 @@ static int lpuart_resume(struct device *dev)
 	} else {
 		lpuart_setup_watermark(sport);
 		temp = readb(sport->port.membase + UARTCR2);
-		temp |= (UARTCR2_RIE | UARTCR2_TIE | UARTCR2_RE | UARTCR2_TE);
+		temp |= UARTCR2_RIE | UARTCR2_TIE | UARTCR2_RE | UARTCR2_TE;
 		writeb(temp, sport->port.membase + UARTCR2);
 	}
 
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 12/24] tty: serial: fsl_lpuart: Clear CSTOPB unconditionally
  2019-07-29 19:52 [PATCH 00/24] LPUART fixes and improvements Andrey Smirnov
                   ` (10 preceding siblings ...)
  2019-07-29 19:52 ` [PATCH 11/24] tty: serial: fsl_lpuart: Drop unnecessary extra parenthesis Andrey Smirnov
@ 2019-07-29 19:52 ` Andrey Smirnov
  2019-07-29 19:52 ` [PATCH 13/24] tty: serial: fsl_lpuart: Use appropriate lpuart32_* I/O funcs Andrey Smirnov
                   ` (12 subsequent siblings)
  24 siblings, 0 replies; 31+ messages in thread
From: Andrey Smirnov @ 2019-07-29 19:52 UTC (permalink / raw)
  To: linux-serial
  Cc: Andrey Smirnov, Stefan Agner, Bhuvanchandra DV, Chris Healy,
	Cory Tusar, Lucas Stach, Greg Kroah-Hartman, Jiri Slaby,
	linux-imx, linux-kernel

Clearing CSTOPB bit if it is set is functionally equivalent to jsut
clearing it unconditionally. Drop unnecessary check.

Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
Cc: Stefan Agner <stefan@agner.ch>
Cc: Bhuvanchandra DV <bhuvanchandra.dv@toradex.com>
Cc: Chris Healy <cphealy@gmail.com>
Cc: Cory Tusar <cory.tusar@zii.aero>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Jiri Slaby <jslaby@suse.com>
Cc: linux-imx@nxp.com
Cc: linux-serial@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/tty/serial/fsl_lpuart.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
index 5a1e19733353..10f1af51c58d 100644
--- a/drivers/tty/serial/fsl_lpuart.c
+++ b/drivers/tty/serial/fsl_lpuart.c
@@ -1656,8 +1656,7 @@ lpuart_set_termios(struct uart_port *port, struct ktermios *termios,
 	else
 		modem &= ~(UARTMODEM_RXRTSE | UARTMODEM_TXCTSE);
 
-	if (termios->c_cflag & CSTOPB)
-		termios->c_cflag &= ~CSTOPB;
+	termios->c_cflag &= ~CSTOPB;
 
 	/* parity must be enabled when CS7 to match 8-bits format */
 	if ((termios->c_cflag & CSIZE) == CS7)
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 13/24] tty: serial: fsl_lpuart: Use appropriate lpuart32_* I/O funcs
  2019-07-29 19:52 [PATCH 00/24] LPUART fixes and improvements Andrey Smirnov
                   ` (11 preceding siblings ...)
  2019-07-29 19:52 ` [PATCH 12/24] tty: serial: fsl_lpuart: Clear CSTOPB unconditionally Andrey Smirnov
@ 2019-07-29 19:52 ` Andrey Smirnov
  2019-07-29 19:52 ` [PATCH 14/24] tty: serial: fsl_lpuart: Introduce lpuart_wait_bit_set() Andrey Smirnov
                   ` (11 subsequent siblings)
  24 siblings, 0 replies; 31+ messages in thread
From: Andrey Smirnov @ 2019-07-29 19:52 UTC (permalink / raw)
  To: linux-serial
  Cc: Andrey Smirnov, Stefan Agner, Bhuvanchandra DV, Chris Healy,
	Cory Tusar, Lucas Stach, Greg Kroah-Hartman, Jiri Slaby,
	linux-imx, linux-kernel

When dealing with 32-bit variant of LPUART IP block appropriate I/O
helpers have to be used to properly deal with endianness
differences. Change all of the offending code to do that.

Fixes: a5fa2660d787 ("tty/serial/fsl_lpuart: Add CONSOLE_POLL support
for lpuart32.")
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
Cc: Stefan Agner <stefan@agner.ch>
Cc: Bhuvanchandra DV <bhuvanchandra.dv@toradex.com>
Cc: Chris Healy <cphealy@gmail.com>
Cc: Cory Tusar <cory.tusar@zii.aero>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Jiri Slaby <jslaby@suse.com>
Cc: linux-imx@nxp.com
Cc: linux-serial@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/tty/serial/fsl_lpuart.c | 28 ++++++++++++++--------------
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
index 10f1af51c58d..50a707c88a16 100644
--- a/drivers/tty/serial/fsl_lpuart.c
+++ b/drivers/tty/serial/fsl_lpuart.c
@@ -616,26 +616,26 @@ static int lpuart32_poll_init(struct uart_port *port)
 	spin_lock_irqsave(&sport->port.lock, flags);
 
 	/* Disable Rx & Tx */
-	writel(0, sport->port.membase + UARTCTRL);
+	lpuart32_write(&sport->port, UARTCTRL, 0);
 
-	temp = readl(sport->port.membase + UARTFIFO);
+	temp = lpuart32_read(&sport->port, UARTFIFO);
 
 	/* Enable Rx and Tx FIFO */
-	writel(temp | UARTFIFO_RXFE | UARTFIFO_TXFE,
-		   sport->port.membase + UARTFIFO);
+	lpuart32_write(&sport->port, UARTFIFO,
+		       temp | UARTFIFO_RXFE | UARTFIFO_TXFE);
 
 	/* flush Tx and Rx FIFO */
-	writel(UARTFIFO_TXFLUSH | UARTFIFO_RXFLUSH,
-			sport->port.membase + UARTFIFO);
+	lpuart32_write(&sport->port, UARTFIFO,
+		       UARTFIFO_TXFLUSH | UARTFIFO_RXFLUSH);
 
 	/* explicitly clear RDRF */
-	if (readl(sport->port.membase + UARTSTAT) & UARTSTAT_RDRF) {
-		readl(sport->port.membase + UARTDATA);
-		writel(UARTFIFO_RXUF, sport->port.membase + UARTFIFO);
+	if (lpuart32_read(&sport->port, UARTSTAT) & UARTSTAT_RDRF) {
+		lpuart32_read(&sport->port, UARTDATA);
+		lpuart32_write(&sport->port, UARTFIFO, UARTFIFO_RXUF);
 	}
 
 	/* Enable Rx and Tx */
-	writel(UARTCTRL_RE | UARTCTRL_TE, sport->port.membase + UARTCTRL);
+	lpuart32_write(&sport->port, UARTCTRL, UARTCTRL_RE | UARTCTRL_TE);
 	spin_unlock_irqrestore(&sport->port.lock, flags);
 
 	return 0;
@@ -643,18 +643,18 @@ static int lpuart32_poll_init(struct uart_port *port)
 
 static void lpuart32_poll_put_char(struct uart_port *port, unsigned char c)
 {
-	while (!(readl(port->membase + UARTSTAT) & UARTSTAT_TDRE))
+	while (!(lpuart32_read(port, UARTSTAT) & UARTSTAT_TDRE))
 		barrier();
 
-	writel(c, port->membase + UARTDATA);
+	lpuart32_write(port, UARTDATA, c);
 }
 
 static int lpuart32_poll_get_char(struct uart_port *port)
 {
-	if (!(readl(port->membase + UARTSTAT) & UARTSTAT_RDRF))
+	if (!(lpuart32_read(port, UARTSTAT) & UARTSTAT_RDRF))
 		return NO_POLL_CHAR;
 
-	return readl(port->membase + UARTDATA);
+	return lpuart32_read(port, UARTDATA);
 }
 #endif
 
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 14/24] tty: serial: fsl_lpuart: Introduce lpuart_wait_bit_set()
  2019-07-29 19:52 [PATCH 00/24] LPUART fixes and improvements Andrey Smirnov
                   ` (12 preceding siblings ...)
  2019-07-29 19:52 ` [PATCH 13/24] tty: serial: fsl_lpuart: Use appropriate lpuart32_* I/O funcs Andrey Smirnov
@ 2019-07-29 19:52 ` Andrey Smirnov
  2019-07-29 19:52 ` [PATCH 15/24] tty: serial: fsl_lpuart: Use cpu_relax() instead of barrier() Andrey Smirnov
                   ` (10 subsequent siblings)
  24 siblings, 0 replies; 31+ messages in thread
From: Andrey Smirnov @ 2019-07-29 19:52 UTC (permalink / raw)
  To: linux-serial
  Cc: Andrey Smirnov, Stefan Agner, Bhuvanchandra DV, Chris Healy,
	Cory Tusar, Lucas Stach, Greg Kroah-Hartman, Jiri Slaby,
	linux-imx, linux-kernel

Busy polling on a bit in a register is used in multiple places in the
driver. Move it into a shared function.

Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
Cc: Stefan Agner <stefan@agner.ch>
Cc: Bhuvanchandra DV <bhuvanchandra.dv@toradex.com>
Cc: Chris Healy <cphealy@gmail.com>
Cc: Cory Tusar <cory.tusar@zii.aero>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Jiri Slaby <jslaby@suse.com>
Cc: linux-imx@nxp.com
Cc: linux-serial@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/tty/serial/fsl_lpuart.c | 42 +++++++++++++++++----------------
 1 file changed, 22 insertions(+), 20 deletions(-)

diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
index 50a707c88a16..dde5caf724ff 100644
--- a/drivers/tty/serial/fsl_lpuart.c
+++ b/drivers/tty/serial/fsl_lpuart.c
@@ -548,6 +548,20 @@ static void lpuart_flush_buffer(struct uart_port *port)
 	}
 }
 
+static void lpuart_wait_bit_set(struct uart_port *port, unsigned int offset,
+				u8 bit)
+{
+	while (!(readb(port->membase + offset) & bit))
+		barrier();
+}
+
+static void lpuart32_wait_bit_set(struct uart_port *port, unsigned int offset,
+				  u32 bit)
+{
+	while (!(lpuart32_read(port, offset) & bit))
+		barrier();
+}
+
 #if defined(CONFIG_CONSOLE_POLL)
 
 static int lpuart_poll_init(struct uart_port *port)
@@ -591,9 +605,7 @@ static int lpuart_poll_init(struct uart_port *port)
 static void lpuart_poll_put_char(struct uart_port *port, unsigned char c)
 {
 	/* drain */
-	while (!(readb(port->membase + UARTSR1) & UARTSR1_TDRE))
-		barrier();
-
+	lpuart_wait_bit_set(port, UARTSR1, UARTSR1_TDRE);
 	writeb(c, port->membase + UARTDR);
 }
 
@@ -643,9 +655,7 @@ static int lpuart32_poll_init(struct uart_port *port)
 
 static void lpuart32_poll_put_char(struct uart_port *port, unsigned char c)
 {
-	while (!(lpuart32_read(port, UARTSTAT) & UARTSTAT_TDRE))
-		barrier();
-
+	lpuart32_wait_bit_set(port, UARTSTAT, UARTSTAT_TDRE);
 	lpuart32_write(port, UARTDATA, c);
 }
 
@@ -1723,8 +1733,7 @@ lpuart_set_termios(struct uart_port *port, struct ktermios *termios,
 	uart_update_timeout(port, termios->c_cflag, baud);
 
 	/* wait transmit engin complete */
-	while (!(readb(sport->port.membase + UARTSR1) & UARTSR1_TC))
-		barrier();
+	lpuart_wait_bit_set(&sport->port, UARTSR1, UARTSR1_TC);
 
 	/* disable transmit and receive */
 	writeb(old_cr2 & ~(UARTCR2_TE | UARTCR2_RE),
@@ -1939,8 +1948,7 @@ lpuart32_set_termios(struct uart_port *port, struct ktermios *termios,
 	uart_update_timeout(port, termios->c_cflag, baud);
 
 	/* wait transmit engin complete */
-	while (!(lpuart32_read(&sport->port, UARTSTAT) & UARTSTAT_TC))
-		barrier();
+	lpuart32_wait_bit_set(&sport->port, UARTSTAT, UARTSTAT_TC);
 
 	/* disable transmit and receive */
 	lpuart32_write(&sport->port, old_ctrl & ~(UARTCTRL_TE | UARTCTRL_RE),
@@ -2055,17 +2063,13 @@ static struct lpuart_port *lpuart_ports[UART_NR];
 #ifdef CONFIG_SERIAL_FSL_LPUART_CONSOLE
 static void lpuart_console_putchar(struct uart_port *port, int ch)
 {
-	while (!(readb(port->membase + UARTSR1) & UARTSR1_TDRE))
-		barrier();
-
+	lpuart_wait_bit_set(port, UARTSR1, UARTSR1_TDRE);
 	writeb(ch, port->membase + UARTDR);
 }
 
 static void lpuart32_console_putchar(struct uart_port *port, int ch)
 {
-	while (!(lpuart32_read(port, UARTSTAT) & UARTSTAT_TDRE))
-		barrier();
-
+	lpuart32_wait_bit_set(port, UARTSTAT, UARTSTAT_TDRE);
 	lpuart32_write(port, ch, UARTDATA);
 }
 
@@ -2091,8 +2095,7 @@ lpuart_console_write(struct console *co, const char *s, unsigned int count)
 	uart_console_write(&sport->port, s, count, lpuart_console_putchar);
 
 	/* wait for transmitter finish complete and restore CR2 */
-	while (!(readb(sport->port.membase + UARTSR1) & UARTSR1_TC))
-		barrier();
+	lpuart_wait_bit_set(&sport->port, UARTSR1, UARTSR1_TC);
 
 	writeb(old_cr2, sport->port.membase + UARTCR2);
 
@@ -2122,8 +2125,7 @@ lpuart32_console_write(struct console *co, const char *s, unsigned int count)
 	uart_console_write(&sport->port, s, count, lpuart32_console_putchar);
 
 	/* wait for transmitter finish complete and restore CR2 */
-	while (!(lpuart32_read(&sport->port, UARTSTAT) & UARTSTAT_TC))
-		barrier();
+	lpuart32_wait_bit_set(&sport->port, UARTSTAT, UARTSTAT_TC);
 
 	lpuart32_write(&sport->port, old_cr, UARTCTRL);
 
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 15/24] tty: serial: fsl_lpuart: Use cpu_relax() instead of barrier()
  2019-07-29 19:52 [PATCH 00/24] LPUART fixes and improvements Andrey Smirnov
                   ` (13 preceding siblings ...)
  2019-07-29 19:52 ` [PATCH 14/24] tty: serial: fsl_lpuart: Introduce lpuart_wait_bit_set() Andrey Smirnov
@ 2019-07-29 19:52 ` Andrey Smirnov
  2019-07-29 19:52 ` [PATCH 16/24] tty: serial: fsl_lpuart: Introduce lpuart_stopped_or_empty() Andrey Smirnov
                   ` (9 subsequent siblings)
  24 siblings, 0 replies; 31+ messages in thread
From: Andrey Smirnov @ 2019-07-29 19:52 UTC (permalink / raw)
  To: linux-serial
  Cc: Andrey Smirnov, Stefan Agner, Bhuvanchandra DV, Chris Healy,
	Cory Tusar, Lucas Stach, Greg Kroah-Hartman, Jiri Slaby,
	linux-imx, linux-kernel

Use cpu_relax() instead of barrier() in a tight polling loops to make
them a bit more idiomatic. Should also improve things on ARM64 a bit
since cpu_relax() will expand into "yield" instruction there.

Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
Cc: Stefan Agner <stefan@agner.ch>
Cc: Bhuvanchandra DV <bhuvanchandra.dv@toradex.com>
Cc: Chris Healy <cphealy@gmail.com>
Cc: Cory Tusar <cory.tusar@zii.aero>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Jiri Slaby <jslaby@suse.com>
Cc: linux-imx@nxp.com
Cc: linux-serial@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/tty/serial/fsl_lpuart.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
index dde5caf724ff..7a0f96952291 100644
--- a/drivers/tty/serial/fsl_lpuart.c
+++ b/drivers/tty/serial/fsl_lpuart.c
@@ -552,14 +552,14 @@ static void lpuart_wait_bit_set(struct uart_port *port, unsigned int offset,
 				u8 bit)
 {
 	while (!(readb(port->membase + offset) & bit))
-		barrier();
+		cpu_relax();
 }
 
 static void lpuart32_wait_bit_set(struct uart_port *port, unsigned int offset,
 				  u32 bit)
 {
 	while (!(lpuart32_read(port, offset) & bit))
-		barrier();
+		cpu_relax();
 }
 
 #if defined(CONFIG_CONSOLE_POLL)
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 16/24] tty: serial: fsl_lpuart: Introduce lpuart_stopped_or_empty()
  2019-07-29 19:52 [PATCH 00/24] LPUART fixes and improvements Andrey Smirnov
                   ` (14 preceding siblings ...)
  2019-07-29 19:52 ` [PATCH 15/24] tty: serial: fsl_lpuart: Use cpu_relax() instead of barrier() Andrey Smirnov
@ 2019-07-29 19:52 ` Andrey Smirnov
  2019-07-29 19:52 ` [PATCH 17/24] tty: serial: fsl_lpuart: Drop unnecessary lpuart*_stop_tx() Andrey Smirnov
                   ` (8 subsequent siblings)
  24 siblings, 0 replies; 31+ messages in thread
From: Andrey Smirnov @ 2019-07-29 19:52 UTC (permalink / raw)
  To: linux-serial
  Cc: Andrey Smirnov, Stefan Agner, Bhuvanchandra DV, Chris Healy,
	Cory Tusar, Lucas Stach, Greg Kroah-Hartman, Jiri Slaby,
	linux-imx, linux-kernel

The check for

    uart_circ_empty(xmit) || uart_tx_stopped(&sport->port)

appears in multiple places in the driver. Move it into a helper
function.

Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
Cc: Stefan Agner <stefan@agner.ch>
Cc: Bhuvanchandra DV <bhuvanchandra.dv@toradex.com>
Cc: Chris Healy <cphealy@gmail.com>
Cc: Cory Tusar <cory.tusar@zii.aero>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Jiri Slaby <jslaby@suse.com>
Cc: linux-imx@nxp.com
Cc: linux-serial@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/tty/serial/fsl_lpuart.c | 17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
index 7a0f96952291..a090b93211e3 100644
--- a/drivers/tty/serial/fsl_lpuart.c
+++ b/drivers/tty/serial/fsl_lpuart.c
@@ -451,6 +451,11 @@ static void lpuart_dma_tx(struct lpuart_port *sport)
 	dma_async_issue_pending(sport->dma_tx_chan);
 }
 
+static bool lpuart_stopped_or_empty(struct uart_port *port)
+{
+	return uart_circ_empty(&port->state->xmit) || uart_tx_stopped(port);
+}
+
 static void lpuart_dma_tx_complete(void *arg)
 {
 	struct lpuart_port *sport = arg;
@@ -478,7 +483,7 @@ static void lpuart_dma_tx_complete(void *arg)
 
 	spin_lock_irqsave(&sport->port.lock, flags);
 
-	if (!uart_circ_empty(xmit) && !uart_tx_stopped(&sport->port))
+	if (!lpuart_stopped_or_empty(&sport->port))
 		lpuart_dma_tx(sport);
 
 	spin_unlock_irqrestore(&sport->port.lock, flags);
@@ -679,7 +684,7 @@ static inline void lpuart_transmit_buffer(struct lpuart_port *sport)
 		return;
 	}
 
-	if (uart_circ_empty(xmit) || uart_tx_stopped(&sport->port)) {
+	if (lpuart_stopped_or_empty(&sport->port)) {
 		lpuart_stop_tx(&sport->port);
 		return;
 	}
@@ -710,7 +715,7 @@ static inline void lpuart32_transmit_buffer(struct lpuart_port *sport)
 		return;
 	}
 
-	if (uart_circ_empty(xmit) || uart_tx_stopped(&sport->port)) {
+	if (lpuart_stopped_or_empty(&sport->port)) {
 		lpuart32_stop_tx(&sport->port);
 		return;
 	}
@@ -738,14 +743,13 @@ static void lpuart_start_tx(struct uart_port *port)
 {
 	struct lpuart_port *sport = container_of(port,
 			struct lpuart_port, port);
-	struct circ_buf *xmit = &sport->port.state->xmit;
 	unsigned char temp;
 
 	temp = readb(port->membase + UARTCR2);
 	writeb(temp | UARTCR2_TIE, port->membase + UARTCR2);
 
 	if (sport->lpuart_dma_tx_use) {
-		if (!uart_circ_empty(xmit) && !uart_tx_stopped(port))
+		if (!lpuart_stopped_or_empty(port))
 			lpuart_dma_tx(sport);
 	} else {
 		if (readb(port->membase + UARTSR1) & UARTSR1_TDRE)
@@ -756,11 +760,10 @@ static void lpuart_start_tx(struct uart_port *port)
 static void lpuart32_start_tx(struct uart_port *port)
 {
 	struct lpuart_port *sport = container_of(port, struct lpuart_port, port);
-	struct circ_buf *xmit = &sport->port.state->xmit;
 	unsigned long temp;
 
 	if (sport->lpuart_dma_tx_use) {
-		if (!uart_circ_empty(xmit) && !uart_tx_stopped(port))
+		if (!lpuart_stopped_or_empty(port))
 			lpuart_dma_tx(sport);
 	} else {
 		temp = lpuart32_read(port, UARTCTRL);
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 17/24] tty: serial: fsl_lpuart: Drop unnecessary lpuart*_stop_tx()
  2019-07-29 19:52 [PATCH 00/24] LPUART fixes and improvements Andrey Smirnov
                   ` (15 preceding siblings ...)
  2019-07-29 19:52 ` [PATCH 16/24] tty: serial: fsl_lpuart: Introduce lpuart_stopped_or_empty() Andrey Smirnov
@ 2019-07-29 19:52 ` Andrey Smirnov
  2019-07-29 19:52 ` [PATCH 18/24] tty: serial: fsl_lpuart: Introduce lpuart_dma_shutdown() Andrey Smirnov
                   ` (7 subsequent siblings)
  24 siblings, 0 replies; 31+ messages in thread
From: Andrey Smirnov @ 2019-07-29 19:52 UTC (permalink / raw)
  To: linux-serial
  Cc: Andrey Smirnov, Stefan Agner, Bhuvanchandra DV, Chris Healy,
	Cory Tusar, Lucas Stach, Greg Kroah-Hartman, Jiri Slaby,
	linux-imx, linux-kernel

By the time lpuart_shutdown() calls lpuart_stop_tx() UARTCR2_TE and
UARTCR2_TIE (which the latter will clear) are already cleared, so that
function call should effectively be a no-op. Moreso, lpuart_stop_tx()
is expected to be executed with port spinlock held, which the caller
doesn't. Given all that, drop the call to lpuart_stop_tx() in
lpuart_shutdown().

In case of lpuart32_shutdown()/lpuart32_stop_tx(), TIE won't even be
set if lpuart_dma_tx_use is true. Drop it there as well.

Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
Cc: Stefan Agner <stefan@agner.ch>
Cc: Bhuvanchandra DV <bhuvanchandra.dv@toradex.com>
Cc: Chris Healy <cphealy@gmail.com>
Cc: Cory Tusar <cory.tusar@zii.aero>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Jiri Slaby <jslaby@suse.com>
Cc: linux-imx@nxp.com
Cc: linux-serial@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/tty/serial/fsl_lpuart.c | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
index a090b93211e3..67f196f66533 100644
--- a/drivers/tty/serial/fsl_lpuart.c
+++ b/drivers/tty/serial/fsl_lpuart.c
@@ -1575,8 +1575,6 @@ static void lpuart_shutdown(struct uart_port *port)
 			sport->dma_tx_in_progress = false;
 			dmaengine_terminate_all(sport->dma_tx_chan);
 		}
-
-		lpuart_stop_tx(port);
 	}
 }
 
@@ -1608,8 +1606,6 @@ static void lpuart32_shutdown(struct uart_port *port)
 			sport->dma_tx_in_progress = false;
 			dmaengine_terminate_all(sport->dma_tx_chan);
 		}
-
-		lpuart32_stop_tx(port);
 	}
 }
 
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 18/24] tty: serial: fsl_lpuart: Introduce lpuart_dma_shutdown()
  2019-07-29 19:52 [PATCH 00/24] LPUART fixes and improvements Andrey Smirnov
                   ` (16 preceding siblings ...)
  2019-07-29 19:52 ` [PATCH 17/24] tty: serial: fsl_lpuart: Drop unnecessary lpuart*_stop_tx() Andrey Smirnov
@ 2019-07-29 19:52 ` Andrey Smirnov
  2019-07-29 19:52 ` [PATCH 19/24] tty: serial: fsl_lpuart: Introduce lpuart_tx_dma_startup() Andrey Smirnov
                   ` (6 subsequent siblings)
  24 siblings, 0 replies; 31+ messages in thread
From: Andrey Smirnov @ 2019-07-29 19:52 UTC (permalink / raw)
  To: linux-serial
  Cc: Andrey Smirnov, Stefan Agner, Bhuvanchandra DV, Chris Healy,
	Cory Tusar, Lucas Stach, Greg Kroah-Hartman, Jiri Slaby,
	linux-imx, linux-kernel

Last steps of .shutdown() code are identical for lpuart and lpuart32
cases, so move it all into a standalone subroutine.

Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
Cc: Stefan Agner <stefan@agner.ch>
Cc: Bhuvanchandra DV <bhuvanchandra.dv@toradex.com>
Cc: Chris Healy <cphealy@gmail.com>
Cc: Cory Tusar <cory.tusar@zii.aero>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Jiri Slaby <jslaby@suse.com>
Cc: linux-imx@nxp.com
Cc: linux-serial@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/tty/serial/fsl_lpuart.c | 42 ++++++++++++++-------------------
 1 file changed, 18 insertions(+), 24 deletions(-)

diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
index 67f196f66533..2ad5750fe511 100644
--- a/drivers/tty/serial/fsl_lpuart.c
+++ b/drivers/tty/serial/fsl_lpuart.c
@@ -1548,6 +1548,22 @@ static int lpuart32_startup(struct uart_port *port)
 	return 0;
 }
 
+static void lpuart_dma_shutdown(struct lpuart_port *sport)
+{
+	if (sport->lpuart_dma_rx_use) {
+		del_timer_sync(&sport->lpuart_timer);
+		lpuart_dma_rx_free(&sport->port);
+	}
+
+	if (sport->lpuart_dma_tx_use) {
+		if (wait_event_interruptible(sport->dma_wait,
+			!sport->dma_tx_in_progress) != false) {
+			sport->dma_tx_in_progress = false;
+			dmaengine_terminate_all(sport->dma_tx_chan);
+		}
+	}
+}
+
 static void lpuart_shutdown(struct uart_port *port)
 {
 	struct lpuart_port *sport = container_of(port, struct lpuart_port, port);
@@ -1564,18 +1580,7 @@ static void lpuart_shutdown(struct uart_port *port)
 
 	spin_unlock_irqrestore(&port->lock, flags);
 
-	if (sport->lpuart_dma_rx_use) {
-		del_timer_sync(&sport->lpuart_timer);
-		lpuart_dma_rx_free(&sport->port);
-	}
-
-	if (sport->lpuart_dma_tx_use) {
-		if (wait_event_interruptible(sport->dma_wait,
-			!sport->dma_tx_in_progress) != false) {
-			sport->dma_tx_in_progress = false;
-			dmaengine_terminate_all(sport->dma_tx_chan);
-		}
-	}
+	lpuart_dma_shutdown(sport);
 }
 
 static void lpuart32_shutdown(struct uart_port *port)
@@ -1595,18 +1600,7 @@ static void lpuart32_shutdown(struct uart_port *port)
 
 	spin_unlock_irqrestore(&port->lock, flags);
 
-	if (sport->lpuart_dma_rx_use) {
-		del_timer_sync(&sport->lpuart_timer);
-		lpuart_dma_rx_free(&sport->port);
-	}
-
-	if (sport->lpuart_dma_tx_use) {
-		if (wait_event_interruptible(sport->dma_wait,
-					     !sport->dma_tx_in_progress)) {
-			sport->dma_tx_in_progress = false;
-			dmaengine_terminate_all(sport->dma_tx_chan);
-		}
-	}
+	lpuart_dma_shutdown(sport);
 }
 
 static void
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 19/24] tty: serial: fsl_lpuart: Introduce lpuart_tx_dma_startup()
  2019-07-29 19:52 [PATCH 00/24] LPUART fixes and improvements Andrey Smirnov
                   ` (17 preceding siblings ...)
  2019-07-29 19:52 ` [PATCH 18/24] tty: serial: fsl_lpuart: Introduce lpuart_dma_shutdown() Andrey Smirnov
@ 2019-07-29 19:52 ` Andrey Smirnov
  2019-07-30 15:56   ` Greg Kroah-Hartman
  2019-07-29 19:52 ` [PATCH 20/24] tty: serial: fsl_lpuart: Introduce lpuart_rx_dma_startup() Andrey Smirnov
                   ` (5 subsequent siblings)
  24 siblings, 1 reply; 31+ messages in thread
From: Andrey Smirnov @ 2019-07-29 19:52 UTC (permalink / raw)
  To: linux-serial
  Cc: Andrey Smirnov, Stefan Agner, Bhuvanchandra DV, Chris Healy,
	Cory Tusar, Lucas Stach, Greg Kroah-Hartman, Jiri Slaby,
	linux-imx, linux-kernel

Code configure DMA TX path in lpuart_startup(), lpuart32_startup() and
lpuart_resume() is doing exactly the same thing, so move it into a
standalone subroutine.

Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
Cc: Stefan Agner <stefan@agner.ch>
Cc: Bhuvanchandra DV <bhuvanchandra.dv@toradex.com>
Cc: Chris Healy <cphealy@gmail.com>
Cc: Cory Tusar <cory.tusar@zii.aero>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Jiri Slaby <jslaby@suse.com>
Cc: linux-imx@nxp.com
Cc: linux-serial@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/tty/serial/fsl_lpuart.c | 53 ++++++++++++++-------------------
 1 file changed, 23 insertions(+), 30 deletions(-)

diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
index 2ad5750fe511..558acf29cbed 100644
--- a/drivers/tty/serial/fsl_lpuart.c
+++ b/drivers/tty/serial/fsl_lpuart.c
@@ -1434,6 +1434,26 @@ static void rx_dma_timer_init(struct lpuart_port *sport)
 	add_timer(&sport->lpuart_timer);
 }
 
+static void lpuart_tx_dma_startup(struct lpuart_port *sport)
+{
+	u32 uartbaud;
+
+	if (sport->dma_tx_chan && !lpuart_dma_tx_request(&sport->port)) {
+		init_waitqueue_head(&sport->dma_wait);
+		sport->lpuart_dma_tx_use = true;
+		if (lpuart_is_32(sport)) {
+			uartbaud = lpuart32_read(&sport->port, UARTBAUD);
+			lpuart32_write(&sport->port,
+				       uartbaud | UARTBAUD_TDMAE, UARTBAUD);
+		} else {
+			writeb(readb(sport->port.membase + UARTCR5) |
+				UARTCR5_TDMAS, sport->port.membase + UARTCR5);
+		}
+	} else {
+		sport->lpuart_dma_tx_use = false;
+	}
+}
+
 static int lpuart_startup(struct uart_port *port)
 {
 	struct lpuart_port *sport = container_of(port, struct lpuart_port, port);
@@ -1471,14 +1491,7 @@ static int lpuart_startup(struct uart_port *port)
 		sport->lpuart_dma_rx_use = false;
 	}
 
-	if (sport->dma_tx_chan && !lpuart_dma_tx_request(port)) {
-		init_waitqueue_head(&sport->dma_wait);
-		sport->lpuart_dma_tx_use = true;
-		temp = readb(port->membase + UARTCR5);
-		writeb(temp | UARTCR5_TDMAS, port->membase + UARTCR5);
-	} else {
-		sport->lpuart_dma_tx_use = false;
-	}
+	lpuart_tx_dma_startup(port);
 
 	spin_unlock_irqrestore(&sport->port.lock, flags);
 
@@ -1522,14 +1535,7 @@ static int lpuart32_startup(struct uart_port *port)
 		sport->lpuart_dma_rx_use = false;
 	}
 
-	if (sport->dma_tx_chan && !lpuart_dma_tx_request(port)) {
-		init_waitqueue_head(&sport->dma_wait);
-		sport->lpuart_dma_tx_use = true;
-		temp = lpuart32_read(&sport->port, UARTBAUD);
-		lpuart32_write(&sport->port, temp | UARTBAUD_TDMAE, UARTBAUD);
-	} else {
-		sport->lpuart_dma_tx_use = false;
-	}
+	lpuart_tx_dma_startup(port);
 
 	if (sport->lpuart_dma_rx_use) {
 		/* RXWATER must be 0 */
@@ -2581,20 +2587,7 @@ static int lpuart_resume(struct device *dev)
 		}
 	}
 
-	if (sport->dma_tx_chan && !lpuart_dma_tx_request(&sport->port)) {
-		init_waitqueue_head(&sport->dma_wait);
-		sport->lpuart_dma_tx_use = true;
-		if (lpuart_is_32(sport)) {
-			temp = lpuart32_read(&sport->port, UARTBAUD);
-			lpuart32_write(&sport->port,
-				       temp | UARTBAUD_TDMAE, UARTBAUD);
-		} else {
-			writeb(readb(sport->port.membase + UARTCR5) |
-				UARTCR5_TDMAS, sport->port.membase + UARTCR5);
-		}
-	} else {
-		sport->lpuart_dma_tx_use = false;
-	}
+	lpuart_tx_dma_startup(sport);
 
 	if (lpuart_is_32(sport)) {
 		if (sport->lpuart_dma_rx_use) {
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 20/24] tty: serial: fsl_lpuart: Introduce lpuart_rx_dma_startup()
  2019-07-29 19:52 [PATCH 00/24] LPUART fixes and improvements Andrey Smirnov
                   ` (18 preceding siblings ...)
  2019-07-29 19:52 ` [PATCH 19/24] tty: serial: fsl_lpuart: Introduce lpuart_tx_dma_startup() Andrey Smirnov
@ 2019-07-29 19:52 ` Andrey Smirnov
  2019-07-29 19:52 ` [PATCH 21/24] tty: serial: fsl_lpuart: Introduce lpuart32_configure() Andrey Smirnov
                   ` (4 subsequent siblings)
  24 siblings, 0 replies; 31+ messages in thread
From: Andrey Smirnov @ 2019-07-29 19:52 UTC (permalink / raw)
  To: linux-serial
  Cc: Andrey Smirnov, Stefan Agner, Bhuvanchandra DV, Chris Healy,
	Cory Tusar, Lucas Stach, Greg Kroah-Hartman, Jiri Slaby,
	linux-imx, linux-kernel

Code doing initial DMA RX configuration in lpuart_startup() and
lpuart32_startup() is exactly the same, so move it into a standalone
subroutine.

Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
Cc: Stefan Agner <stefan@agner.ch>
Cc: Bhuvanchandra DV <bhuvanchandra.dv@toradex.com>
Cc: Chris Healy <cphealy@gmail.com>
Cc: Cory Tusar <cory.tusar@zii.aero>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Jiri Slaby <jslaby@suse.com>
Cc: linux-imx@nxp.com
Cc: linux-serial@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/tty/serial/fsl_lpuart.c | 41 ++++++++++++++-------------------
 1 file changed, 17 insertions(+), 24 deletions(-)

diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
index 558acf29cbed..bda01d23cea8 100644
--- a/drivers/tty/serial/fsl_lpuart.c
+++ b/drivers/tty/serial/fsl_lpuart.c
@@ -1454,6 +1454,21 @@ static void lpuart_tx_dma_startup(struct lpuart_port *sport)
 	}
 }
 
+static void lpuart_rx_dma_startup(struct lpuart_port *sport)
+{
+	if (sport->dma_rx_chan && !lpuart_start_rx_dma(sport)) {
+		/* set Rx DMA timeout */
+		sport->dma_rx_timeout = msecs_to_jiffies(DMA_RX_TIMEOUT);
+		if (!sport->dma_rx_timeout)
+			sport->dma_rx_timeout = 1;
+
+		sport->lpuart_dma_rx_use = true;
+		rx_dma_timer_init(sport);
+	} else {
+		sport->lpuart_dma_rx_use = false;
+	}
+}
+
 static int lpuart_startup(struct uart_port *port)
 {
 	struct lpuart_port *sport = container_of(port, struct lpuart_port, port);
@@ -1479,18 +1494,7 @@ static int lpuart_startup(struct uart_port *port)
 	temp |= UARTCR2_RIE | UARTCR2_TIE | UARTCR2_RE | UARTCR2_TE;
 	writeb(temp, sport->port.membase + UARTCR2);
 
-	if (sport->dma_rx_chan && !lpuart_start_rx_dma(sport)) {
-		/* set Rx DMA timeout */
-		sport->dma_rx_timeout = msecs_to_jiffies(DMA_RX_TIMEOUT);
-		if (!sport->dma_rx_timeout)
-		     sport->dma_rx_timeout = 1;
-
-		sport->lpuart_dma_rx_use = true;
-		rx_dma_timer_init(sport);
-	} else {
-		sport->lpuart_dma_rx_use = false;
-	}
-
+	lpuart_rx_dma_startup(sport);
 	lpuart_tx_dma_startup(port);
 
 	spin_unlock_irqrestore(&sport->port.lock, flags);
@@ -1523,18 +1527,7 @@ static int lpuart32_startup(struct uart_port *port)
 	temp |= UARTCTRL_RE | UARTCTRL_TE | UARTCTRL_ILIE;
 	lpuart32_write(&sport->port, temp, UARTCTRL);
 
-	if (sport->dma_rx_chan && !lpuart_start_rx_dma(sport)) {
-		/* set Rx DMA timeout */
-		sport->dma_rx_timeout = msecs_to_jiffies(DMA_RX_TIMEOUT);
-		if (!sport->dma_rx_timeout)
-			sport->dma_rx_timeout = 1;
-
-		sport->lpuart_dma_rx_use = true;
-		rx_dma_timer_init(sport);
-	} else {
-		sport->lpuart_dma_rx_use = false;
-	}
-
+	lpuart_rx_dma_startup(sport);
 	lpuart_tx_dma_startup(port);
 
 	if (sport->lpuart_dma_rx_use) {
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 21/24] tty: serial: fsl_lpuart: Introduce lpuart32_configure()
  2019-07-29 19:52 [PATCH 00/24] LPUART fixes and improvements Andrey Smirnov
                   ` (19 preceding siblings ...)
  2019-07-29 19:52 ` [PATCH 20/24] tty: serial: fsl_lpuart: Introduce lpuart_rx_dma_startup() Andrey Smirnov
@ 2019-07-29 19:52 ` Andrey Smirnov
  2019-07-29 19:52 ` [PATCH 22/24] tty: serial: fsl_lpuart: Introduce lpuart*_setup_watermark_enable() Andrey Smirnov
                   ` (3 subsequent siblings)
  24 siblings, 0 replies; 31+ messages in thread
From: Andrey Smirnov @ 2019-07-29 19:52 UTC (permalink / raw)
  To: linux-serial
  Cc: Andrey Smirnov, Stefan Agner, Bhuvanchandra DV, Chris Healy,
	Cory Tusar, Lucas Stach, Greg Kroah-Hartman, Jiri Slaby,
	linux-imx, linux-kernel

Code doing final steps of TX/RX configuration in lpuart32_startup()
and lpuart_resume() is identical, so move it into a standalone
subroutine.

Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
Cc: Stefan Agner <stefan@agner.ch>
Cc: Bhuvanchandra DV <bhuvanchandra.dv@toradex.com>
Cc: Chris Healy <cphealy@gmail.com>
Cc: Cory Tusar <cory.tusar@zii.aero>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Jiri Slaby <jslaby@suse.com>
Cc: linux-imx@nxp.com
Cc: linux-serial@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/tty/serial/fsl_lpuart.c | 48 +++++++++++++++------------------
 1 file changed, 21 insertions(+), 27 deletions(-)

diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
index bda01d23cea8..112fb1e19a1c 100644
--- a/drivers/tty/serial/fsl_lpuart.c
+++ b/drivers/tty/serial/fsl_lpuart.c
@@ -1502,6 +1502,24 @@ static int lpuart_startup(struct uart_port *port)
 	return 0;
 }
 
+static void lpuart32_configure(struct lpuart_port *sport)
+{
+	unsigned long temp;
+
+	if (sport->lpuart_dma_rx_use) {
+		/* RXWATER must be 0 */
+		temp = lpuart32_read(&sport->port, UARTWATER);
+		temp &= ~(UARTWATER_WATER_MASK << UARTWATER_RXWATER_OFF);
+		lpuart32_write(&sport->port, temp, UARTWATER);
+	}
+	temp = lpuart32_read(&sport->port, UARTCTRL);
+	if (!sport->lpuart_dma_rx_use)
+		temp |= UARTCTRL_RIE;
+	if (!sport->lpuart_dma_tx_use)
+		temp |= UARTCTRL_TIE;
+	lpuart32_write(&sport->port, temp, UARTCTRL);
+}
+
 static int lpuart32_startup(struct uart_port *port)
 {
 	struct lpuart_port *sport = container_of(port, struct lpuart_port, port);
@@ -1530,18 +1548,7 @@ static int lpuart32_startup(struct uart_port *port)
 	lpuart_rx_dma_startup(sport);
 	lpuart_tx_dma_startup(port);
 
-	if (sport->lpuart_dma_rx_use) {
-		/* RXWATER must be 0 */
-		temp = lpuart32_read(&sport->port, UARTWATER);
-		temp &= ~(UARTWATER_WATER_MASK << UARTWATER_RXWATER_OFF);
-		lpuart32_write(&sport->port, temp, UARTWATER);
-	}
-	temp = lpuart32_read(&sport->port, UARTCTRL);
-	if (!sport->lpuart_dma_rx_use)
-		temp |= UARTCTRL_RIE;
-	if (!sport->lpuart_dma_tx_use)
-		temp |= UARTCTRL_TIE;
-	lpuart32_write(&sport->port, temp, UARTCTRL);
+	lpuart32_configure(sport);
 
 	spin_unlock_irqrestore(&sport->port.lock, flags);
 	return 0;
@@ -2582,21 +2589,8 @@ static int lpuart_resume(struct device *dev)
 
 	lpuart_tx_dma_startup(sport);
 
-	if (lpuart_is_32(sport)) {
-		if (sport->lpuart_dma_rx_use) {
-			/* RXWATER must be 0 */
-			temp = lpuart32_read(&sport->port, UARTWATER);
-			temp &= ~(UARTWATER_WATER_MASK <<
-				  UARTWATER_RXWATER_OFF);
-			lpuart32_write(&sport->port, temp, UARTWATER);
-		}
-		temp = lpuart32_read(&sport->port, UARTCTRL);
-		if (!sport->lpuart_dma_rx_use)
-			temp |= UARTCTRL_RIE;
-		if (!sport->lpuart_dma_tx_use)
-			temp |= UARTCTRL_TIE;
-		lpuart32_write(&sport->port, temp, UARTCTRL);
-	}
+	if (lpuart_is_32(sport))
+		lpuart32_configure(sport);
 
 	uart_resume_port(&lpuart_reg, &sport->port);
 
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 22/24] tty: serial: fsl_lpuart: Introduce lpuart*_setup_watermark_enable()
  2019-07-29 19:52 [PATCH 00/24] LPUART fixes and improvements Andrey Smirnov
                   ` (20 preceding siblings ...)
  2019-07-29 19:52 ` [PATCH 21/24] tty: serial: fsl_lpuart: Introduce lpuart32_configure() Andrey Smirnov
@ 2019-07-29 19:52 ` Andrey Smirnov
  2019-07-29 19:52 ` [PATCH 23/24] tty: serial: fsl_lpuart: Don't enable TIE in .startup() or .resume() Andrey Smirnov
                   ` (2 subsequent siblings)
  24 siblings, 0 replies; 31+ messages in thread
From: Andrey Smirnov @ 2019-07-29 19:52 UTC (permalink / raw)
  To: linux-serial
  Cc: Andrey Smirnov, Stefan Agner, Bhuvanchandra DV, Chris Healy,
	Cory Tusar, Lucas Stach, Greg Kroah-Hartman, Jiri Slaby,
	linux-imx, linux-kernel

Most users of lpuart*_setup_watermark() enable identical set of flags
right after the call, so combine those two action into a subroutine
and make use of it.

Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
Cc: Stefan Agner <stefan@agner.ch>
Cc: Bhuvanchandra DV <bhuvanchandra.dv@toradex.com>
Cc: Chris Healy <cphealy@gmail.com>
Cc: Cory Tusar <cory.tusar@zii.aero>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Jiri Slaby <jslaby@suse.com>
Cc: linux-imx@nxp.com
Cc: linux-serial@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/tty/serial/fsl_lpuart.c | 50 ++++++++++++++++++---------------
 1 file changed, 28 insertions(+), 22 deletions(-)

diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
index 112fb1e19a1c..9643d4524e59 100644
--- a/drivers/tty/serial/fsl_lpuart.c
+++ b/drivers/tty/serial/fsl_lpuart.c
@@ -1402,6 +1402,17 @@ static void lpuart_setup_watermark(struct lpuart_port *sport)
 	writeb(cr2_saved, sport->port.membase + UARTCR2);
 }
 
+static void lpuart_setup_watermark_enable(struct lpuart_port *sport)
+{
+	unsigned char cr2;
+
+	lpuart_setup_watermark(sport);
+
+	cr2 = readb(sport->port.membase + UARTCR2);
+	cr2 |= UARTCR2_RIE | UARTCR2_TIE | UARTCR2_RE | UARTCR2_TE;
+	writeb(cr2, sport->port.membase + UARTCR2);
+}
+
 static void lpuart32_setup_watermark(struct lpuart_port *sport)
 {
 	unsigned long val, ctrl;
@@ -1427,6 +1438,17 @@ static void lpuart32_setup_watermark(struct lpuart_port *sport)
 	lpuart32_write(&sport->port, ctrl_saved, UARTCTRL);
 }
 
+static void lpuart32_setup_watermark_enable(struct lpuart_port *sport)
+{
+	u32 temp;
+
+	lpuart32_setup_watermark(sport);
+
+	temp = lpuart32_read(&sport->port, UARTCTRL);
+	temp |= UARTCTRL_RE | UARTCTRL_TE | UARTCTRL_ILIE;
+	lpuart32_write(&sport->port, temp, UARTCTRL);
+}
+
 static void rx_dma_timer_init(struct lpuart_port *sport)
 {
 	timer_setup(&sport->lpuart_timer, lpuart_timer_func, 0);
@@ -1488,11 +1510,7 @@ static int lpuart_startup(struct uart_port *port)
 
 	spin_lock_irqsave(&sport->port.lock, flags);
 
-	lpuart_setup_watermark(sport);
-
-	temp = readb(sport->port.membase + UARTCR2);
-	temp |= UARTCR2_RIE | UARTCR2_TIE | UARTCR2_RE | UARTCR2_TE;
-	writeb(temp, sport->port.membase + UARTCR2);
+	lpuart_setup_watermark_enable(sport);
 
 	lpuart_rx_dma_startup(sport);
 	lpuart_tx_dma_startup(port);
@@ -1539,11 +1557,7 @@ static int lpuart32_startup(struct uart_port *port)
 
 	spin_lock_irqsave(&sport->port.lock, flags);
 
-	lpuart32_setup_watermark(sport);
-
-	temp = lpuart32_read(&sport->port, UARTCTRL);
-	temp |= UARTCTRL_RE | UARTCTRL_TE | UARTCTRL_ILIE;
-	lpuart32_write(&sport->port, temp, UARTCTRL);
+	lpuart32_setup_watermark_enable(sport);
 
 	lpuart_rx_dma_startup(sport);
 	lpuart_tx_dma_startup(port);
@@ -2561,22 +2575,14 @@ static int lpuart_resume(struct device *dev)
 {
 	struct lpuart_port *sport = dev_get_drvdata(dev);
 	bool irq_wake = irqd_is_wakeup_set(irq_get_irq_data(sport->port.irq));
-	unsigned long temp;
 
 	if (sport->port.suspended && !irq_wake)
 		lpuart_enable_clks(sport);
 
-	if (lpuart_is_32(sport)) {
-		lpuart32_setup_watermark(sport);
-		temp = lpuart32_read(&sport->port, UARTCTRL);
-		temp |= UARTCTRL_RE | UARTCTRL_TE | UARTCTRL_ILIE;
-		lpuart32_write(&sport->port, temp, UARTCTRL);
-	} else {
-		lpuart_setup_watermark(sport);
-		temp = readb(sport->port.membase + UARTCR2);
-		temp |= UARTCR2_RIE | UARTCR2_TIE | UARTCR2_RE | UARTCR2_TE;
-		writeb(temp, sport->port.membase + UARTCR2);
-	}
+	if (lpuart_is_32(sport))
+		lpuart32_setup_watermark_enable(sport);
+	else
+		lpuart_setup_watermark_enable(sport);
 
 	if (sport->lpuart_dma_rx_use) {
 		if (irq_wake) {
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 23/24] tty: serial: fsl_lpuart: Don't enable TIE in .startup() or .resume()
  2019-07-29 19:52 [PATCH 00/24] LPUART fixes and improvements Andrey Smirnov
                   ` (21 preceding siblings ...)
  2019-07-29 19:52 ` [PATCH 22/24] tty: serial: fsl_lpuart: Introduce lpuart*_setup_watermark_enable() Andrey Smirnov
@ 2019-07-29 19:52 ` Andrey Smirnov
  2019-07-29 19:52 ` [PATCH 24/24] tty: serial: fsl_lpuart: Ignore TX/RX interrupts if DMA is enabled Andrey Smirnov
  2019-07-30 15:53 ` [PATCH 00/24] LPUART fixes and improvements Greg Kroah-Hartman
  24 siblings, 0 replies; 31+ messages in thread
From: Andrey Smirnov @ 2019-07-29 19:52 UTC (permalink / raw)
  To: linux-serial
  Cc: Andrey Smirnov, Stefan Agner, Bhuvanchandra DV, Chris Healy,
	Cory Tusar, Lucas Stach, Greg Kroah-Hartman, Jiri Slaby,
	linux-imx, linux-kernel

Enabling TIE in .startup() callback causes the driver to start (or at
least try) to transmit data before .start_tx() is called. Which, while
harmless (since TIE handler will immediately disable it), is a no-op
and shouldn't really happen. Drop UARTCR2_TIE from list of bits set in
lpuart_startup().

This change will also not enable TIE in .resume(), but it seems that,
similart to .startup(), transmit interrupt shouldn't be enabled there
either.

Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
Cc: Stefan Agner <stefan@agner.ch>
Cc: Bhuvanchandra DV <bhuvanchandra.dv@toradex.com>
Cc: Chris Healy <cphealy@gmail.com>
Cc: Cory Tusar <cory.tusar@zii.aero>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Jiri Slaby <jslaby@suse.com>
Cc: linux-imx@nxp.com
Cc: linux-serial@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/tty/serial/fsl_lpuart.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
index 9643d4524e59..53b98065f9c5 100644
--- a/drivers/tty/serial/fsl_lpuart.c
+++ b/drivers/tty/serial/fsl_lpuart.c
@@ -1409,7 +1409,7 @@ static void lpuart_setup_watermark_enable(struct lpuart_port *sport)
 	lpuart_setup_watermark(sport);
 
 	cr2 = readb(sport->port.membase + UARTCR2);
-	cr2 |= UARTCR2_RIE | UARTCR2_TIE | UARTCR2_RE | UARTCR2_TE;
+	cr2 |= UARTCR2_RIE | UARTCR2_RE | UARTCR2_TE;
 	writeb(cr2, sport->port.membase + UARTCR2);
 }
 
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 24/24] tty: serial: fsl_lpuart: Ignore TX/RX interrupts if DMA is enabled
  2019-07-29 19:52 [PATCH 00/24] LPUART fixes and improvements Andrey Smirnov
                   ` (22 preceding siblings ...)
  2019-07-29 19:52 ` [PATCH 23/24] tty: serial: fsl_lpuart: Don't enable TIE in .startup() or .resume() Andrey Smirnov
@ 2019-07-29 19:52 ` Andrey Smirnov
  2019-07-30 15:53 ` [PATCH 00/24] LPUART fixes and improvements Greg Kroah-Hartman
  24 siblings, 0 replies; 31+ messages in thread
From: Andrey Smirnov @ 2019-07-29 19:52 UTC (permalink / raw)
  To: linux-serial
  Cc: Andrey Smirnov, Stefan Agner, Bhuvanchandra DV, Chris Healy,
	Cory Tusar, Lucas Stach, Greg Kroah-Hartman, Jiri Slaby,
	linux-imx, linux-kernel

In a mixed DMA/IRQ use-case (e.g.: DMA for TX, IRQ for RX), interrupt
handler might try to handle Rx/Tx condition it shouldn't. Change the
code to only handle TX/RX event if corresponding path isn't being
handled by DMA.

Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
Cc: Stefan Agner <stefan@agner.ch>
Cc: Bhuvanchandra DV <bhuvanchandra.dv@toradex.com>
Cc: Chris Healy <cphealy@gmail.com>
Cc: Cory Tusar <cory.tusar@zii.aero>
Cc: Lucas Stach <l.stach@pengutronix.de>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Jiri Slaby <jslaby@suse.com>
Cc: linux-imx@nxp.com
Cc: linux-serial@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
 drivers/tty/serial/fsl_lpuart.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
index 53b98065f9c5..b74027964b45 100644
--- a/drivers/tty/serial/fsl_lpuart.c
+++ b/drivers/tty/serial/fsl_lpuart.c
@@ -966,10 +966,10 @@ static irqreturn_t lpuart_int(int irq, void *dev_id)
 
 	sts = readb(sport->port.membase + UARTSR1);
 
-	if (sts & UARTSR1_RDRF)
+	if (sts & UARTSR1_RDRF && !sport->lpuart_dma_rx_use)
 		lpuart_rxint(sport);
 
-	if (sts & UARTSR1_TDRE)
+	if (sts & UARTSR1_TDRE && !sport->lpuart_dma_tx_use)
 		lpuart_txint(sport);
 
 	return IRQ_HANDLED;
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* Re: [PATCH 06/24] tty: serial: fsl_lpuart: Drop unnecessary sg_set_buf() call
  2019-07-29 19:52 ` [PATCH 06/24] tty: serial: fsl_lpuart: Drop unnecessary sg_set_buf() call Andrey Smirnov
@ 2019-07-30 15:51   ` Greg Kroah-Hartman
  2019-07-31  2:08     ` Andrey Smirnov
  0 siblings, 1 reply; 31+ messages in thread
From: Greg Kroah-Hartman @ 2019-07-30 15:51 UTC (permalink / raw)
  To: Andrey Smirnov
  Cc: linux-serial, Stefan Agner, Bhuvanchandra DV, Chris Healy,
	Cory Tusar, Lucas Stach, Jiri Slaby, linux-imx, linux-kernel

On Mon, Jul 29, 2019 at 12:52:08PM -0700, Andrey Smirnov wrote:
> Sg_init_one() will already call sg_set_buf(), so another explicit call
> right after it is unnecessary. Drop it.
> 
> Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
> Cc: Stefan Agner <stefan@agner.ch>
> Cc: Bhuvanchandra DV <bhuvanchandra.dv@toradex.com>
> Cc: Chris Healy <cphealy@gmail.com>
> Cc: Cory Tusar <cory.tusar@zii.aero>
> Cc: Lucas Stach <l.stach@pengutronix.de>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Cc: Jiri Slaby <jslaby@suse.com>
> Cc: linux-imx@nxp.com
> Cc: linux-serial@vger.kernel.org
> Cc: linux-kernel@vger.kernel.org
> ---
>  drivers/tty/serial/fsl_lpuart.c | 1 -
>  1 file changed, 1 deletion(-)
> 
> diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
> index 1b3f2a87e558..b600f591c8c2 100644
> --- a/drivers/tty/serial/fsl_lpuart.c
> +++ b/drivers/tty/serial/fsl_lpuart.c
> @@ -1144,7 +1144,6 @@ static inline int lpuart_start_rx_dma(struct lpuart_port *sport)
>  		return -ENOMEM;
>  
>  	sg_init_one(&sport->rx_sgl, ring->buf, sport->rx_dma_rng_buf_len);
> -	sg_set_buf(&sport->rx_sgl, ring->buf, sport->rx_dma_rng_buf_len);
>  	nent = dma_map_sg(sport->port.dev, &sport->rx_sgl, 1, DMA_FROM_DEVICE);
>  
>  	if (!nent) {

This patch doesn't apply, is it already in the tree from someone else?

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 00/24] LPUART fixes and improvements
  2019-07-29 19:52 [PATCH 00/24] LPUART fixes and improvements Andrey Smirnov
                   ` (23 preceding siblings ...)
  2019-07-29 19:52 ` [PATCH 24/24] tty: serial: fsl_lpuart: Ignore TX/RX interrupts if DMA is enabled Andrey Smirnov
@ 2019-07-30 15:53 ` Greg Kroah-Hartman
  2019-07-30 15:54   ` Greg Kroah-Hartman
  24 siblings, 1 reply; 31+ messages in thread
From: Greg Kroah-Hartman @ 2019-07-30 15:53 UTC (permalink / raw)
  To: Andrey Smirnov
  Cc: linux-serial, Stefan Agner, Bhuvanchandra DV, Chris Healy,
	Cory Tusar, Lucas Stach, Jiri Slaby, linux-imx, linux-kernel

On Mon, Jul 29, 2019 at 12:52:02PM -0700, Andrey Smirnov wrote:
> Everyone:
> 
> This series contains fixes/improvements to LPUART dirver I came up
> with recently as well as fixes picked up from Toradex and NXP Vybrid
> repos.
> 
> Feedback is welcome!

Nice cleanups, all now queued up.

greg k-h

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 00/24] LPUART fixes and improvements
  2019-07-30 15:53 ` [PATCH 00/24] LPUART fixes and improvements Greg Kroah-Hartman
@ 2019-07-30 15:54   ` Greg Kroah-Hartman
  0 siblings, 0 replies; 31+ messages in thread
From: Greg Kroah-Hartman @ 2019-07-30 15:54 UTC (permalink / raw)
  To: Andrey Smirnov
  Cc: linux-serial, Stefan Agner, Bhuvanchandra DV, Chris Healy,
	Cory Tusar, Lucas Stach, Jiri Slaby, linux-imx, linux-kernel

On Tue, Jul 30, 2019 at 05:53:57PM +0200, Greg Kroah-Hartman wrote:
> On Mon, Jul 29, 2019 at 12:52:02PM -0700, Andrey Smirnov wrote:
> > Everyone:
> > 
> > This series contains fixes/improvements to LPUART dirver I came up
> > with recently as well as fixes picked up from Toradex and NXP Vybrid
> > repos.
> > 
> > Feedback is welcome!
> 
> Nice cleanups, all now queued up.

Oops, nope, not all, have a build error...

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 19/24] tty: serial: fsl_lpuart: Introduce lpuart_tx_dma_startup()
  2019-07-29 19:52 ` [PATCH 19/24] tty: serial: fsl_lpuart: Introduce lpuart_tx_dma_startup() Andrey Smirnov
@ 2019-07-30 15:56   ` Greg Kroah-Hartman
  2019-07-31  2:09     ` Andrey Smirnov
  0 siblings, 1 reply; 31+ messages in thread
From: Greg Kroah-Hartman @ 2019-07-30 15:56 UTC (permalink / raw)
  To: Andrey Smirnov
  Cc: linux-serial, Stefan Agner, Bhuvanchandra DV, Chris Healy,
	Cory Tusar, Lucas Stach, Jiri Slaby, linux-imx, linux-kernel

On Mon, Jul 29, 2019 at 12:52:21PM -0700, Andrey Smirnov wrote:
> Code configure DMA TX path in lpuart_startup(), lpuart32_startup() and
> lpuart_resume() is doing exactly the same thing, so move it into a
> standalone subroutine.
> 
> Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
> Cc: Stefan Agner <stefan@agner.ch>
> Cc: Bhuvanchandra DV <bhuvanchandra.dv@toradex.com>
> Cc: Chris Healy <cphealy@gmail.com>
> Cc: Cory Tusar <cory.tusar@zii.aero>
> Cc: Lucas Stach <l.stach@pengutronix.de>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Cc: Jiri Slaby <jslaby@suse.com>
> Cc: linux-imx@nxp.com
> Cc: linux-serial@vger.kernel.org
> Cc: linux-kernel@vger.kernel.org
> ---
>  drivers/tty/serial/fsl_lpuart.c | 53 ++++++++++++++-------------------
>  1 file changed, 23 insertions(+), 30 deletions(-)
> 
> diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
> index 2ad5750fe511..558acf29cbed 100644
> --- a/drivers/tty/serial/fsl_lpuart.c
> +++ b/drivers/tty/serial/fsl_lpuart.c
> @@ -1434,6 +1434,26 @@ static void rx_dma_timer_init(struct lpuart_port *sport)
>  	add_timer(&sport->lpuart_timer);
>  }
>  
> +static void lpuart_tx_dma_startup(struct lpuart_port *sport)
> +{
> +	u32 uartbaud;
> +
> +	if (sport->dma_tx_chan && !lpuart_dma_tx_request(&sport->port)) {
> +		init_waitqueue_head(&sport->dma_wait);
> +		sport->lpuart_dma_tx_use = true;
> +		if (lpuart_is_32(sport)) {
> +			uartbaud = lpuart32_read(&sport->port, UARTBAUD);
> +			lpuart32_write(&sport->port,
> +				       uartbaud | UARTBAUD_TDMAE, UARTBAUD);
> +		} else {
> +			writeb(readb(sport->port.membase + UARTCR5) |
> +				UARTCR5_TDMAS, sport->port.membase + UARTCR5);
> +		}
> +	} else {
> +		sport->lpuart_dma_tx_use = false;
> +	}
> +}
> +
>  static int lpuart_startup(struct uart_port *port)
>  {
>  	struct lpuart_port *sport = container_of(port, struct lpuart_port, port);
> @@ -1471,14 +1491,7 @@ static int lpuart_startup(struct uart_port *port)
>  		sport->lpuart_dma_rx_use = false;
>  	}
>  
> -	if (sport->dma_tx_chan && !lpuart_dma_tx_request(port)) {
> -		init_waitqueue_head(&sport->dma_wait);
> -		sport->lpuart_dma_tx_use = true;
> -		temp = readb(port->membase + UARTCR5);
> -		writeb(temp | UARTCR5_TDMAS, port->membase + UARTCR5);
> -	} else {
> -		sport->lpuart_dma_tx_use = false;
> -	}
> +	lpuart_tx_dma_startup(port);
>  
>  	spin_unlock_irqrestore(&sport->port.lock, flags);
>  
> @@ -1522,14 +1535,7 @@ static int lpuart32_startup(struct uart_port *port)
>  		sport->lpuart_dma_rx_use = false;
>  	}
>  
> -	if (sport->dma_tx_chan && !lpuart_dma_tx_request(port)) {
> -		init_waitqueue_head(&sport->dma_wait);
> -		sport->lpuart_dma_tx_use = true;
> -		temp = lpuart32_read(&sport->port, UARTBAUD);
> -		lpuart32_write(&sport->port, temp | UARTBAUD_TDMAE, UARTBAUD);
> -	} else {
> -		sport->lpuart_dma_tx_use = false;
> -	}
> +	lpuart_tx_dma_startup(port);
>  
>  	if (sport->lpuart_dma_rx_use) {
>  		/* RXWATER must be 0 */
> @@ -2581,20 +2587,7 @@ static int lpuart_resume(struct device *dev)
>  		}
>  	}
>  
> -	if (sport->dma_tx_chan && !lpuart_dma_tx_request(&sport->port)) {
> -		init_waitqueue_head(&sport->dma_wait);
> -		sport->lpuart_dma_tx_use = true;
> -		if (lpuart_is_32(sport)) {
> -			temp = lpuart32_read(&sport->port, UARTBAUD);
> -			lpuart32_write(&sport->port,
> -				       temp | UARTBAUD_TDMAE, UARTBAUD);
> -		} else {
> -			writeb(readb(sport->port.membase + UARTCR5) |
> -				UARTCR5_TDMAS, sport->port.membase + UARTCR5);
> -		}
> -	} else {
> -		sport->lpuart_dma_tx_use = false;
> -	}
> +	lpuart_tx_dma_startup(sport);
>  
>  	if (lpuart_is_32(sport)) {
>  		if (sport->lpuart_dma_rx_use) {
> -- 
> 2.21.0
> 

This patch breaks the build:

drivers/tty/serial/fsl_lpuart.c: In function lpuart_startup:
drivers/tty/serial/fsl_lpuart.c:1494:24: error: passing argument 1 of lpuart_tx_dma_startup from incompatible pointer type [-Werror=incompatible-pointer-types]
 1494 |  lpuart_tx_dma_startup(port);
      |                        ^~~~
      |                        |
      |                        struct uart_port *
drivers/tty/serial/fsl_lpuart.c:1438:55: note: expected struct lpuart_port * but argument is of type struct uart_port *
 1438 | static void lpuart_tx_dma_startup(struct lpuart_port *sport)
      |                                   ~~~~~~~~~~~~~~~~~~~~^~~~~
drivers/tty/serial/fsl_lpuart.c: In function lpuart32_startup:
drivers/tty/serial/fsl_lpuart.c:1537:24: error: passing argument 1 of lpuart_tx_dma_startup from incompatible pointer type [-Werror=incompatible-pointer-types]
 1537 |  lpuart_tx_dma_startup(port);
      |                        ^~~~
      |                        |
      |                        struct uart_port *
drivers/tty/serial/fsl_lpuart.c:1438:55: note: expected struct lpuart_port * but argument is of type struct uart_port *
 1438 | static void lpuart_tx_dma_startup(struct lpuart_port *sport)
      |                                   ~~~~~~~~~~~~~~~~~~~~^~~~~
cc1: some warnings being treated as errors


So I've stopped applying the series here.

Please fix up and resend the remaining ones.

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 06/24] tty: serial: fsl_lpuart: Drop unnecessary sg_set_buf() call
  2019-07-30 15:51   ` Greg Kroah-Hartman
@ 2019-07-31  2:08     ` Andrey Smirnov
  0 siblings, 0 replies; 31+ messages in thread
From: Andrey Smirnov @ 2019-07-31  2:08 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linux-serial, Stefan Agner, Chris Healy, Cory Tusar, Lucas Stach,
	Jiri Slaby, dl-linux-imx, linux-kernel

On Tue, Jul 30, 2019 at 8:51 AM Greg Kroah-Hartman
<gregkh@linuxfoundation.org> wrote:
>
> On Mon, Jul 29, 2019 at 12:52:08PM -0700, Andrey Smirnov wrote:
> > Sg_init_one() will already call sg_set_buf(), so another explicit call
> > right after it is unnecessary. Drop it.
> >
> > Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
> > Cc: Stefan Agner <stefan@agner.ch>
> > Cc: Bhuvanchandra DV <bhuvanchandra.dv@toradex.com>
> > Cc: Chris Healy <cphealy@gmail.com>
> > Cc: Cory Tusar <cory.tusar@zii.aero>
> > Cc: Lucas Stach <l.stach@pengutronix.de>
> > Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> > Cc: Jiri Slaby <jslaby@suse.com>
> > Cc: linux-imx@nxp.com
> > Cc: linux-serial@vger.kernel.org
> > Cc: linux-kernel@vger.kernel.org
> > ---
> >  drivers/tty/serial/fsl_lpuart.c | 1 -
> >  1 file changed, 1 deletion(-)
> >
> > diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
> > index 1b3f2a87e558..b600f591c8c2 100644
> > --- a/drivers/tty/serial/fsl_lpuart.c
> > +++ b/drivers/tty/serial/fsl_lpuart.c
> > @@ -1144,7 +1144,6 @@ static inline int lpuart_start_rx_dma(struct lpuart_port *sport)
> >               return -ENOMEM;
> >
> >       sg_init_one(&sport->rx_sgl, ring->buf, sport->rx_dma_rng_buf_len);
> > -     sg_set_buf(&sport->rx_sgl, ring->buf, sport->rx_dma_rng_buf_len);
> >       nent = dma_map_sg(sport->port.dev, &sport->rx_sgl, 1, DMA_FROM_DEVICE);
> >
> >       if (!nent) {
>
> This patch doesn't apply, is it already in the tree from someone else?
>

Yeah, looks like d9aa9ab4fe6b5c43b9ccb8a0811dadcfe40ea27f from your
tty tree already covered this and I didn't have it in my tree. Will
drop in v2.

Thanks,
Andrey Smirnov

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 19/24] tty: serial: fsl_lpuart: Introduce lpuart_tx_dma_startup()
  2019-07-30 15:56   ` Greg Kroah-Hartman
@ 2019-07-31  2:09     ` Andrey Smirnov
  0 siblings, 0 replies; 31+ messages in thread
From: Andrey Smirnov @ 2019-07-31  2:09 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linux-serial, Stefan Agner, Chris Healy, Cory Tusar, Lucas Stach,
	Jiri Slaby, dl-linux-imx, linux-kernel

On Tue, Jul 30, 2019 at 8:56 AM Greg Kroah-Hartman
<gregkh@linuxfoundation.org> wrote:
>
> On Mon, Jul 29, 2019 at 12:52:21PM -0700, Andrey Smirnov wrote:
> > Code configure DMA TX path in lpuart_startup(), lpuart32_startup() and
> > lpuart_resume() is doing exactly the same thing, so move it into a
> > standalone subroutine.
> >
> > Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
> > Cc: Stefan Agner <stefan@agner.ch>
> > Cc: Bhuvanchandra DV <bhuvanchandra.dv@toradex.com>
> > Cc: Chris Healy <cphealy@gmail.com>
> > Cc: Cory Tusar <cory.tusar@zii.aero>
> > Cc: Lucas Stach <l.stach@pengutronix.de>
> > Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> > Cc: Jiri Slaby <jslaby@suse.com>
> > Cc: linux-imx@nxp.com
> > Cc: linux-serial@vger.kernel.org
> > Cc: linux-kernel@vger.kernel.org
> > ---
> >  drivers/tty/serial/fsl_lpuart.c | 53 ++++++++++++++-------------------
> >  1 file changed, 23 insertions(+), 30 deletions(-)
> >
> > diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
> > index 2ad5750fe511..558acf29cbed 100644
> > --- a/drivers/tty/serial/fsl_lpuart.c
> > +++ b/drivers/tty/serial/fsl_lpuart.c
> > @@ -1434,6 +1434,26 @@ static void rx_dma_timer_init(struct lpuart_port *sport)
> >       add_timer(&sport->lpuart_timer);
> >  }
> >
> > +static void lpuart_tx_dma_startup(struct lpuart_port *sport)
> > +{
> > +     u32 uartbaud;
> > +
> > +     if (sport->dma_tx_chan && !lpuart_dma_tx_request(&sport->port)) {
> > +             init_waitqueue_head(&sport->dma_wait);
> > +             sport->lpuart_dma_tx_use = true;
> > +             if (lpuart_is_32(sport)) {
> > +                     uartbaud = lpuart32_read(&sport->port, UARTBAUD);
> > +                     lpuart32_write(&sport->port,
> > +                                    uartbaud | UARTBAUD_TDMAE, UARTBAUD);
> > +             } else {
> > +                     writeb(readb(sport->port.membase + UARTCR5) |
> > +                             UARTCR5_TDMAS, sport->port.membase + UARTCR5);
> > +             }
> > +     } else {
> > +             sport->lpuart_dma_tx_use = false;
> > +     }
> > +}
> > +
> >  static int lpuart_startup(struct uart_port *port)
> >  {
> >       struct lpuart_port *sport = container_of(port, struct lpuart_port, port);
> > @@ -1471,14 +1491,7 @@ static int lpuart_startup(struct uart_port *port)
> >               sport->lpuart_dma_rx_use = false;
> >       }
> >
> > -     if (sport->dma_tx_chan && !lpuart_dma_tx_request(port)) {
> > -             init_waitqueue_head(&sport->dma_wait);
> > -             sport->lpuart_dma_tx_use = true;
> > -             temp = readb(port->membase + UARTCR5);
> > -             writeb(temp | UARTCR5_TDMAS, port->membase + UARTCR5);
> > -     } else {
> > -             sport->lpuart_dma_tx_use = false;
> > -     }
> > +     lpuart_tx_dma_startup(port);
> >
> >       spin_unlock_irqrestore(&sport->port.lock, flags);
> >
> > @@ -1522,14 +1535,7 @@ static int lpuart32_startup(struct uart_port *port)
> >               sport->lpuart_dma_rx_use = false;
> >       }
> >
> > -     if (sport->dma_tx_chan && !lpuart_dma_tx_request(port)) {
> > -             init_waitqueue_head(&sport->dma_wait);
> > -             sport->lpuart_dma_tx_use = true;
> > -             temp = lpuart32_read(&sport->port, UARTBAUD);
> > -             lpuart32_write(&sport->port, temp | UARTBAUD_TDMAE, UARTBAUD);
> > -     } else {
> > -             sport->lpuart_dma_tx_use = false;
> > -     }
> > +     lpuart_tx_dma_startup(port);
> >
> >       if (sport->lpuart_dma_rx_use) {
> >               /* RXWATER must be 0 */
> > @@ -2581,20 +2587,7 @@ static int lpuart_resume(struct device *dev)
> >               }
> >       }
> >
> > -     if (sport->dma_tx_chan && !lpuart_dma_tx_request(&sport->port)) {
> > -             init_waitqueue_head(&sport->dma_wait);
> > -             sport->lpuart_dma_tx_use = true;
> > -             if (lpuart_is_32(sport)) {
> > -                     temp = lpuart32_read(&sport->port, UARTBAUD);
> > -                     lpuart32_write(&sport->port,
> > -                                    temp | UARTBAUD_TDMAE, UARTBAUD);
> > -             } else {
> > -                     writeb(readb(sport->port.membase + UARTCR5) |
> > -                             UARTCR5_TDMAS, sport->port.membase + UARTCR5);
> > -             }
> > -     } else {
> > -             sport->lpuart_dma_tx_use = false;
> > -     }
> > +     lpuart_tx_dma_startup(sport);
> >
> >       if (lpuart_is_32(sport)) {
> >               if (sport->lpuart_dma_rx_use) {
> > --
> > 2.21.0
> >
>
> This patch breaks the build:
>
> drivers/tty/serial/fsl_lpuart.c: In function lpuart_startup:
> drivers/tty/serial/fsl_lpuart.c:1494:24: error: passing argument 1 of lpuart_tx_dma_startup from incompatible pointer type [-Werror=incompatible-pointer-types]
>  1494 |  lpuart_tx_dma_startup(port);
>       |                        ^~~~
>       |                        |
>       |                        struct uart_port *
> drivers/tty/serial/fsl_lpuart.c:1438:55: note: expected struct lpuart_port * but argument is of type struct uart_port *
>  1438 | static void lpuart_tx_dma_startup(struct lpuart_port *sport)
>       |                                   ~~~~~~~~~~~~~~~~~~~~^~~~~
> drivers/tty/serial/fsl_lpuart.c: In function lpuart32_startup:
> drivers/tty/serial/fsl_lpuart.c:1537:24: error: passing argument 1 of lpuart_tx_dma_startup from incompatible pointer type [-Werror=incompatible-pointer-types]
>  1537 |  lpuart_tx_dma_startup(port);
>       |                        ^~~~
>       |                        |
>       |                        struct uart_port *
> drivers/tty/serial/fsl_lpuart.c:1438:55: note: expected struct lpuart_port * but argument is of type struct uart_port *
>  1438 | static void lpuart_tx_dma_startup(struct lpuart_port *sport)
>       |                                   ~~~~~~~~~~~~~~~~~~~~^~~~~
> cc1: some warnings being treated as errors
>
>
> So I've stopped applying the series here.
>
> Please fix up and resend the remaining ones.
>

Ugh, my bad, sorry about that. Will do in v2.

Thanks,
Andrey Smirnov

^ permalink raw reply	[flat|nested] 31+ messages in thread

end of thread, other threads:[~2019-07-31  2:09 UTC | newest]

Thread overview: 31+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-07-29 19:52 [PATCH 00/24] LPUART fixes and improvements Andrey Smirnov
2019-07-29 19:52 ` [PATCH 01/24] tty: serial: fsl_lpuart: fix framing error handling when using DMA Andrey Smirnov
2019-07-29 19:52 ` [PATCH 02/24] tty: serial: fsl_lpuart: flush receive FIFO after overruns Andrey Smirnov
2019-07-29 19:52 ` [PATCH 03/24] tty: serial: fsl_lpuart: Flush HW FIFOs in .flush_buffer Andrey Smirnov
2019-07-29 19:52 ` [PATCH 04/24] tty: serial: fsl_lpuart: Simplify RX/TX IRQ handlers Andrey Smirnov
2019-07-29 19:52 ` [PATCH 05/24] tty: serial: fsl_lpuart: Fix bogus indentation Andrey Smirnov
2019-07-29 19:52 ` [PATCH 06/24] tty: serial: fsl_lpuart: Drop unnecessary sg_set_buf() call Andrey Smirnov
2019-07-30 15:51   ` Greg Kroah-Hartman
2019-07-31  2:08     ` Andrey Smirnov
2019-07-29 19:52 ` [PATCH 07/24] tty: serial: fsl_lpuart: Drop unnecessary uart_write_wakeup() Andrey Smirnov
2019-07-29 19:52 ` [PATCH 08/24] tty: serial: fsl_lpuart: Fix issue in software flow control Andrey Smirnov
2019-07-29 19:52 ` [PATCH 09/24] tty: serial: fls_lpuart: Split shared TX IRQ handler into two Andrey Smirnov
2019-07-29 19:52 ` [PATCH 10/24] tty: serial: fsl_lpuart: Drop no-op bit opearation Andrey Smirnov
2019-07-29 19:52 ` [PATCH 11/24] tty: serial: fsl_lpuart: Drop unnecessary extra parenthesis Andrey Smirnov
2019-07-29 19:52 ` [PATCH 12/24] tty: serial: fsl_lpuart: Clear CSTOPB unconditionally Andrey Smirnov
2019-07-29 19:52 ` [PATCH 13/24] tty: serial: fsl_lpuart: Use appropriate lpuart32_* I/O funcs Andrey Smirnov
2019-07-29 19:52 ` [PATCH 14/24] tty: serial: fsl_lpuart: Introduce lpuart_wait_bit_set() Andrey Smirnov
2019-07-29 19:52 ` [PATCH 15/24] tty: serial: fsl_lpuart: Use cpu_relax() instead of barrier() Andrey Smirnov
2019-07-29 19:52 ` [PATCH 16/24] tty: serial: fsl_lpuart: Introduce lpuart_stopped_or_empty() Andrey Smirnov
2019-07-29 19:52 ` [PATCH 17/24] tty: serial: fsl_lpuart: Drop unnecessary lpuart*_stop_tx() Andrey Smirnov
2019-07-29 19:52 ` [PATCH 18/24] tty: serial: fsl_lpuart: Introduce lpuart_dma_shutdown() Andrey Smirnov
2019-07-29 19:52 ` [PATCH 19/24] tty: serial: fsl_lpuart: Introduce lpuart_tx_dma_startup() Andrey Smirnov
2019-07-30 15:56   ` Greg Kroah-Hartman
2019-07-31  2:09     ` Andrey Smirnov
2019-07-29 19:52 ` [PATCH 20/24] tty: serial: fsl_lpuart: Introduce lpuart_rx_dma_startup() Andrey Smirnov
2019-07-29 19:52 ` [PATCH 21/24] tty: serial: fsl_lpuart: Introduce lpuart32_configure() Andrey Smirnov
2019-07-29 19:52 ` [PATCH 22/24] tty: serial: fsl_lpuart: Introduce lpuart*_setup_watermark_enable() Andrey Smirnov
2019-07-29 19:52 ` [PATCH 23/24] tty: serial: fsl_lpuart: Don't enable TIE in .startup() or .resume() Andrey Smirnov
2019-07-29 19:52 ` [PATCH 24/24] tty: serial: fsl_lpuart: Ignore TX/RX interrupts if DMA is enabled Andrey Smirnov
2019-07-30 15:53 ` [PATCH 00/24] LPUART fixes and improvements Greg Kroah-Hartman
2019-07-30 15:54   ` Greg Kroah-Hartman

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).