aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/serial
diff options
context:
space:
mode:
authorRussell King <rmk@dyn-67.arm.linux.org.uk>2006-01-04 11:55:09 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2006-01-04 11:55:09 -0500
commit2af7cd68f1ed20e2e72c91988c3d4f457fa29ebc (patch)
treea242ce0d1ecd154ef6bfa7aaf910a003bed3abdd /drivers/serial
parent88026842b0a760145aa71d69e74fbc9ec118ca44 (diff)
[Serial] Don't miss modem status changes
Reading the MSR register on 8250-compatible UARTs results in any modem status interrupts being cleared. To avoid missing any status changes, arrange for get_mctrl() to read the current status via check_modem_status(), which will process any pending state changes for us. Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'drivers/serial')
-rw-r--r--drivers/serial/8250.c33
1 files changed, 16 insertions, 17 deletions
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index d2bcd1f87cd6..076bf848e4d1 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -1255,25 +1255,24 @@ static _INLINE_ void transmit_chars(struct uart_8250_port *up)
1255 __stop_tx(up); 1255 __stop_tx(up);
1256} 1256}
1257 1257
1258static _INLINE_ void check_modem_status(struct uart_8250_port *up) 1258static unsigned int check_modem_status(struct uart_8250_port *up)
1259{ 1259{
1260 int status; 1260 unsigned int status = serial_in(up, UART_MSR);
1261 1261
1262 status = serial_in(up, UART_MSR); 1262 if (status & UART_MSR_ANY_DELTA && up->ier & UART_IER_MSI) {
1263 if (status & UART_MSR_TERI)
1264 up->port.icount.rng++;
1265 if (status & UART_MSR_DDSR)
1266 up->port.icount.dsr++;
1267 if (status & UART_MSR_DDCD)
1268 uart_handle_dcd_change(&up->port, status & UART_MSR_DCD);
1269 if (status & UART_MSR_DCTS)
1270 uart_handle_cts_change(&up->port, status & UART_MSR_CTS);
1263 1271
1264 if ((status & UART_MSR_ANY_DELTA) == 0) 1272 wake_up_interruptible(&up->port.info->delta_msr_wait);
1265 return; 1273 }
1266
1267 if (status & UART_MSR_TERI)
1268 up->port.icount.rng++;
1269 if (status & UART_MSR_DDSR)
1270 up->port.icount.dsr++;
1271 if (status & UART_MSR_DDCD)
1272 uart_handle_dcd_change(&up->port, status & UART_MSR_DCD);
1273 if (status & UART_MSR_DCTS)
1274 uart_handle_cts_change(&up->port, status & UART_MSR_CTS);
1275 1274
1276 wake_up_interruptible(&up->port.info->delta_msr_wait); 1275 return status;
1277} 1276}
1278 1277
1279/* 1278/*
@@ -1454,10 +1453,10 @@ static unsigned int serial8250_tx_empty(struct uart_port *port)
1454static unsigned int serial8250_get_mctrl(struct uart_port *port) 1453static unsigned int serial8250_get_mctrl(struct uart_port *port)
1455{ 1454{
1456 struct uart_8250_port *up = (struct uart_8250_port *)port; 1455 struct uart_8250_port *up = (struct uart_8250_port *)port;
1457 unsigned char status; 1456 unsigned int status;
1458 unsigned int ret; 1457 unsigned int ret;
1459 1458
1460 status = serial_in(up, UART_MSR); 1459 status = check_modem_status(up);
1461 1460
1462 ret = 0; 1461 ret = 0;
1463 if (status & UART_MSR_DCD) 1462 if (status & UART_MSR_DCD)