linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] 8250: add workaround for MPC8[356]xx UART break IRQ storm
@ 2010-02-26 19:25 Paul Gortmaker
  2010-02-26 19:42 ` Kumar Gala
                   ` (2 more replies)
  0 siblings, 3 replies; 11+ messages in thread
From: Paul Gortmaker @ 2010-02-26 19:25 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: linux-serial

Sending a break on the SOC UARTs found in some MPC83xx/85xx/86xx
chips seems to cause a short lived IRQ storm (/proc/interrupts
typically shows somewhere between 300 and 1500 events).  Unfortunately
this renders SysRQ over the serial console completely inoperable.
Testing with obvious things like ACKing the event doesn't seem to
change anything vs. a completely dumb approach of just ignoring
it and waiting for it to stop, so that is what is implemented here.

Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
---

This is a refresh of a patch I'd done earlier -- I've tried to make
the bug support as generic as possible to minimize having board
specific ifdef crap in 8250.c -- any suggestions on how to further
improve it are welcome.

 drivers/serial/8250.c      |    6 ++++++
 drivers/serial/8250.h      |   20 ++++++++++++++++++++
 drivers/serial/Kconfig     |   14 ++++++++++++++
 include/linux/serial_reg.h |    2 ++
 4 files changed, 42 insertions(+), 0 deletions(-)

diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index e9b15c3..850b0e9 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -1531,6 +1531,11 @@ static void serial8250_handle_port(struct uart_8250_port *up)
 
 	status = serial_inp(up, UART_LSR);
 
+	if ((up->bugs & UART_BUG_PPC) && (status == UART_LSR_RFE_ERROR_BITS)) {
+		spin_unlock_irqrestore(&up->port.lock, flags);
+		return;
+	}
+
 	DEBUG_INTR("status = %x...", status);
 
 	if (status & (UART_LSR_DR | UART_LSR_BI))
@@ -1948,6 +1953,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);
diff --git a/drivers/serial/8250.h b/drivers/serial/8250.h
index 6e19ea3..2074ce1 100644
--- a/drivers/serial/8250.h
+++ b/drivers/serial/8250.h
@@ -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)
+
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 9ff47db..e01a411 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -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, addional checks will be added in the 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
diff --git a/include/linux/serial_reg.h b/include/linux/serial_reg.h
index cf9327c..010174f 100644
--- a/include/linux/serial_reg.h
+++ b/include/linux/serial_reg.h
@@ -111,6 +111,7 @@
 #define UART_MCR_DTR		0x01 /* DTR complement */
 
 #define UART_LSR	5	/* In:  Line Status Register */
+#define UART_LSR_RFE		0x80 /* Rx FIFO Error (BE, FE, or PE) */
 #define UART_LSR_TEMT		0x40 /* Transmitter empty */
 #define UART_LSR_THRE		0x20 /* Transmit-hold-register empty */
 #define UART_LSR_BI		0x10 /* Break interrupt indicator */
@@ -119,6 +120,7 @@
 #define UART_LSR_OE		0x02 /* Overrun error indicator */
 #define UART_LSR_DR		0x01 /* Receiver data ready */
 #define UART_LSR_BRK_ERROR_BITS	0x1E /* BI, FE, PE, OE bits */
+#define UART_LSR_RFE_ERROR_BITS	0xF1 /* RFE, TEMT, THRE, BI, DR bits */
 
 #define UART_MSR	6	/* In:  Modem Status Register */
 #define UART_MSR_DCD		0x80 /* Data Carrier Detect */
-- 
1.6.5.2

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

* Re: [PATCH] 8250: add workaround for MPC8[356]xx UART break IRQ storm
  2010-02-26 19:25 [PATCH] 8250: add workaround for MPC8[356]xx UART break IRQ storm Paul Gortmaker
@ 2010-02-26 19:42 ` Kumar Gala
  2010-02-26 20:21   ` Paul Gortmaker
  2010-02-26 20:23   ` Scott Wood
  2010-03-01 23:03 ` vb
  2011-11-24  8:14 ` Kumar Gala
  2 siblings, 2 replies; 11+ messages in thread
From: Kumar Gala @ 2010-02-26 19:42 UTC (permalink / raw)
  To: Paul Gortmaker; +Cc: linuxppc-dev, linux-serial


On Feb 26, 2010, at 1:25 PM, Paul Gortmaker wrote:

> Sending a break on the SOC UARTs found in some MPC83xx/85xx/86xx
> chips seems to cause a short lived IRQ storm (/proc/interrupts
> typically shows somewhere between 300 and 1500 events).  Unfortunately
> this renders SysRQ over the serial console completely inoperable.
> Testing with obvious things like ACKing the event doesn't seem to
> change anything vs. a completely dumb approach of just ignoring
> it and waiting for it to stop, so that is what is implemented here.
>=20
> Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
> ---
>=20
> This is a refresh of a patch I'd done earlier -- I've tried to make
> the bug support as generic as possible to minimize having board
> specific ifdef crap in 8250.c -- any suggestions on how to further
> improve it are welcome.
>=20
> drivers/serial/8250.c      |    6 ++++++
> drivers/serial/8250.h      |   20 ++++++++++++++++++++
> drivers/serial/Kconfig     |   14 ++++++++++++++
> include/linux/serial_reg.h |    2 ++
> 4 files changed, 42 insertions(+), 0 deletions(-)
>=20
> diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
> index e9b15c3..850b0e9 100644
> --- a/drivers/serial/8250.c
> +++ b/drivers/serial/8250.c
> @@ -1531,6 +1531,11 @@ static void serial8250_handle_port(struct =
uart_8250_port *up)
>=20
> 	status =3D serial_inp(up, UART_LSR);
>=20
> +	if ((up->bugs & UART_BUG_PPC) && (status =3D=3D =
UART_LSR_RFE_ERROR_BITS)) {
> +		spin_unlock_irqrestore(&up->port.lock, flags);
> +		return;
> +	}
> +
> 	DEBUG_INTR("status =3D %x...", status);
>=20
> 	if (status & (UART_LSR_DR | UART_LSR_BI))
> @@ -1948,6 +1953,7 @@ static int serial8250_startup(struct uart_port =
*port)
>=20
> 	up->capabilities =3D uart_config[up->port.type].flags;
> 	up->mcr =3D 0;
> +	up->bugs |=3D UART_KNOWN_BUGS;
>=20
> 	if (up->port.iotype !=3D up->cur_iotype)
> 		set_io_from_upio(port);
> diff --git a/drivers/serial/8250.h b/drivers/serial/8250.h
> index 6e19ea3..2074ce1 100644
> --- a/drivers/serial/8250.h
> +++ b/drivers/serial/8250.h
> @@ -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 */
>=20
> #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)
> +
> diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
> index 9ff47db..e01a411 100644
> --- a/drivers/serial/Kconfig
> +++ b/drivers/serial/Kconfig
> @@ -70,6 +70,20 @@ config SERIAL_8250_CONSOLE
>=20
> 	  If unsure, say N.
>=20
> +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, addional checks will be added in the =
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.
> +

is there harm caused if we have SERIAL_8250_PPC_BUG set and dont need =
it?

- k=

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

* Re: [PATCH] 8250: add workaround for MPC8[356]xx UART break IRQ storm
  2010-02-26 19:42 ` Kumar Gala
