tty: serial8250: add break handler quirk for tegra
Bibek Basu [Mon, 28 Apr 2014 05:29:24 +0000 (10:29 +0530)]
On tegra,after a break is issued, uart status register
generates FIFOE error rather than the next character
ready status. For that quirk is already present. Hook is added
for the quirk so that sysrq key combination works. This helps
in debugging soft hangs

Bug 1401397

Change-Id: I0131cfc986aba694ddc21d859685748843534611
Signed-off-by: Bibek Basu <bbasu@nvidia.com>
Reviewed-on: http://git-master/r/401535
(cherry picked from commit c72b366e010b5cfbac6541eb339a0324b863ff17)
Reviewed-on: http://git-master/r/406402
Reviewed-by: Matthew Pedro <mapedro@nvidia.com>
GVS: Gerrit_Virtual_Submit
Reviewed-by: Venkat Moganty <vmoganty@nvidia.com>

drivers/tty/serial/8250/8250_core.c
drivers/tty/serial/of_serial.c
include/linux/serial_8250.h

index 264054f..5914e7a 100644 (file)
@@ -1601,6 +1601,24 @@ static int serial8250_tegra_handle_irq(struct uart_port *port)
        return 1;
 }
 
+#ifdef CONFIG_ARCH_TEGRA
+void tegra_serial_handle_break(struct uart_port *p)
+{
+       unsigned int status, tmout = 10000;
+
+       do {
+               status = p->serial_in(p, UART_LSR);
+               if (status & (UART_LSR_FIFOE | UART_LSR_BRK_ERROR_BITS))
+                       status = p->serial_in(p, UART_RX);
+               else
+                       break;
+               if (--tmout == 0)
+                       break;
+               udelay(1);
+       } while (1);
+}
+#endif
+
 /*
  * These Exar UARTs have an extra interrupt indicator that could
  * fire for a few unimplemented interrupts.  One of which is a
@@ -2761,6 +2779,9 @@ static void serial8250_config_port(struct uart_port *port, int flags)
        if (port->type == PORT_TEGRA) {
                up->bugs |= UART_BUG_NOMSR;
                port->handle_irq = serial8250_tegra_handle_irq;
+#if defined CONFIG_ARCH_TEGRA
+               port->handle_break = tegra_serial_handle_break;
+#endif
        }
 
        if (port->type != PORT_UNKNOWN && flags & UART_CONFIG_IRQ)
index 39c7ea4..261c0ad 100644 (file)
@@ -29,28 +29,6 @@ struct of_serial_info {
        int line;
 };
 
-#ifdef CONFIG_ARCH_TEGRA
-void tegra_serial_handle_break(struct uart_port *p)
-{
-       unsigned int status, tmout = 10000;
-
-       do {
-               status = p->serial_in(p, UART_LSR);
-               if (status & (UART_LSR_FIFOE | UART_LSR_BRK_ERROR_BITS))
-                       status = p->serial_in(p, UART_RX);
-               else
-                       break;
-               if (--tmout == 0)
-                       break;
-               udelay(1);
-       } while (1);
-}
-#else
-static inline void tegra_serial_handle_break(struct uart_port *port)
-{
-}
-#endif
-
 /*
  * Fill a struct uart_port for a given device node
  */
index af47a8a..b4ddb42 100644 (file)
@@ -125,5 +125,12 @@ unsigned int serial8250_modem_status(struct uart_8250_port *up);
 extern void serial8250_set_isa_configurator(void (*v)
                                        (int port, struct uart_port *up,
                                                unsigned short *capabilities));
+#ifdef CONFIG_ARCH_TEGRA
+extern void tegra_serial_handle_break(struct uart_port *p);
+#else
+static inline void tegra_serial_handle_break(struct uart_port *port)
+{
+}
+#endif
 
 #endif