diff options
Diffstat (limited to 'drivers/serial/8250.c')
-rw-r--r-- | drivers/serial/8250.c | 36 |
1 files changed, 19 insertions, 17 deletions
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index 34e75bc8f4cc..7e8fc7c1d4cc 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c | |||
@@ -105,7 +105,7 @@ static struct old_serial_port old_serial_port[] = { | |||
105 | SERIAL_PORT_DFNS /* defined in asm/serial.h */ | 105 | SERIAL_PORT_DFNS /* defined in asm/serial.h */ |
106 | }; | 106 | }; |
107 | 107 | ||
108 | #define UART_NR (ARRAY_SIZE(old_serial_port) + CONFIG_SERIAL_8250_NR_UARTS) | 108 | #define UART_NR CONFIG_SERIAL_8250_NR_UARTS |
109 | 109 | ||
110 | #ifdef CONFIG_SERIAL_8250_RSA | 110 | #ifdef CONFIG_SERIAL_8250_RSA |
111 | 111 | ||
@@ -993,21 +993,24 @@ static void autoconfig_irq(struct uart_8250_port *up) | |||
993 | up->port.irq = (irq > 0) ? irq : 0; | 993 | up->port.irq = (irq > 0) ? irq : 0; |
994 | } | 994 | } |
995 | 995 | ||
996 | static inline void __stop_tx(struct uart_8250_port *p) | ||
997 | { | ||
998 | if (p->ier & UART_IER_THRI) { | ||
999 | p->ier &= ~UART_IER_THRI; | ||
1000 | serial_out(p, UART_IER, p->ier); | ||
1001 | } | ||
1002 | } | ||
1003 | |||
996 | static void serial8250_stop_tx(struct uart_port *port, unsigned int tty_stop) | 1004 | static void serial8250_stop_tx(struct uart_port *port, unsigned int tty_stop) |
997 | { | 1005 | { |
998 | struct uart_8250_port *up = (struct uart_8250_port *)port; | 1006 | struct uart_8250_port *up = (struct uart_8250_port *)port; |
999 | 1007 | ||
1000 | if (up->ier & UART_IER_THRI) { | 1008 | __stop_tx(up); |
1001 | up->ier &= ~UART_IER_THRI; | ||
1002 | serial_out(up, UART_IER, up->ier); | ||
1003 | } | ||
1004 | 1009 | ||
1005 | /* | 1010 | /* |
1006 | * We only do this from uart_stop - if we run out of | 1011 | * We really want to stop the transmitter from sending. |
1007 | * characters to send, we don't want to prevent the | ||
1008 | * FIFO from emptying. | ||
1009 | */ | 1012 | */ |
1010 | if (up->port.type == PORT_16C950 && tty_stop) { | 1013 | if (up->port.type == PORT_16C950) { |
1011 | up->acr |= UART_ACR_TXDIS; | 1014 | up->acr |= UART_ACR_TXDIS; |
1012 | serial_icr_write(up, UART_ACR, up->acr); | 1015 | serial_icr_write(up, UART_ACR, up->acr); |
1013 | } | 1016 | } |
@@ -1031,10 +1034,11 @@ static void serial8250_start_tx(struct uart_port *port, unsigned int tty_start) | |||
1031 | transmit_chars(up); | 1034 | transmit_chars(up); |
1032 | } | 1035 | } |
1033 | } | 1036 | } |
1037 | |||
1034 | /* | 1038 | /* |
1035 | * We only do this from uart_start | 1039 | * Re-enable the transmitter if we disabled it. |
1036 | */ | 1040 | */ |
1037 | if (tty_start && up->port.type == PORT_16C950) { | 1041 | if (up->port.type == PORT_16C950 && up->acr & UART_ACR_TXDIS) { |
1038 | up->acr &= ~UART_ACR_TXDIS; | 1042 | up->acr &= ~UART_ACR_TXDIS; |
1039 | serial_icr_write(up, UART_ACR, up->acr); | 1043 | serial_icr_write(up, UART_ACR, up->acr); |
1040 | } | 1044 | } |
@@ -1155,7 +1159,7 @@ static _INLINE_ void transmit_chars(struct uart_8250_port *up) | |||
1155 | return; | 1159 | return; |
1156 | } | 1160 | } |
1157 | if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) { | 1161 | if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) { |
1158 | serial8250_stop_tx(&up->port, 0); | 1162 | __stop_tx(up); |
1159 | return; | 1163 | return; |
1160 | } | 1164 | } |
1161 | 1165 | ||
@@ -1174,7 +1178,7 @@ static _INLINE_ void transmit_chars(struct uart_8250_port *up) | |||
1174 | DEBUG_INTR("THRE..."); | 1178 | DEBUG_INTR("THRE..."); |
1175 | 1179 | ||
1176 | if (uart_circ_empty(xmit)) | 1180 | if (uart_circ_empty(xmit)) |
1177 | serial8250_stop_tx(&up->port, 0); | 1181 | __stop_tx(up); |
1178 | } | 1182 | } |
1179 | 1183 | ||
1180 | static _INLINE_ void check_modem_status(struct uart_8250_port *up) | 1184 | static _INLINE_ void check_modem_status(struct uart_8250_port *up) |
@@ -1376,13 +1380,10 @@ static unsigned int serial8250_tx_empty(struct uart_port *port) | |||
1376 | static unsigned int serial8250_get_mctrl(struct uart_port *port) | 1380 | static unsigned int serial8250_get_mctrl(struct uart_port *port) |
1377 | { | 1381 | { |
1378 | struct uart_8250_port *up = (struct uart_8250_port *)port; | 1382 | struct uart_8250_port *up = (struct uart_8250_port *)port; |
1379 | unsigned long flags; | ||
1380 | unsigned char status; | 1383 | unsigned char status; |
1381 | unsigned int ret; | 1384 | unsigned int ret; |
1382 | 1385 | ||
1383 | spin_lock_irqsave(&up->port.lock, flags); | ||
1384 | status = serial_in(up, UART_MSR); | 1386 | status = serial_in(up, UART_MSR); |
1385 | spin_unlock_irqrestore(&up->port.lock, flags); | ||
1386 | 1387 | ||
1387 | ret = 0; | 1388 | ret = 0; |
1388 | if (status & UART_MSR_DCD) | 1389 | if (status & UART_MSR_DCD) |
@@ -2060,7 +2061,8 @@ static void __init serial8250_isa_init_ports(void) | |||
2060 | up->port.ops = &serial8250_pops; | 2061 | up->port.ops = &serial8250_pops; |
2061 | } | 2062 | } |
2062 | 2063 | ||
2063 | for (i = 0, up = serial8250_ports; i < ARRAY_SIZE(old_serial_port); | 2064 | for (i = 0, up = serial8250_ports; |
2065 | i < ARRAY_SIZE(old_serial_port) && i < UART_NR; | ||
2064 | i++, up++) { | 2066 | i++, up++) { |
2065 | up->port.iobase = old_serial_port[i].port; | 2067 | up->port.iobase = old_serial_port[i].port; |
2066 | up->port.irq = irq_canonicalize(old_serial_port[i].irq); | 2068 | up->port.irq = irq_canonicalize(old_serial_port[i].irq); |