linux/drivers/tty
Douglas Anderson 424d79183a serial: 8250_dw: Avoid "too much work" from bogus rx timeout interrupt
On a Rockchip rk3399-based board during suspend/resume testing, we
found that we could get the console UART into a state where it would
print this to the console a lot:
  serial8250: too much work for irq42

Followed eventually by:
  NMI watchdog: BUG: soft lockup - CPU#0 stuck for 11s!

Upon debugging I found that we're in this state:
  iir = 0x000000cc
  lsr = 0x00000060

It appears that somehow we have a RX Timeout interrupt but there is no
actual data present to receive.  When we're in this state the UART
driver claims that it handled the interrupt but it actually doesn't
really do anything.  This means that we keep getting the interrupt
over and over again.

Normally we don't actually need to do anything special to handle a RX
Timeout interrupt.  We'll notice that there is some data ready and
we'll read it, which will end up clearing the RX Timeout.  In this
case we have a problem specifically because we got the RX TImeout
without any data.  Reading a bogus byte is confirmed to get us out of
this state.

It's unclear how exactly the UART got into this state, but it is known
that the UART lines are essentially undriven and unpowered during
suspend, so possibly during resume some garbage / half transmitted
bits are seen on the line and put the UART into this state.

The UART on the rk3399 is a DesignWare based 8250 UART.  From mailing
list posts, it appears that other people have run into similar
problems with DesignWare based IP.  Presumably this problem is unique
to that IP, so I have placed the workaround there to avoid possibly of
accidentally triggering bad behavior on other IP.  Also note the RX
Timeout behaves very differently in the DMA case, for for now the
workaround is only applied to the non-DMA case.

Signed-off-by: Douglas Anderson <dianders@chromium.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-02-10 15:10:16 +01:00
..
hvc Replace <asm/uaccess.h> with <linux/uaccess.h> globally 2016-12-24 11:46:01 -08:00
ipwireless tty: ipwireless, cleanup TIOCGSERIAL 2016-06-25 08:56:30 -07:00
serdev serdev: ttyport: check whether tty_init_dev() fails 2017-02-09 13:54:49 +01:00
serial serial: 8250_dw: Avoid "too much work" from bogus rx timeout interrupt 2017-02-10 15:10:16 +01:00
vt console: Add callback to flush scrollback buffer to consw struct 2017-01-25 11:54:02 +01:00
amiserial.c Replace <asm/uaccess.h> with <linux/uaccess.h> globally 2016-12-24 11:46:01 -08:00
bfin_jtag_comm.c
cyclades.c tty: stop defining STD_COM_FLAGS in drivers 2016-06-25 08:56:30 -07:00
ehv_bytechan.c drivers/tty: make ehv_bytechan.c explicitly non-modular 2016-02-06 23:26:43 -08:00
goldfish.c tty: goldfish: Fix a parameter of a call to free_irq 2017-01-12 11:51:25 +01:00
isicom.c tty: Replace ASYNC_INITIALIZED bit and update atomically 2016-04-30 09:26:55 -07:00
Kconfig devpts: Make each mount of devpts an independent filesystem. 2016-06-05 10:36:01 -07:00
Makefile serdev: Introduce new bus for serial attached devices 2017-02-03 10:17:02 +01:00
metag_da.c timers, drivers/tty/metag_da: Initialize the poll timer as pinned 2016-07-07 10:25:14 +02:00
mips_ejtag_fdc.c timers, drivers/tty/mips_ejtag: Initialize the poll timer as pinned 2016-07-07 10:34:59 +02:00
moxa.c Replace <asm/uaccess.h> with <linux/uaccess.h> globally 2016-12-24 11:46:01 -08:00
moxa.h
mxser.c Replace <asm/uaccess.h> with <linux/uaccess.h> globally 2016-12-24 11:46:01 -08:00
mxser.h
n_gsm.c net: use core MTU range checking in wireless drivers 2016-10-20 14:51:08 -04:00
n_hdlc.c Replace <asm/uaccess.h> with <linux/uaccess.h> globally 2016-12-24 11:46:01 -08:00
n_r3964.c Replace <asm/uaccess.h> with <linux/uaccess.h> globally 2016-12-24 11:46:01 -08:00
n_tracerouter.c
n_tracesink.c
n_tracesink.h
n_tty.c Fix OpenSSH pty regression on close 2016-05-01 13:22:54 -07:00
nozomi.c tty: nozomi: avoid sprintf buffer overflow 2016-11-29 20:20:07 +01:00
pty.c pty: make ptmx file ops read-only after init 2016-09-15 12:47:03 +02:00
rocket_int.h tty: rocket: Remove private close_wait 2016-01-28 14:13:44 -08:00
rocket.c tty: rocket: fix invalid user-pointer checks 2016-11-10 14:41:25 +01:00
rocket.h
synclink_gt.c Replace <asm/uaccess.h> with <linux/uaccess.h> globally 2016-12-24 11:46:01 -08:00
synclink.c Replace <asm/uaccess.h> with <linux/uaccess.h> globally 2016-12-24 11:46:01 -08:00
synclinkmp.c Replace <asm/uaccess.h> with <linux/uaccess.h> globally 2016-12-24 11:46:01 -08:00
sysrq.c sysrq: attach sysrq handler correctly for 32-bit kernel 2017-01-11 09:22:54 +01:00
tty_audit.c tty: audit: remove unused variable 2016-03-07 16:11:14 -08:00
tty_buffer.c tty_port: Add port client functions 2017-02-03 10:17:02 +01:00
tty_io.c tty_port: allow a port to be opened with a tty that has no file handle 2017-01-19 17:22:34 +01:00
tty_ioctl.c Replace <asm/uaccess.h> with <linux/uaccess.h> globally 2016-12-24 11:46:01 -08:00
tty_ldisc.c tty: Eliminate global symbol tty_ldisc_N_TTY 2016-01-27 15:13:28 -08:00
tty_ldsem.c
tty_mutex.c Merge 4.5-rc4 into tty-next 2016-02-14 14:36:04 -08:00
tty_port.c tty_port: register tty ports with serdev bus 2017-02-03 10:17:02 +01:00