@ 2010-02-26 20:21   ` Paul Gortmaker
  2010-02-26 20:23   ` Scott Wood
  1 sibling, 0 replies; 11+ messages in thread
From: Paul Gortmaker @ 2010-02-26 20:21 UTC (permalink / raw)
  To: Kumar Gala; +Cc: linuxppc-dev, linux-serial

On 10-02-26 02:42 PM, Kumar Gala wrote:
> 
> On Feb 26, 2010, at 1:25 PM, Paul Gortmaker wrote:
> 

[...]

>>
>> +	if ((up->bugs&  UART_BUG_PPC)&&  (status == UART_LSR_RFE_ERROR_BITS)) {
>> +		spin_unlock_irqrestore(&up->port.lock, flags);
>> +		return;
>> +	}
>> +

[...]

> 
> is there harm caused if we have SERIAL_8250_PPC_BUG set and dont need it?

In theory, no -- strip away all the window dressing and we are
left with the above change.  So, you'd have to have some UART
implementation that was setting those bits and still relying
on its interrupt event to be processed normally.  But since
there are so many different 8250 implementations out there,
I was being cautious and taking the absolute safe approach.

P.

> 
> - k

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

* Re: [PATCH] 8250: add workaround for MPC8[356]xx UART break IRQ storm
  2010-02-26 19:42 ` Kumar Gala
  2010-02-26 20:21   ` Paul Gortmaker
@ 2010-02-26 20:23   ` Scott Wood
  2010-03-01 21:23     ` Paul Gortmaker
  1 sibling, 1 reply; 11+ messages in thread
From: Scott Wood @ 2010-02-26 20:23 UTC (permalink / raw)
  To: Kumar Gala; +Cc: Paul Gortmaker, linuxppc-dev, linux-serial

On Fri, Feb 26, 2010 at 01:42:39PM -0600, Kumar Gala wrote:
> 
> On Feb 26, 2010, at 1:25 PM, Paul Gortmaker wrote:
> 
> > Sending a break on the SOC UARTs found in some MPC83xx/85xx/86xx
> > chips seems to cause a short lived IRQ storm (/proc/interrupts
> > typically shows somewhere between 300 and 1500 events).  Unfortunately
> > this renders SysRQ over the serial console completely inoperable.
> > Testing with obvious things like ACKing the event doesn't seem to
> > change anything vs. a completely dumb approach of just ignoring
> > it and waiting for it to stop, so that is what is implemented here.
> > 
> > Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
> > ---
> > 
> > This is a refresh of a patch I'd done earlier -- I've tried to make
> > the bug support as generic as possible to minimize having board
> > specific ifdef crap in 8250.c -- any suggestions on how to further
> > improve it are welcome.
> > 
> > drivers/serial/8250.c      |    6 ++++++
> > drivers/serial/8250.h      |   20 ++++++++++++++++++++
> > drivers/serial/Kconfig     |   14 ++++++++++++++
> > include/linux/serial_reg.h |    2 ++
> > 4 files changed, 42 insertions(+), 0 deletions(-)
> > 
> > diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
> > index e9b15c3..850b0e9 100644
> > --- a/drivers/serial/8250.c
> > +++ b/drivers/serial/8250.c
> > @@ -1531,6 +1531,11 @@ static void serial8250_handle_port(struct uart_8250_port *up)
> > 
> > 	status = serial_inp(up, UART_LSR);
> > 
> > +	if ((up->bugs & UART_BUG_PPC) && (status == UART_LSR_RFE_ERROR_BITS)) {
> > +		spin_unlock_irqrestore(&up->port.lock, flags);
> > +		return;
> > +	}

Will LSR always be 0xf1 when this problem hits?  At least the transmit bits
shouldn't be relevant.

This has been listed as an erratum in some of the newer chips (e.g.
mpc8568).

The suggested as workaround is to, upon seeing a break condition:
- read RBR
- delay at least one character period
- read RBR again

If I'm interpreting this correctly, it could be implemented by doing the
normal break handling on the first interrupt, plus setting a flag so that the
next interrupt simply reads RBR, clears the flag, and returns, without ever
reading LSR.

-Scott

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

* Re: [PATCH] 8250: add workaround for MPC8[356]xx UART break IRQ storm
  2010-02-26 20:23   ` Scott Wood
@ 2010-03-01 21:23     ` Paul Gortmaker
  0 siblings, 0 replies; 11+ messages in thread
From: Paul Gortmaker @ 2010-03-01 21:23 UTC (permalink / raw)
  To: Scott Wood; +Cc: linuxppc-dev, linux-serial

[Re: [PATCH] 8250: add workaround for MPC8[356]xx UART break IRQ storm] On 26/02/2010 (Fri 14:23) Scott Wood wrote:

> On Fri, Feb 26, 2010 at 01:42:39PM -0600, Kumar Gala wrote:
> > 
> > On Feb 26, 2010, at 1:25 PM, Paul Gortmaker wrote:
> > 
> > > Sending a break on the SOC UARTs found in some MPC83xx/85xx/86xx
> > > chips seems to cause a short lived IRQ storm (/proc/interrupts
> > > typically shows somewhere between 300 and 1500 events).  Unfortunately
> > > this renders SysRQ over the serial console completely inoperable.
> > > Testing with obvious things like ACKing the event doesn't seem to
> > > change anything vs. a completely dumb approach of just ignoring
> > > it and waiting for it to stop, so that is what is implemented here.
> > > 
> > > Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
> > > ---
> > > 
> > > This is a refresh of a patch I'd done earlier -- I've tried to make
> > > the bug support as generic as possible to minimize having board
> > > specific ifdef crap in 8250.c -- any suggestions on how to further
> > > improve it are welcome.
> > > 
> > > drivers/serial/8250.c      |    6 ++++++
> > > drivers/serial/8250.h      |   20 ++++++++++++++++++++
> > > drivers/serial/Kconfig     |   14 ++++++++++++++
> > > include/linux/serial_reg.h |    2 ++
> > > 4 files changed, 42 insertions(+), 0 deletions(-)
> > > 
> > > diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
> > > index e9b15c3..850b0e9 100644
> > > --- a/drivers/serial/8250.c
> > > +++ b/drivers/serial/8250.c
> > > @@ -1531,6 +1531,11 @@ static void serial8250_handle_port(struct uart_8250_port *up)
> > > 
> > > 	status = serial_inp(up, UART_LSR);
> > > 
> > > +	if ((up->bugs & UART_BUG_PPC) && (status == UART_LSR_RFE_ERROR_BITS)) {
> > > +		spin_unlock_irqrestore(&up->port.lock, flags);
> > > +		return;
> > > +	}
> 
> Will LSR always be 0xf1 when this problem hits?  At least the transmit bits
> shouldn't be relevant.

It was, based only on the emperical data I collected.  I agree that
the Tx data shouldn't really matter.  But it is a moot point now that
I know about the errata workaround...

> 
> This has been listed as an erratum in some of the newer chips (e.g.
> mpc8568).
> 
> The suggested as workaround is to, upon seeing a break condition:
> - read RBR
> - delay at least one character period
> - read RBR again
> 
> If I'm interpreting this correctly, it could be implemented by doing the
> normal break handling on the first interrupt, plus setting a flag so that the
> next interrupt simply reads RBR, clears the flag, and returns, without ever
> reading LSR.

Thanks for the info -- that makes for a better fix (in that the storm
gets averted completely) so your interpretation is on the money.

The only question that remains is whether we:
(a) deploy it everywhere, or
(b) leave it as a config option and update Kconfig with select on
   the boards of interest, or
(c) implement dynamic enablement based on something like adding a
   detect_arch_bugs() to 8250.c and then for powerpc, we iterate over
   of_flat_dt_is_compatible(root, blacklist[i]) looking for a match.

Paul.

 From c77b1600975b5fc596b2baebf43e28b66969181f Mon Sep 17 00:00:00 2001
From: Paul Gortmaker <paul.gortmaker@windriver.com>
Date: Fri, 26 Feb 2010 10:29:46 -0500
Subject: [PATCH] 8250: add workaround for MPC8[356]xx UART break IRQ storm

Sending a break on the SOC UARTs found in some MPC83xx/85xx/86xx
chips seems to cause a short lived IRQ storm (/proc/interrupts
typically shows somewhere between 300 and 1500 events).  Unfortunately
this renders SysRQ over the serial console completely inoperable.

The suggested workaround in the errata is to read the Rx register,
wait one character period, and then read the Rx register again.
We achieve this by tracking the old LSR value, and on the subsequent
interrupt event after a break, we don't read LSR, instead we just
read the RBR again and return immediately.

Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
---
 drivers/serial/8250.c  |   11 ++++++++++-
 drivers/serial/8250.h  |   20 ++++++++++++++++++++
 drivers/serial/Kconfig |   14 ++++++++++++++
 3 files changed, 44 insertions(+), 1 deletions(-)

diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index e9b15c3..645cf9b 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -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);
diff --git a/drivers/serial/8250.h b/drivers/serial/8250.h
index 6e19ea3..2074ce1 100644
--- a/drivers/serial/8250.h
+++ b/drivers/serial/8250.h
@@ -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)
+
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 9ff47db..5e58a1a 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -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
-- 
1.6.5.2

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

* Re: [PATCH] 8250: add workaround for MPC8[356]xx UART break IRQ storm
  2010-02-26 19:25 [PATCH] 8250: add workaround for MPC8[356]xx UART break IRQ storm Paul Gortmaker
  2010-02-26 19:42 ` Kumar Gala
@ 2010-03-01 23:03 ` vb
  2010-03-02 16:27   ` Paul Gortmaker
  2011-11-24  8:14 ` Kumar Gala
  2 siblings, 1 reply; 11+ messages in thread
From: vb @ 2010-03-01 23:03 UTC (permalink / raw)
  To: Paul Gortmaker; +Cc: linuxppc-dev, linux-serial

sounds very much like this issue:

http://linux.derkeiler.com/Mailing-Lists/Kernel/2010-02/msg09470.html

(interrupt storm on the second port which is hit with breaks).

It's not the uart driver problem per se, the below fixes it:

*** linux/drivers/serial/serial_core.c#1        Wed Feb 24 17:46:22 2010
---  linux/drivers/serial/serial_core.c#2        Mon Mar  1 15:00:29 2010
***************
*** 622,632 ****
        struct uart_port *port =3D state->port;

        if (I_IXOFF(tty)) {
                if (port->x_char)
                        port->x_char =3D 0;
!               else
                        uart_send_xchar(tty, START_CHAR(tty));
        }

        if (tty->termios->c_cflag & CRTSCTS)
                uart_set_mctrl(port, TIOCM_RTS);
--- 622,632 ----
        struct uart_port *port =3D state->port;

        if (I_IXOFF(tty)) {
                if (port->x_char)
                        port->x_char =3D 0;
!               else if (!(tty->flags & (1 << TTY_IO_ERROR)))
                        uart_send_xchar(tty, START_CHAR(tty));
        }

        if (tty->termios->c_cflag & CRTSCTS)
                uart_set_mctrl(port, TIOCM_RTS);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^=
^^^^^^^^^^^^^^^^^^^

I did not get to trying to submit it, but it sure gets rid o the storm.

cheers,
/vb

On Fri, Feb 26, 2010 at 11:25 AM, Paul Gortmaker
<paul.gortmaker@windriver.com> wrote:
> Sending a break on the SOC UARTs found in some MPC83xx/85xx/86xx
> chips seems to cause a short lived IRQ storm (/proc/interrupts
> typically shows somewhere between 300 and 1500 events). =A0Unfortunately
> this renders SysRQ over the serial console completely inoperable.
> Testing with obvious things like ACKing the event doesn't seem to
> change anything vs. a completely dumb approach of just ignoring
> it and waiting for it to stop, so that is what is implemented here.
>
> Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
> ---
>
> This is a refresh of a patch I'd done earlier -- I've tried to make
> the bug support as generic as possible to minimize having board
> specific ifdef crap in 8250.c -- any suggestions on how to further
> improve it are welcome.
>
> =A0drivers/serial/8250.c =A0 =A0 =A0| =A0 =A06 ++++++
> =A0drivers/serial/8250.h =A0 =A0 =A0| =A0 20 ++++++++++++++++++++
> =A0drivers/serial/Kconfig =A0 =A0 | =A0 14 ++++++++++++++
> =A0include/linux/serial_reg.h | =A0 =A02 ++
> =A04 files changed, 42 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
> index e9b15c3..850b0e9 100644
> --- a/drivers/serial/8250.c
> +++ b/drivers/serial/8250.c
> @@ -1531,6 +1531,11 @@ static void serial8250_handle_port(struct uart_825=
0_port *up)
>
> =A0 =A0 =A0 =A0status =3D serial_inp(up, UART_LSR);
>
> + =A0 =A0 =A0 if ((up->bugs & UART_BUG_PPC) && (status =3D=3D UART_LSR_RF=
E_ERROR_BITS)) {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 spin_unlock_irqrestore(&up->port.lock, flag=
s);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 return;
> + =A0 =A0 =A0 }
> +
> =A0 =A0 =A0 =A0DEBUG_INTR("status =3D %x...", status);
>
> =A0 =A0 =A0 =A0if (status & (UART_LSR_DR | UART_LSR_BI))
> @@ -1948,6 +1953,7 @@ static int serial8250_startup(struct uart_port *por=
t)
>
> =A0 =A0 =A0 =A0up->capabilities =3D uart_config[up->port.type].flags;
> =A0 =A0 =A0 =A0up->mcr =3D 0;
> + =A0 =A0 =A0 up->bugs |=3D UART_KNOWN_BUGS;
>
> =A0 =A0 =A0 =A0if (up->port.iotype !=3D up->cur_iotype)
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0set_io_from_upio(port);
> diff --git a/drivers/serial/8250.h b/drivers/serial/8250.h
> index 6e19ea3..2074ce1 100644
> --- a/drivers/serial/8250.h
> +++ b/drivers/serial/8250.h
> @@ -49,6 +49,7 @@ struct serial8250_config {
> =A0#define UART_BUG_TXEN =A0(1 << 1) =A0 =A0 =A0 =A0/* UART has buggy TX =
IIR status */
> =A0#define UART_BUG_NOMSR (1 << 2) =A0 =A0 =A0 =A0/* UART has buggy MSR s=
tatus bits (Au1x00) */
> =A0#define UART_BUG_THRE =A0(1 << 3) =A0 =A0 =A0 =A0/* UART has buggy THR=
E reassertion */
> +#define UART_BUG_PPC =A0 (1 << 4) =A0 =A0 =A0 =A0/* UART has buggy PPC b=
reak IRQ storm */
>
> =A0#define PROBE_RSA =A0 =A0 =A0(1 << 0)
> =A0#define PROBE_ANY =A0 =A0 =A0(~0)
> @@ -78,3 +79,22 @@ struct serial8250_config {
> =A0#else
> =A0#define ALPHA_KLUDGE_MCR 0
> =A0#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 =A0 0 =A0 =A0 =A0 /* assign UART_BUG_QUOT to enable=
 */
> +#define HAS_BUG_TXEN =A0 0 =A0 =A0 =A0 /* assign UART_BUG_TXEN to enable=
 */
> +#define HAS_BUG_NOMSR =A00 =A0 =A0 =A0 /* assign UART_BUG_NOMSR to enabl=
e */
> +#define HAS_BUG_THRE =A0 0 =A0 =A0 =A0 /* assign UART_BUG_THRE to enable=
 */
> +
> +#ifdef CONFIG_SERIAL_8250_PPC_BUG
> +#define HAS_BUG_PPC =A0 =A0UART_BUG_PPC
> +#else
> +#define HAS_BUG_PPC =A0 =A00
> +#endif
> +
> +#define UART_KNOWN_BUGS (HAS_BUG_QUOT | HAS_BUG_TXEN | HAS_BUG_NOMSR | \
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 HAS_BUG_THRE | HAS_BUG_PPC)
> +
> diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
> index 9ff47db..e01a411 100644
> --- a/drivers/serial/Kconfig
> +++ b/drivers/serial/Kconfig
> @@ -70,6 +70,20 @@ config SERIAL_8250_CONSOLE
>
> =A0 =A0 =A0 =A0 =A0If unsure, say N.
>
> +config SERIAL_8250_PPC_BUG
> + =A0 =A0 =A0 bool "Fix 8250/16550 to handle IRQ storm after receipt of a=
 break"
> + =A0 =A0 =A0 depends on SERIAL_8250 && PPC32
> + =A0 =A0 =A0 ---help---
> + =A0 =A0 =A0 =A0 If you say Y here, addional checks will be added in the=
 handling of
> + =A0 =A0 =A0 =A0 interrupts on the serial ports which will prevent ill e=
ffects of
> + =A0 =A0 =A0 =A0 an interrupt storm triggered by a break on the serial l=
ine. Without
> + =A0 =A0 =A0 =A0 this enabled, a Sysrq via the serial console can be unu=
sable on
> + =A0 =A0 =A0 =A0 some systems.
> +
> + =A0 =A0 =A0 =A0 This is commonly observed on PPC32 MPC83xx/85xx/86xx ba=
sed boards.
> +
> + =A0 =A0 =A0 =A0 If unsure, say N.
> +
> =A0config FIX_EARLYCON_MEM
> =A0 =A0 =A0 =A0bool
> =A0 =A0 =A0 =A0depends on X86
> diff --git a/include/linux/serial_reg.h b/include/linux/serial_reg.h
> index cf9327c..010174f 100644
> --- a/include/linux/serial_reg.h
> +++ b/include/linux/serial_reg.h
> @@ -111,6 +111,7 @@
> =A0#define UART_MCR_DTR =A0 =A0 =A0 =A0 =A0 0x01 /* DTR complement */
>
> =A0#define UART_LSR =A0 =A0 =A0 5 =A0 =A0 =A0 /* In: =A0Line Status Regis=
ter */
> +#define UART_LSR_RFE =A0 =A0 =A0 =A0 =A0 0x80 /* Rx FIFO Error (BE, FE, =
or PE) */
> =A0#define UART_LSR_TEMT =A0 =A0 =A0 =A0 =A00x40 /* Transmitter empty */
> =A0#define UART_LSR_THRE =A0 =A0 =A0 =A0 =A00x20 /* Transmit-hold-registe=
r empty */
> =A0#define UART_LSR_BI =A0 =A0 =A0 =A0 =A0 =A00x10 /* Break interrupt ind=
icator */
> @@ -119,6 +120,7 @@
> =A0#define UART_LSR_OE =A0 =A0 =A0 =A0 =A0 =A00x02 /* Overrun error indic=
ator */
> =A0#define UART_LSR_DR =A0 =A0 =A0 =A0 =A0 =A00x01 /* Receiver data ready=
 */
> =A0#define UART_LSR_BRK_ERROR_BITS =A0 =A0 =A0 =A00x1E /* BI, FE, PE, OE =
bits */
> +#define UART_LSR_RFE_ERROR_BITS =A0 =A0 =A0 =A00xF1 /* RFE, TEMT, THRE, =
BI, DR bits */
>
> =A0#define UART_MSR =A0 =A0 =A0 6 =A0 =A0 =A0 /* In: =A0Modem Status Regi=
ster */
> =A0#define UART_MSR_DCD =A0 =A0 =A0 =A0 =A0 0x80 /* Data Carrier Detect *=
/
> --
> 1.6.5.2
>
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev
>

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

