@@ -143,6 +143,7 @@ struct uart_8250_port {
unsigned char mcr_mask; /* mask of user bits */
unsigned char mcr_force; /* mask of forced bits */
unsigned char cur_iotype; /* Running I/O type */
+ unsigned char lsr_last; /* LSR of last IRQ event */
/*
* Some bits in registers are cleared on a read, so they must
@@ -1529,7 +1530,14 @@ static void serial8250_handle_port(struct uart_8250_port *up)
spin_lock_irqsave(&up->port.lock, flags);
- status = serial_inp(up, UART_LSR);
+ if (unlikely(up->lsr_last & UART_LSR_BI && up->bugs & UART_BUG_PPC)) {
+ up->lsr_last &= ~UART_LSR_BI;
+ serial_inp(up, UART_RX);
+ spin_unlock_irqrestore(&up->port.lock, flags);
+ return;
+ }
+
+ status = up->lsr_last = serial_inp(up, UART_LSR);
DEBUG_INTR("status = %x...", status);
@@ -1948,6 +1956,7 @@ static int serial8250_startup(struct uart_port *port)
up->capabilities = uart_config[up->port.type].flags;
up->mcr = 0;
+ up->bugs |= UART_KNOWN_BUGS;
if (up->port.iotype != up->cur_iotype)
set_io_from_upio(port);
@@ -49,6 +49,7 @@ struct serial8250_config {
#define UART_BUG_TXEN (1 << 1) /* UART has buggy TX IIR status */
#define UART_BUG_NOMSR (1 << 2) /* UART has buggy MSR status bits (Au1x00) */
#define UART_BUG_THRE (1 << 3) /* UART has buggy THRE reassertion */
+#define UART_BUG_PPC (1 << 4) /* UART has buggy PPC break IRQ storm */
#define PROBE_RSA (1 << 0)
#define PROBE_ANY (~0)
@@ -78,3 +79,22 @@ struct serial8250_config {
#else
#define ALPHA_KLUDGE_MCR 0
#endif
+
+/*
+ * The following UART bugs are currently dynamically detected and not
+ * required to be contingent on any particular compile time options.
+ */
+#define HAS_BUG_QUOT 0 /* assign UART_BUG_QUOT to enable */
+#define HAS_BUG_TXEN 0 /* assign UART_BUG_TXEN to enable */
+#define HAS_BUG_NOMSR 0 /* assign UART_BUG_NOMSR to enable */
+#define HAS_BUG_THRE 0 /* assign UART_BUG_THRE to enable */
+
+#ifdef CONFIG_SERIAL_8250_PPC_BUG
+#define HAS_BUG_PPC UART_BUG_PPC
+#else
+#define HAS_BUG_PPC 0
+#endif
+
+#define UART_KNOWN_BUGS (HAS_BUG_QUOT | HAS_BUG_TXEN | HAS_BUG_NOMSR | \
+ HAS_BUG_THRE | HAS_BUG_PPC)
+
@@ -70,6 +70,20 @@ config SERIAL_8250_CONSOLE
If unsure, say N.
+config SERIAL_8250_PPC_BUG
+ bool "Fix 8250/16550 to handle IRQ storm after receipt of a break"
+ depends on SERIAL_8250 && PPC32
+ ---help---
+ If you say Y here, additional checks will be added to handling of
+ interrupts on the serial ports which will prevent ill effects of
+ an interrupt storm triggered by a break on the serial line. Without
+ this enabled, a Sysrq via the serial console can be unusable on
+ some systems.
+
+ This is commonly observed on PPC32 MPC83xx/85xx/86xx based boards.
+
+ If unsure, say N.
+
config FIX_EARLYCON_MEM
bool
depends on X86