From 01c194d9278efc15d4785ff205643e9c0bdcef53 Mon Sep 17 00:00:00 2001 From: Alex Williamson Date: Mon, 28 Apr 2008 02:14:09 -0700 Subject: 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: Alex Williamson Cc: Thomas Koeller Cc: Russell King Cc: Alan Cox Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/serial/8250.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index 6d0ce64163e5..ea41f2626458 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c @@ -1868,6 +1868,7 @@ static int serial8250_startup(struct uart_port *port) } if (is_real_interrupt(up->port.irq)) { + unsigned char iir1; /* * Test for UARTs that do not reassert THRE when the * transmitter is idle and the interrupt has already @@ -1881,7 +1882,7 @@ static int serial8250_startup(struct uart_port *port) wait_for_xmitr(up, UART_LSR_THRE); serial_out_sync(up, UART_IER, UART_IER_THRI); 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_sync(up, UART_IER, UART_IER_THRI); udelay(1); /* allow a working UART time to re-assert THRE */ @@ -1894,7 +1895,7 @@ static int serial8250_startup(struct uart_port *port) * If the interrupt is not reasserted, setup a timer to * 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); up->timer.function = serial8250_backup_timeout; up->timer.data = (unsigned long)up; -- cgit v1.2.2