LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
* [PATCH 0/2] 8250_omap: Fix throttle callback
@ 2020-03-19 10:32 Vignesh Raghavendra
  2020-03-19 10:32 ` [PATCH 1/2] serial: 8250_port: Don't service RX FIFO if throttled Vignesh Raghavendra
  2020-03-19 10:32 ` [PATCH 2/2] serial: 8250: 8250_omap: Fix throttle to call stop_rx() Vignesh Raghavendra
  0 siblings, 2 replies; 3+ messages in thread
From: Vignesh Raghavendra @ 2020-03-19 10:32 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Vignesh Raghavendra, linux-serial, linux-kernel, Oliver Barta

This series tries to reimplement commit 2e9fe5391083 ("serial: 8250: Don't
service RX FIFO if interrupts are disabled") which was reverted by
commit 3f2640ed7be8 ("Revert "serial: 8250: Don't service RX FIFO if
interrupts are disabled") due a bug that caused error informations to be
missed.
Current series uses stop_rx() instead of relying on IIR bits

Vignesh Raghavendra (2):
  serial: 8250: Don't service RX FIFO if throttled
  serial: 8250: 8250_omap: Fix throttle to call stop_rx()

 drivers/tty/serial/8250/8250_omap.c |  5 ++---
 drivers/tty/serial/8250/8250_port.c | 16 +++++++++++++++-
 2 files changed, 17 insertions(+), 4 deletions(-)

-- 
2.25.2


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

* [PATCH 1/2] serial: 8250_port: Don't service RX FIFO if throttled
  2020-03-19 10:32 [PATCH 0/2] 8250_omap: Fix throttle callback Vignesh Raghavendra
@ 2020-03-19 10:32 ` Vignesh Raghavendra
  2020-03-19 10:32 ` [PATCH 2/2] serial: 8250: 8250_omap: Fix throttle to call stop_rx() Vignesh Raghavendra
  1 sibling, 0 replies; 3+ messages in thread
From: Vignesh Raghavendra @ 2020-03-19 10:32 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Vignesh Raghavendra, linux-serial, linux-kernel, Oliver Barta

When port's throttle callback is called, it should stop pushing any more
data into TTY buffer to avoid buffer overflow. This means driver has to
stop HW from receiving more data and assert the HW flow control. For
UARTs with auto HW flow control (such as 8250_omap) manual assertion of
flow control line is not possible and only way is to allow RX FIFO to
fill up, thus trigger auto HW flow control logic.

Therefore make sure that 8250 generic IRQ handler does not drain data
when port is stopped (i.e UART_LSR_DR is unset in read_status_mask). Not
servicing, RX FIFO would trigger auto HW flow control when FIFO
occupancy reaches preset threshold, thus halting RX.
Since, error conditions in UART_LSR register are cleared just by reading
the register, data has to be drained in case there are FIFO errors, else
error information will lost.

Signed-off-by: Vignesh Raghavendra <vigneshr@ti.com>
---
 drivers/tty/serial/8250/8250_port.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c
index 4440867b7d20..2f973280c34a 100644
--- a/drivers/tty/serial/8250/8250_port.c
+++ b/drivers/tty/serial/8250/8250_port.c
@@ -1883,6 +1883,7 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir)
 	unsigned char status;
 	unsigned long flags;
 	struct uart_8250_port *up = up_to_u8250p(port);
+	bool skip_rx = false;
 
 	if (iir & UART_IIR_NO_INT)
 		return 0;
@@ -1891,7 +1892,20 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir)
 
 	status = serial_port_in(port, UART_LSR);
 
-	if (status & (UART_LSR_DR | UART_LSR_BI)) {
+	/*
+	 * If port is stopped and there are no error conditions in the
+	 * FIFO, then don't drain the FIFO, as this may lead to TTY buffer
+	 * overflow. Not servicing, RX FIFO would trigger auto HW flow
+	 * control when FIFO occupancy reaches preset threshold, thus
+	 * halting RX. This only works when auto HW flow control is
+	 * available.
+	 */
+	if (!(status & (UART_LSR_FIFOE | UART_LSR_BRK_ERROR_BITS)) &&
+	    (port->status & (UPSTAT_AUTOCTS | UPSTAT_AUTORTS)) &&
+	    !(port->read_status_mask & UART_LSR_DR))
+		skip_rx = true;
+
+	if (status & (UART_LSR_DR | UART_LSR_BI) && !skip_rx) {
 		if (!up->dma || handle_rx_dma(up, iir))
 			status = serial8250_rx_chars(up, status);
 	}
-- 
2.25.2


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

* [PATCH 2/2] serial: 8250: 8250_omap: Fix throttle to call stop_rx()
  2020-03-19 10:32 [PATCH 0/2] 8250_omap: Fix throttle callback Vignesh Raghavendra
  2020-03-19 10:32 ` [PATCH 1/2] serial: 8250_port: Don't service RX FIFO if throttled Vignesh Raghavendra
@ 2020-03-19 10:32 ` Vignesh Raghavendra
  1 sibling, 0 replies; 3+ messages in thread
From: Vignesh Raghavendra @ 2020-03-19 10:32 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: Vignesh Raghavendra, linux-serial, linux-kernel, Oliver Barta

Call stop_rx() to halt reception when throttle is requested. Update
unthrottle callback to restart reception.

Signed-off-by: Vignesh Raghavendra <vigneshr@ti.com>
---
 drivers/tty/serial/8250/8250_omap.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c
index 449f1519e70f..82fca112409c 100644
--- a/drivers/tty/serial/8250/8250_omap.c
+++ b/drivers/tty/serial/8250/8250_omap.c
@@ -699,14 +699,12 @@ static void omap_8250_shutdown(struct uart_port *port)
 static void omap_8250_throttle(struct uart_port *port)
 {
 	struct omap8250_priv *priv = port->private_data;
-	struct uart_8250_port *up = up_to_u8250p(port);
 	unsigned long flags;
 
 	pm_runtime_get_sync(port->dev);
 
 	spin_lock_irqsave(&port->lock, flags);
-	up->ier &= ~(UART_IER_RLSI | UART_IER_RDI);
-	serial_out(up, UART_IER, up->ier);
+	port->ops->stop_rx(port);
 	priv->throttled = true;
 	spin_unlock_irqrestore(&port->lock, flags);
 
@@ -727,6 +725,7 @@ static void omap_8250_unthrottle(struct uart_port *port)
 	if (up->dma)
 		up->dma->rx_dma(up);
 	up->ier |= UART_IER_RLSI | UART_IER_RDI;
+	port->read_status_mask |= UART_LSR_DR;
 	serial_out(up, UART_IER, up->ier);
 	spin_unlock_irqrestore(&port->lock, flags);
 
-- 
2.25.2


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

end of thread, other threads:[~2020-03-19 10:32 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-03-19 10:32 [PATCH 0/2] 8250_omap: Fix throttle callback Vignesh Raghavendra
2020-03-19 10:32 ` [PATCH 1/2] serial: 8250_port: Don't service RX FIFO if throttled Vignesh Raghavendra
2020-03-19 10:32 ` [PATCH 2/2] serial: 8250: 8250_omap: Fix throttle to call stop_rx() Vignesh Raghavendra

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).