* Re: [PATCH] 8250: add workaround for MPC8[356]xx UART break IRQ storm
  2010-03-01 23:03 ` vb
@ 2010-03-02 16:27   ` Paul Gortmaker
  2010-03-02 21:21     ` vb
  0 siblings, 1 reply; 11+ messages in thread
From: Paul Gortmaker @ 2010-03-02 16:27 UTC (permalink / raw)
  To: vb; +Cc: linuxppc-dev, linux-serial

On 10-03-01 06:03 PM, vb@vsbe.com wrote:
> sounds very much like this issue:
> 
> http://linux.derkeiler.com/Mailing-Lists/Kernel/2010-02/msg09470.html

Thanks for the link.

> 
> (interrupt storm on the second port which is hit with breaks).
> 
> It's not the uart driver problem per se, the below fixes it:

Actually, it is a uart *hardware* problem -- see in this same
thread where Scott Wood described an errata, and when I
implemented his interpretation of what the fix should look
like, things just worked.  You might want to try out that patch
and see if it helps you, since from the link above, I see you
are also on a powerpc board.

Paul.

> 
> *** linux/drivers/serial/serial_core.c#1        Wed Feb 24 17:46:22 2010
> ---  linux/drivers/serial/serial_core.c#2        Mon Mar  1 15:00:29 2010
> ***************
> *** 622,632 ****
>          struct uart_port *port = state->port;
> 
>          if (I_IXOFF(tty)) {
>                  if (port->x_char)
>                          port->x_char = 0;
> !               else
>                          uart_send_xchar(tty, START_CHAR(tty));
>          }
> 
>          if (tty->termios->c_cflag&  CRTSCTS)
>                  uart_set_mctrl(port, TIOCM_RTS);
> --- 622,632 ----
>          struct uart_port *port = state->port;
> 
>          if (I_IXOFF(tty)) {
>                  if (port->x_char)
>                          port->x_char = 0;
> !               else if (!(tty->flags&  (1<<  TTY_IO_ERROR)))
>                          uart_send_xchar(tty, START_CHAR(tty));
>          }
> 
>          if (tty->termios->c_cflag&  CRTSCTS)
>                  uart_set_mctrl(port, TIOCM_RTS);
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> 
> I did not get to trying to submit it, but it sure gets rid o the storm.
> 
> cheers,
> /vb
> 
> On Fri, Feb 26, 2010 at 11:25 AM, Paul Gortmaker
> <paul.gortmaker@windriver.com>  wrote:
>> Sending a break on the SOC UARTs found in some MPC83xx/85xx/86xx
>> chips seems to cause a short lived IRQ storm (/proc/interrupts
>> typically shows somewhere between 300 and 1500 events).  Unfortunately
>> this renders SysRQ over the serial console completely inoperable.
>> Testing with obvious things like ACKing the event doesn't seem to
>> change anything vs. a completely dumb approach of just ignoring
>> it and waiting for it to stop, so that is what is implemented here.
>>
>> Signed-off-by: Paul Gortmaker<paul.gortmaker@windriver.com>
>> ---
>>
>> This is a refresh of a patch I'd done earlier -- I've tried to make
>> the bug support as generic as possible to minimize having board
>> specific ifdef crap in 8250.c -- any suggestions on how to further
>> improve it are welcome.
>>
>>   drivers/serial/8250.c      |    6 ++++++
>>   drivers/serial/8250.h      |   20 ++++++++++++++++++++
>>   drivers/serial/Kconfig     |   14 ++++++++++++++
>>   include/linux/serial_reg.h |    2 ++
>>   4 files changed, 42 insertions(+), 0 deletions(-)
>>
>> diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
>> index e9b15c3..850b0e9 100644
>> --- a/drivers/serial/8250.c
>> +++ b/drivers/serial/8250.c
>> @@ -1531,6 +1531,11 @@ static void serial8250_handle_port(struct uart_8250_port *up)
>>
>>         status = serial_inp(up, UART_LSR);
>>
>> +       if ((up->bugs&  UART_BUG_PPC)&&  (status == UART_LSR_RFE_ERROR_BITS)) {
>> +               spin_unlock_irqrestore(&up->port.lock, flags);
>> +               return;
>> +       }
>> +
>>         DEBUG_INTR("status = %x...", status);
>>
>>         if (status&  (UART_LSR_DR | UART_LSR_BI))
>> @@ -1948,6 +1953,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);
>> diff --git a/drivers/serial/8250.h b/drivers/serial/8250.h
>> index 6e19ea3..2074ce1 100644
>> --- a/drivers/serial/8250.h
>> +++ b/drivers/serial/8250.h
>> @@ -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)
>> +
>> diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
>> index 9ff47db..e01a411 100644
>> --- a/drivers/serial/Kconfig
>> +++ b/drivers/serial/Kconfig
>> @@ -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, addional checks will be added in the 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
>> diff --git a/include/linux/serial_reg.h b/include/linux/serial_reg.h
>> index cf9327c..010174f 100644
>> --- a/include/linux/serial_reg.h
>> +++ b/include/linux/serial_reg.h
>> @@ -111,6 +111,7 @@
>>   #define UART_MCR_DTR           0x01 /* DTR complement */
>>
>>   #define UART_LSR       5       /* In:  Line Status Register */
>> +#define UART_LSR_RFE           0x80 /* Rx FIFO Error (BE, FE, or PE) */
>>   #define UART_LSR_TEMT          0x40 /* Transmitter empty */
>>   #define UART_LSR_THRE          0x20 /* Transmit-hold-register empty */
>>   #define UART_LSR_BI            0x10 /* Break interrupt indicator */
>> @@ -119,6 +120,7 @@
>>   #define UART_LSR_OE            0x02 /* Overrun error indicator */
>>   #define UART_LSR_DR            0x01 /* Receiver data ready */
>>   #define UART_LSR_BRK_ERROR_BITS        0x1E /* BI, FE, PE, OE bits */
>> +#define UART_LSR_RFE_ERROR_BITS        0xF1 /* RFE, TEMT, THRE, BI, DR bits */
>>
>>   #define UART_MSR       6       /* In:  Modem Status Register */
>>   #define UART_MSR_DCD           0x80 /* Data Carrier Detect */
>> --
>> 1.6.5.2
>>
>> _______________________________________________
>> Linuxppc-dev mailing list
>> Linuxppc-dev@lists.ozlabs.org
>> https://lists.ozlabs.org/listinfo/linuxppc-dev
>>

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

* Re: [PATCH] 8250: add workaround for MPC8[356]xx UART break IRQ storm
  2010-03-02 16:27   ` Paul Gortmaker
