Skip to content
Snippets Groups Projects
Commit 01c194d9 authored by Alex Williamson's avatar Alex Williamson Committed by Linus Torvalds
Browse files

serial 8250: tighten test for using backup timer


Thomas Koeller had reported an issue where a device that had been making use
of the UART_BUG_TXEN code in the 8250 driver was mistakenly being caught by
the backup timer test, causing the device to work improperly.

To fix this, tighten the test requirements to enable the backup timer
workaround.

The backup timer is really meant to catch UARTs that don't re-assert the THRE
interrupt.  The expectation is that they do initially assert THRE.  This patch
clarifies the test.

Signed-off-by: default avatarAlex Williamson <alex.williamson@hp.com>
Cc: Thomas Koeller <thomas@koeller.dyndns.org>
Cc: Russell King <rmk@arm.linux.org.uk>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent fc3f341b
No related branches found
No related tags found
No related merge requests found
...@@ -1868,6 +1868,7 @@ static int serial8250_startup(struct uart_port *port) ...@@ -1868,6 +1868,7 @@ static int serial8250_startup(struct uart_port *port)
} }
if (is_real_interrupt(up->port.irq)) { if (is_real_interrupt(up->port.irq)) {
unsigned char iir1;
/* /*
* Test for UARTs that do not reassert THRE when the * Test for UARTs that do not reassert THRE when the
* transmitter is idle and the interrupt has already * transmitter is idle and the interrupt has already
...@@ -1881,7 +1882,7 @@ static int serial8250_startup(struct uart_port *port) ...@@ -1881,7 +1882,7 @@ static int serial8250_startup(struct uart_port *port)
wait_for_xmitr(up, UART_LSR_THRE); wait_for_xmitr(up, UART_LSR_THRE);
serial_out_sync(up, UART_IER, UART_IER_THRI); serial_out_sync(up, UART_IER, UART_IER_THRI);
udelay(1); /* allow THRE to set */ udelay(1); /* allow THRE to set */
serial_in(up, UART_IIR); iir1 = serial_in(up, UART_IIR);
serial_out(up, UART_IER, 0); serial_out(up, UART_IER, 0);
serial_out_sync(up, UART_IER, UART_IER_THRI); serial_out_sync(up, UART_IER, UART_IER_THRI);
udelay(1); /* allow a working UART time to re-assert THRE */ udelay(1); /* allow a working UART time to re-assert THRE */
...@@ -1894,7 +1895,7 @@ static int serial8250_startup(struct uart_port *port) ...@@ -1894,7 +1895,7 @@ static int serial8250_startup(struct uart_port *port)
* If the interrupt is not reasserted, setup a timer to * If the interrupt is not reasserted, setup a timer to
* kick the UART on a regular basis. * kick the UART on a regular basis.
*/ */
if (iir & UART_IIR_NO_INT) { if (!(iir1 & UART_IIR_NO_INT) && (iir & UART_IIR_NO_INT)) {
pr_debug("ttyS%d - using backup timer\n", port->line); pr_debug("ttyS%d - using backup timer\n", port->line);
up->timer.function = serial8250_backup_timeout; up->timer.function = serial8250_backup_timeout;
up->timer.data = (unsigned long)up; up->timer.data = (unsigned long)up;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment