diff options
Diffstat (limited to 'drivers/serial/8250.c')
-rw-r--r-- | drivers/serial/8250.c | 60 |
1 files changed, 29 insertions, 31 deletions
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index d2bcd1f87cd6..1891cf5bdeef 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c | |||
@@ -296,7 +296,7 @@ static inline int map_8250_out_reg(struct uart_8250_port *up, int offset) | |||
296 | 296 | ||
297 | #endif | 297 | #endif |
298 | 298 | ||
299 | static _INLINE_ unsigned int serial_in(struct uart_8250_port *up, int offset) | 299 | static unsigned int serial_in(struct uart_8250_port *up, int offset) |
300 | { | 300 | { |
301 | offset = map_8250_in_reg(up, offset) << up->port.regshift; | 301 | offset = map_8250_in_reg(up, offset) << up->port.regshift; |
302 | 302 | ||
@@ -321,7 +321,7 @@ static _INLINE_ unsigned int serial_in(struct uart_8250_port *up, int offset) | |||
321 | } | 321 | } |
322 | } | 322 | } |
323 | 323 | ||
324 | static _INLINE_ void | 324 | static void |
325 | serial_out(struct uart_8250_port *up, int offset, int value) | 325 | serial_out(struct uart_8250_port *up, int offset, int value) |
326 | { | 326 | { |
327 | offset = map_8250_out_reg(up, offset) << up->port.regshift; | 327 | offset = map_8250_out_reg(up, offset) << up->port.regshift; |
@@ -1131,7 +1131,7 @@ static void serial8250_enable_ms(struct uart_port *port) | |||
1131 | serial_out(up, UART_IER, up->ier); | 1131 | serial_out(up, UART_IER, up->ier); |
1132 | } | 1132 | } |
1133 | 1133 | ||
1134 | static _INLINE_ void | 1134 | static void |
1135 | receive_chars(struct uart_8250_port *up, int *status, struct pt_regs *regs) | 1135 | receive_chars(struct uart_8250_port *up, int *status, struct pt_regs *regs) |
1136 | { | 1136 | { |
1137 | struct tty_struct *tty = up->port.info->tty; | 1137 | struct tty_struct *tty = up->port.info->tty; |
@@ -1217,7 +1217,7 @@ receive_chars(struct uart_8250_port *up, int *status, struct pt_regs *regs) | |||
1217 | *status = lsr; | 1217 | *status = lsr; |
1218 | } | 1218 | } |
1219 | 1219 | ||
1220 | static _INLINE_ void transmit_chars(struct uart_8250_port *up) | 1220 | static void transmit_chars(struct uart_8250_port *up) |
1221 | { | 1221 | { |
1222 | struct circ_buf *xmit = &up->port.info->xmit; | 1222 | struct circ_buf *xmit = &up->port.info->xmit; |
1223 | int count; | 1223 | int count; |
@@ -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 | ||
1258 | static _INLINE_ void check_modem_status(struct uart_8250_port *up) | 1258 | static 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 | |||
1262 | status = serial_in(up, UART_MSR); | ||
1263 | 1261 | ||
1264 | if ((status & UART_MSR_ANY_DELTA) == 0) | 1262 | if (status & UART_MSR_ANY_DELTA && up->ier & UART_IER_MSI) { |
1265 | return; | 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); | ||
1266 | 1271 | ||
1267 | if (status & UART_MSR_TERI) | 1272 | wake_up_interruptible(&up->port.info->delta_msr_wait); |
1268 | up->port.icount.rng++; | 1273 | } |
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 | /* |
@@ -1282,7 +1281,11 @@ static _INLINE_ void check_modem_status(struct uart_8250_port *up) | |||
1282 | static inline void | 1281 | static inline void |
1283 | serial8250_handle_port(struct uart_8250_port *up, struct pt_regs *regs) | 1282 | serial8250_handle_port(struct uart_8250_port *up, struct pt_regs *regs) |
1284 | { | 1283 | { |
1285 | unsigned int status = serial_inp(up, UART_LSR); | 1284 | unsigned int status; |
1285 | |||
1286 | spin_lock(&up->port.lock); | ||
1287 | |||
1288 | status = serial_inp(up, UART_LSR); | ||
1286 | 1289 | ||
1287 | DEBUG_INTR("status = %x...", status); | 1290 | DEBUG_INTR("status = %x...", status); |
1288 | 1291 | ||
@@ -1291,6 +1294,8 @@ serial8250_handle_port(struct uart_8250_port *up, struct pt_regs *regs) | |||
1291 | check_modem_status(up); | 1294 | check_modem_status(up); |
1292 | if (status & UART_LSR_THRE) | 1295 | if (status & UART_LSR_THRE) |
1293 | transmit_chars(up); | 1296 | transmit_chars(up); |
1297 | |||
1298 | spin_unlock(&up->port.lock); | ||
1294 | } | 1299 | } |
1295 | 1300 | ||
1296 | /* | 1301 | /* |
@@ -1326,9 +1331,7 @@ static irqreturn_t serial8250_interrupt(int irq, void *dev_id, struct pt_regs *r | |||
1326 | 1331 | ||
1327 | iir = serial_in(up, UART_IIR); | 1332 | iir = serial_in(up, UART_IIR); |
1328 | if (!(iir & UART_IIR_NO_INT)) { | 1333 | if (!(iir & UART_IIR_NO_INT)) { |
1329 | spin_lock(&up->port.lock); | ||
1330 | serial8250_handle_port(up, regs); | 1334 | serial8250_handle_port(up, regs); |
1331 | spin_unlock(&up->port.lock); | ||
1332 | 1335 | ||
1333 | handled = 1; | 1336 | handled = 1; |
1334 | 1337 | ||
@@ -1427,11 +1430,8 @@ static void serial8250_timeout(unsigned long data) | |||
1427 | unsigned int iir; | 1430 | unsigned int iir; |
1428 | 1431 | ||
1429 | iir = serial_in(up, UART_IIR); | 1432 | iir = serial_in(up, UART_IIR); |
1430 | if (!(iir & UART_IIR_NO_INT)) { | 1433 | if (!(iir & UART_IIR_NO_INT)) |
1431 | spin_lock(&up->port.lock); | ||
1432 | serial8250_handle_port(up, NULL); | 1434 | serial8250_handle_port(up, NULL); |
1433 | spin_unlock(&up->port.lock); | ||
1434 | } | ||
1435 | 1435 | ||
1436 | timeout = up->port.timeout; | 1436 | timeout = up->port.timeout; |
1437 | timeout = timeout > 6 ? (timeout / 2 - 2) : 1; | 1437 | timeout = timeout > 6 ? (timeout / 2 - 2) : 1; |
@@ -1454,10 +1454,10 @@ static unsigned int serial8250_tx_empty(struct uart_port *port) | |||
1454 | static unsigned int serial8250_get_mctrl(struct uart_port *port) | 1454 | static unsigned int serial8250_get_mctrl(struct uart_port *port) |
1455 | { | 1455 | { |
1456 | struct uart_8250_port *up = (struct uart_8250_port *)port; | 1456 | struct uart_8250_port *up = (struct uart_8250_port *)port; |
1457 | unsigned char status; | 1457 | unsigned int status; |
1458 | unsigned int ret; | 1458 | unsigned int ret; |
1459 | 1459 | ||
1460 | status = serial_in(up, UART_MSR); | 1460 | status = check_modem_status(up); |
1461 | 1461 | ||
1462 | ret = 0; | 1462 | ret = 0; |
1463 | if (status & UART_MSR_DCD) | 1463 | if (status & UART_MSR_DCD) |
@@ -2300,9 +2300,7 @@ static int __init find_port(struct uart_port *p) | |||
2300 | 2300 | ||
2301 | for (line = 0; line < UART_NR; line++) { | 2301 | for (line = 0; line < UART_NR; line++) { |
2302 | port = &serial8250_ports[line].port; | 2302 | port = &serial8250_ports[line].port; |
2303 | if (p->iotype == port->iotype && | 2303 | if (uart_match_port(p, port)) |
2304 | p->iobase == port->iobase && | ||
2305 | p->membase == port->membase) | ||
2306 | return line; | 2304 | return line; |
2307 | } | 2305 | } |
2308 | return -ENODEV; | 2306 | return -ENODEV; |