@ 2010-03-02 21:21     ` vb
  0 siblings, 0 replies; 11+ messages in thread
From: vb @ 2010-03-02 21:21 UTC (permalink / raw)
  To: Paul Gortmaker; +Cc: linuxppc-dev, linux-serial

On Tue, Mar 2, 2010 at 8:27 AM, Paul Gortmaker
<paul.gortmaker@windriver.com> wrote:
> On 10-03-01 06:03 PM, vb@vsbe.com wrote:
>> sounds very much like this issue:
>>
>> http://linux.derkeiler.com/Mailing-Lists/Kernel/2010-02/msg09470.html
>
> Thanks for the link.
>
>>
>> (interrupt storm on the second port which is hit with breaks).
>>
>> It's not the uart driver problem per se, the below fixes it:
>
> Actually, it is a uart *hardware* problem -- see in this same
> thread where Scott Wood described an errata, and when I
> implemented his interpretation of what the fix should look
> like, things just worked. =A0You might want to try out that patch
> and see if it helps you, since from the link above, I see you
> are also on a powerpc board.
>
> Paul.
>

yeah, I was not aware of the hardware bug you are describing, it's
just the scenario I encountered is very similar: the serial interface
is flooded with breaks, after a while the prot generates an IRQ storm.
But the storm happens only after the port gets shut down (by getty in
my case).

In my case this behavior is due to a SW bug, you might be hitting the
HW problem, I have not seen it yet,

cheers,
/vb


>>
>> *** linux/drivers/serial/serial_core.c#1 =A0 =A0 =A0 =A0Wed Feb 24 17:46=
:22 2010
>> --- =A0linux/drivers/serial/serial_core.c#2 =A0 =A0 =A0 =A0Mon Mar =A01 =
15:00:29 2010
>> ***************
>> *** 622,632 ****
>> =A0 =A0 =A0 =A0 =A0struct uart_port *port =3D state->port;
>>
>> =A0 =A0 =A0 =A0 =A0if (I_IXOFF(tty)) {
>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0if (port->x_char)
>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0port->x_char =3D 0;
>> ! =A0 =A0 =A0 =A0 =A0 =A0 =A0 else
>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0uart_send_xchar(tty, =
START_CHAR(tty));
>> =A0 =A0 =A0 =A0 =A0}
>>
>> =A0 =A0 =A0 =A0 =A0if (tty->termios->c_cflag& =A0CRTSCTS)
>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0uart_set_mctrl(port, TIOCM_RTS);
>> --- 622,632 ----
>> =A0 =A0 =A0 =A0 =A0struct uart_port *port =3D state->port;
>>
>> =A0 =A0 =A0 =A0 =A0if (I_IXOFF(tty)) {
>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0if (port->x_char)
>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0port->x_char =3D 0;
>> ! =A0 =A0 =A0 =A0 =A0 =A0 =A0 else if (!(tty->flags& =A0(1<< =A0TTY_IO_E=
RROR)))
>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0uart_send_xchar(tty, =
START_CHAR(tty));
>> =A0 =A0 =A0 =A0 =A0}
>>
>> =A0 =A0 =A0 =A0 =A0if (tty->termios->c_cflag& =A0CRTSCTS)
>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0uart_set_mctrl(port, TIOCM_RTS);
>> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^=
^^^^^^^^^^^^^^^^^^^^^^
>>
>> I did not get to trying to submit it, but it sure gets rid o the storm.
>>
>> cheers,
>> /vb
>>
>> On Fri, Feb 26, 2010 at 11:25 AM, Paul Gortmaker
>> <paul.gortmaker@windriver.com> =A0wrote:
>>> Sending a break on the SOC UARTs found in some MPC83xx/85xx/86xx
>>> chips seems to cause a short lived IRQ storm (/proc/interrupts
>>> typically shows somewhere between 300 and 1500 events). =A0Unfortunatel=
y
>>> this renders SysRQ over the serial console completely inoperable.
>>> Testing with obvious things like ACKing the event doesn't seem to
>>> change anything vs. a completely dumb approach of just ignoring
>>> it and waiting for it to stop, so that is what is implemented here.
>>>
>>> Signed-off-by: Paul Gortmaker<paul.gortmaker@windriver.com>
>>> ---
>>>
>>> This is a refresh of a patch I'd done earlier -- I've tried to make
>>> the bug support as generic as possible to minimize having board
>>> specific ifdef crap in 8250.c -- any suggestions on how to further
>>> improve it are welcome.
>>>
>>> =A0 drivers/serial/8250.c =A0 =A0 =A0| =A0 =A06 ++++++
>>> =A0 drivers/serial/8250.h =A0 =A0 =A0| =A0 20 ++++++++++++++++++++
>>> =A0 drivers/serial/Kconfig =A0 =A0 | =A0 14 ++++++++++++++
>>> =A0 include/linux/serial_reg.h | =A0 =A02 ++
>>> =A0 4 files changed, 42 insertions(+), 0 deletions(-)
>>>
>>> diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
>>> index e9b15c3..850b0e9 100644
>>> --- a/drivers/serial/8250.c
>>> +++ b/drivers/serial/8250.c
>>> @@ -1531,6 +1531,11 @@ static void serial8250_handle_port(struct uart_8=
250_port *up)
>>>
>>> =A0 =A0 =A0 =A0 status =3D serial_inp(up, UART_LSR);
>>>
>>> + =A0 =A0 =A0 if ((up->bugs& =A0UART_BUG_PPC)&& =A0(status =3D=3D UART_=
LSR_RFE_ERROR_BITS)) {
>>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 spin_unlock_irqrestore(&up->port.lock, fl=
ags);
>>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 return;
>>> + =A0 =A0 =A0 }
>>> +
>>> =A0 =A0 =A0 =A0 DEBUG_INTR("status =3D %x...", status);
>>>
>>> =A0 =A0 =A0 =A0 if (status& =A0(UART_LSR_DR | UART_LSR_BI))
>>> @@ -1948,6 +1953,7 @@ static int serial8250_startup(struct uart_port *p=
ort)
>>>
>>> =A0 =A0 =A0 =A0 up->capabilities =3D uart_config[up->port.type].flags;
>>> =A0 =A0 =A0 =A0 up->mcr =3D 0;
>>> + =A0 =A0 =A0 up->bugs |=3D UART_KNOWN_BUGS;
>>>
>>> =A0 =A0 =A0 =A0 if (up->port.iotype !=3D up->cur_iotype)
>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 set_io_from_upio(port);
>>> diff --git a/drivers/serial/8250.h b/drivers/serial/8250.h
>>> index 6e19ea3..2074ce1 100644
>>> --- a/drivers/serial/8250.h
>>> +++ b/drivers/serial/8250.h
>>> @@ -49,6 +49,7 @@ struct serial8250_config {
>>> =A0 #define UART_BUG_TXEN =A0(1<< =A01) =A0 =A0 =A0 =A0/* UART has bugg=
y TX IIR status */
>>> =A0 #define UART_BUG_NOMSR (1<< =A02) =A0 =A0 =A0 =A0/* UART has buggy =
MSR status bits (Au1x00) */
>>> =A0 #define UART_BUG_THRE =A0(1<< =A03) =A0 =A0 =A0 =A0/* UART has bugg=
y THRE reassertion */
>>> +#define UART_BUG_PPC =A0 (1<< =A04) =A0 =A0 =A0 =A0/* UART has buggy P=
PC break IRQ storm */
>>>
>>> =A0 #define PROBE_RSA =A0 =A0 =A0(1<< =A00)
>>> =A0 #define PROBE_ANY =A0 =A0 =A0(~0)
>>> @@ -78,3 +79,22 @@ struct serial8250_config {
>>> =A0 #else
>>> =A0 #define ALPHA_KLUDGE_MCR 0
>>> =A0 #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 =A0 0 =A0 =A0 =A0 /* assign UART_BUG_QUOT to enab=
le */
>>> +#define HAS_BUG_TXEN =A0 0 =A0 =A0 =A0 /* assign UART_BUG_TXEN to enab=
le */
>>> +#define HAS_BUG_NOMSR =A00 =A0 =A0 =A0 /* assign UART_BUG_NOMSR to ena=
ble */
>>> +#define HAS_BUG_THRE =A0 0 =A0 =A0 =A0 /* assign UART_BUG_THRE to enab=
le */
>>> +
>>> +#ifdef CONFIG_SERIAL_8250_PPC_BUG
>>> +#define HAS_BUG_PPC =A0 =A0UART_BUG_PPC
>>> +#else
>>> +#define HAS_BUG_PPC =A0 =A00
>>> +#endif
>>> +
>>> +#define UART_KNOWN_BUGS (HAS_BUG_QUOT | HAS_BUG_TXEN | HAS_BUG_NOMSR |=
 \
>>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 HAS_BUG_THRE | HAS_BUG_PP=
C)
>>> +
>>> diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
>>> index 9ff47db..e01a411 100644
>>> --- a/drivers/serial/Kconfig
>>> +++ b/drivers/serial/Kconfig
>>> @@ -70,6 +70,20 @@ config SERIAL_8250_CONSOLE
>>>
>>> =A0 =A0 =A0 =A0 =A0 If unsure, say N.
>>>
>>> +config SERIAL_8250_PPC_BUG
>>> + =A0 =A0 =A0 bool "Fix 8250/16550 to handle IRQ storm after receipt of=
 a break"
>>> + =A0 =A0 =A0 depends on SERIAL_8250&& =A0PPC32
>>> + =A0 =A0 =A0 ---help---
>>> + =A0 =A0 =A0 =A0 If you say Y here, addional checks will be added in t=
he handling of
>>> + =A0 =A0 =A0 =A0 interrupts on the serial ports which will prevent ill=
 effects of
>>> + =A0 =A0 =A0 =A0 an interrupt storm triggered by a break on the serial=
 line. Without
>>> + =A0 =A0 =A0 =A0 this enabled, a Sysrq via the serial console can be u=
nusable on
>>> + =A0 =A0 =A0 =A0 some systems.
>>> +
>>> + =A0 =A0 =A0 =A0 This is commonly observed on PPC32 MPC83xx/85xx/86xx =
based boards.
>>> +
>>> + =A0 =A0 =A0 =A0 If unsure, say N.
>>> +
>>> =A0 config FIX_EARLYCON_MEM
>>> =A0 =A0 =A0 =A0 bool
>>> =A0 =A0 =A0 =A0 depends on X86
>>> diff --git a/include/linux/serial_reg.h b/include/linux/serial_reg.h
>>> index cf9327c..010174f 100644
>>> --- a/include/linux/serial_reg.h
>>> +++ b/include/linux/serial_reg.h
>>> @@ -111,6 +111,7 @@
>>> =A0 #define UART_MCR_DTR =A0 =A0 =A0 =A0 =A0 0x01 /* DTR complement */
>>>
>>> =A0 #define UART_LSR =A0 =A0 =A0 5 =A0 =A0 =A0 /* In: =A0Line Status Re=
gister */
>>> +#define UART_LSR_RFE =A0 =A0 =A0 =A0 =A0 0x80 /* Rx FIFO Error (BE, FE=
, or PE) */
>>> =A0 #define UART_LSR_TEMT =A0 =A0 =A0 =A0 =A00x40 /* Transmitter empty =
*/
>>> =A0 #define UART_LSR_THRE =A0 =A0 =A0 =A0 =A00x20 /* Transmit-hold-regi=
ster empty */
>>> =A0 #define UART_LSR_BI =A0 =A0 =A0 =A0 =A0 =A00x10 /* Break interrupt =
indicator */
>>> @@ -119,6 +120,7 @@
>>> =A0 #define UART_LSR_OE =A0 =A0 =A0 =A0 =A0 =A00x02 /* Overrun error in=
dicator */
>>> =A0 #define UART_LSR_DR =A0 =A0 =A0 =A0 =A0 =A00x01 /* Receiver data re=
ady */
>>> =A0 #define UART_LSR_BRK_ERROR_BITS =A0 =A0 =A0 =A00x1E /* BI, FE, PE, =
OE bits */
>>> +#define UART_LSR_RFE_ERROR_BITS =A0 =A0 =A0 =A00xF1 /* RFE, TEMT, THRE=
, BI, DR bits */
>>>
>>> =A0 #define UART_MSR =A0 =A0 =A0 6 =A0 =A0 =A0 /* In: =A0Modem Status R=
egister */
>>> =A0 #define UART_MSR_DCD =A0 =A0 =A0 =A0 =A0 0x80 /* Data Carrier Detec=
t */
>>> --
>>> 1.6.5.2
>>>
>>> _______________________________________________
>>> Linuxppc-dev mailing list
>>> Linuxppc-dev@lists.ozlabs.org
>>> https://lists.ozlabs.org/listinfo/linuxppc-dev
>>>
>
>

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

* Re: [PATCH] 8250: add workaround for MPC8[356]xx UART break IRQ storm
  2010-02-26 19:25 [PATCH] 8250: add workaround for MPC8[356]xx UART break IRQ storm Paul Gortmaker
  2010-02-26 19:42 ` Kumar Gala
  2010-03-01 23:03 ` vb
@ 2011-11-24  8:14 ` Kumar Gala
  2011-11-24 15:26   ` Paul Gortmaker
  2 siblings, 1 reply; 11+ messages in thread
From: Kumar Gala @ 2011-11-24  8:14 UTC (permalink / raw)
  To: Paul Gortmaker; +Cc: linuxppc-dev, linux-serial


On Feb 26, 2010, at 1:25 PM, Paul Gortmaker wrote:

> Sending a break on the SOC UARTs found in some MPC83xx/85xx/86xx
> chips seems to cause a short lived IRQ storm (/proc/interrupts
> typically shows somewhere between 300 and 1500 events).  Unfortunately
> this renders SysRQ over the serial console completely inoperable.
> Testing with obvious things like ACKing the event doesn't seem to
> change anything vs. a completely dumb approach of just ignoring
> it and waiting for it to stop, so that is what is implemented here.
>=20
> Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
> ---
>=20
> This is a refresh of a patch I'd done earlier -- I've tried to make
> the bug support as generic as possible to minimize having board
> specific ifdef crap in 8250.c -- any suggestions on how to further
> improve it are welcome.
>=20
> drivers/serial/8250.c      |    6 ++++++
> drivers/serial/8250.h      |   20 ++++++++++++++++++++
> drivers/serial/Kconfig     |   14 ++++++++++++++
> include/linux/serial_reg.h |    2 ++
> 4 files changed, 42 insertions(+), 0 deletions(-)

Did we ever decide what to do with this or trying to get it accepted =
upstream?

- k=

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

* Re: [PATCH] 8250: add workaround for MPC8[356]xx UART break IRQ storm
  2011-11-24  8:14 ` Kumar Gala
