brcm2708: update to latest patches from RPi foundation
[openwrt/openwrt.git] / target / linux / brcm2708 / patches-4.19 / 950-0796-tty-amba-pl011-Add-un-throttle-support.patch
diff --git a/target/linux/brcm2708/patches-4.19/950-0796-tty-amba-pl011-Add-un-throttle-support.patch b/target/linux/brcm2708/patches-4.19/950-0796-tty-amba-pl011-Add-un-throttle-support.patch
new file mode 100644 (file)
index 0000000..0ab6cf2
--- /dev/null
@@ -0,0 +1,61 @@
+From d4f4b57c667141ca98711cfcb30ae2b8deb1a034 Mon Sep 17 00:00:00 2001
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Fri, 24 Jan 2020 11:38:28 +0000
+Subject: [PATCH] tty: amba-pl011: Add un/throttle support
+
+The PL011 driver lacks throttle and unthrottle methods. As a result,
+sending more data to the Pi than it can immediately sink while CRTSCTS
+is enabled causes a NULL pointer to be followed.
+
+Add a throttle handler that disables the RX interrupts, and an
+unthrottle handler that reenables them.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.org>
+---
+ drivers/tty/serial/amba-pl011.c | 28 ++++++++++++++++++++++++++++
+ 1 file changed, 28 insertions(+)
+
+--- a/drivers/tty/serial/amba-pl011.c
++++ b/drivers/tty/serial/amba-pl011.c
+@@ -1323,6 +1323,32 @@ static void pl011_start_tx(struct uart_p
+               pl011_start_tx_pio(uap);
+ }
++static void pl011_throttle(struct uart_port *port)
++{
++      struct uart_amba_port *uap =
++          container_of(port, struct uart_amba_port, port);
++      unsigned long flags;
++
++      spin_lock_irqsave(&uap->port.lock, flags);
++      uap->im &= ~(UART011_RTIM | UART011_RXIM);
++      pl011_write(uap->im, uap, REG_IMSC);
++      spin_unlock_irqrestore(&uap->port.lock, flags);
++}
++
++static void pl011_unthrottle(struct uart_port *port)
++{
++      struct uart_amba_port *uap =
++          container_of(port, struct uart_amba_port, port);
++      unsigned long flags;
++
++      spin_lock_irqsave(&uap->port.lock, flags);
++      uap->im |= UART011_RTIM;
++      if (!pl011_dma_rx_running(uap))
++          uap->im |= UART011_RXIM;
++      pl011_write(uap->im, uap, REG_IMSC);
++      spin_unlock_irqrestore(&uap->port.lock, flags);
++}
++
+ static void pl011_stop_rx(struct uart_port *port)
+ {
+       struct uart_amba_port *uap =
+@@ -2165,6 +2191,8 @@ static const struct uart_ops amba_pl011_
+       .stop_tx        = pl011_stop_tx,
+       .start_tx       = pl011_start_tx,
+       .stop_rx        = pl011_stop_rx,
++      .throttle       = pl011_throttle,
++      .unthrottle     = pl011_unthrottle,
+       .enable_ms      = pl011_enable_ms,
+       .break_ctl      = pl011_break_ctl,
+       .startup        = pl011_startup,