@ 2011-11-24 15:26   ` Paul Gortmaker
  2011-11-24 19:07     ` Kumar Gala
  0 siblings, 1 reply; 11+ messages in thread
From: Paul Gortmaker @ 2011-11-24 15:26 UTC (permalink / raw)
  To: Kumar Gala; +Cc: linuxppc-dev, linux-serial

On 11-11-24 03:14 AM, Kumar Gala wrote:
> 
> On Feb 26, 2010, at 1:25 PM, Paul Gortmaker wrote:
> 
>> Sending a break on the SOC UARTs found in some MPC83xx/85xx/86xx
>> chips seems to cause a short lived IRQ storm (/proc/interrupts
>> typically shows somewhere between 300 and 1500 events).  Unfortunately
>> this renders SysRQ over the serial console completely inoperable.
>> Testing with obvious things like ACKing the event doesn't seem to
>> change anything vs. a completely dumb approach of just ignoring
>> it and waiting for it to stop, so that is what is implemented here.
>>
>> Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
>> ---
>>
>> This is a refresh of a patch I'd done earlier -- I've tried to make
>> the bug support as generic as possible to minimize having board
>> specific ifdef crap in 8250.c -- any suggestions on how to further
>> improve it are welcome.
>>
>> drivers/serial/8250.c      |    6 ++++++
>> drivers/serial/8250.h      |   20 ++++++++++++++++++++
>> drivers/serial/Kconfig     |   14 ++++++++++++++
>> include/linux/serial_reg.h |    2 ++
>> 4 files changed, 42 insertions(+), 0 deletions(-)
> 
> Did we ever decide what to do with this or trying to get it accepted upstream?

That is an old version.  ScottW gave me the errata information
which allowed me to fix the problem in a cleaner way.

http://patchwork.ozlabs.org/patch/46609/

I think the above version is OK as-is; the only thing I
think we could do to improve it is to go and automatically
select the thing based on known impacted CPU types (which
could be a separate commit or commits, as various CPUs are
confirmed to have the issue.)

Paul.

> 
> - k

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

* Re: [PATCH] 8250: add workaround for MPC8[356]xx UART break IRQ storm
  2011-11-24 15:26   ` Paul Gortmaker
@ 2011-11-24 19:07     ` Kumar Gala
  0 siblings, 0 replies; 11+ messages in thread
From: Kumar Gala @ 2011-11-24 19:07 UTC (permalink / raw)
  To: Paul Gortmaker; +Cc: linuxppc-dev, linux-serial


On Nov 24, 2011, at 9:26 AM, Paul Gortmaker wrote:

> On 11-11-24 03:14 AM, Kumar Gala wrote:
>>=20
>> On Feb 26, 2010, at 1:25 PM, Paul Gortmaker wrote:
>>=20
>>> Sending a break on the SOC UARTs found in some MPC83xx/85xx/86xx
>>> chips seems to cause a short lived IRQ storm (/proc/interrupts
>>> typically shows somewhere between 300 and 1500 events).  =
Unfortunately
>>> this renders SysRQ over the serial console completely inoperable.
>>> Testing with obvious things like ACKing the event doesn't seem to
>>> change anything vs. a completely dumb approach of just ignoring
>>> it and waiting for it to stop, so that is what is implemented here.
>>>=20
>>> Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
>>> ---
>>>=20
>>> This is a refresh of a patch I'd done earlier -- I've tried to make
>>> the bug support as generic as possible to minimize having board
>>> specific ifdef crap in 8250.c -- any suggestions on how to further
>>> improve it are welcome.
>>>=20
>>> drivers/serial/8250.c      |    6 ++++++
>>> drivers/serial/8250.h      |   20 ++++++++++++++++++++
>>> drivers/serial/Kconfig     |   14 ++++++++++++++
>>> include/linux/serial_reg.h |    2 ++
>>> 4 files changed, 42 insertions(+), 0 deletions(-)
>>=20
>> Did we ever decide what to do with this or trying to get it accepted =
upstream?
>=20
> That is an old version.  ScottW gave me the errata information
> which allowed me to fix the problem in a cleaner way.
>=20
> http://patchwork.ozlabs.org/patch/46609/
>=20
> I think the above version is OK as-is; the only thing I
> think we could do to improve it is to go and automatically
> select the thing based on known impacted CPU types (which
> could be a separate commit or commits, as various CPUs are
> confirmed to have the issue.)

Seems as if we could have ->bugs passed in via plat_serial8250_port and =
than we can get the info from the device tree.

- k=

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

end of thread, other threads:[~2011-11-24 19:07 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-02-26 19:25 [PATCH] 8250: add workaround for MPC8[356]xx UART break IRQ storm Paul Gortmaker
2010-02-26 19:42 ` Kumar Gala
2010-02-26 20:21   ` Paul Gortmaker
2010-02-26 20:23   ` Scott Wood
2010-03-01 21:23     ` Paul Gortmaker
2010-03-01 23:03 ` vb
2010-03-02 16:27   ` Paul Gortmaker
2010-03-02 21:21     ` vb
2011-11-24  8:14 ` Kumar Gala
2011-11-24 15:26   ` Paul Gortmaker
2011-11-24 19:07     ` Kumar Gala

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