diff options
Diffstat (limited to 'drivers/tty/serial/8250/8250_port.c')
-rw-r--r-- | drivers/tty/serial/8250/8250_port.c | 48 |
1 files changed, 40 insertions, 8 deletions
diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c index 60ca19eca1f6..34687c354f5e 100644 --- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c | |||
@@ -132,7 +132,8 @@ static const struct serial8250_config uart_config[] = { | |||
132 | .name = "16C950/954", | 132 | .name = "16C950/954", |
133 | .fifo_size = 128, | 133 | .fifo_size = 128, |
134 | .tx_loadsz = 128, | 134 | .tx_loadsz = 128, |
135 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, | 135 | .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_01, |
136 | .rxtrig_bytes = {16, 32, 112, 120}, | ||
136 | /* UART_CAP_EFR breaks billionon CF bluetooth card. */ | 137 | /* UART_CAP_EFR breaks billionon CF bluetooth card. */ |
137 | .flags = UART_CAP_FIFO | UART_CAP_SLEEP, | 138 | .flags = UART_CAP_FIFO | UART_CAP_SLEEP, |
138 | }, | 139 | }, |
@@ -313,7 +314,11 @@ static const struct serial8250_config uart_config[] = { | |||
313 | /* Uart divisor latch read */ | 314 | /* Uart divisor latch read */ |
314 | static int default_serial_dl_read(struct uart_8250_port *up) | 315 | static int default_serial_dl_read(struct uart_8250_port *up) |
315 | { | 316 | { |
316 | return serial_in(up, UART_DLL) | serial_in(up, UART_DLM) << 8; | 317 | /* Assign these in pieces to truncate any bits above 7. */ |
318 | unsigned char dll = serial_in(up, UART_DLL); | ||
319 | unsigned char dlm = serial_in(up, UART_DLM); | ||
320 | |||
321 | return dll | dlm << 8; | ||
317 | } | 322 | } |
318 | 323 | ||
319 | /* Uart divisor latch write */ | 324 | /* Uart divisor latch write */ |
@@ -1301,9 +1306,11 @@ static void autoconfig(struct uart_8250_port *up) | |||
1301 | serial_out(up, UART_LCR, 0); | 1306 | serial_out(up, UART_LCR, 0); |
1302 | 1307 | ||
1303 | serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO); | 1308 | serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO); |
1304 | scratch = serial_in(up, UART_IIR) >> 6; | ||
1305 | 1309 | ||
1306 | switch (scratch) { | 1310 | /* Assign this as it is to truncate any bits above 7. */ |
1311 | scratch = serial_in(up, UART_IIR); | ||
1312 | |||
1313 | switch (scratch >> 6) { | ||
1307 | case 0: | 1314 | case 0: |
1308 | autoconfig_8250(up); | 1315 | autoconfig_8250(up); |
1309 | break; | 1316 | break; |
@@ -1587,6 +1594,18 @@ static inline void start_tx_rs485(struct uart_port *port) | |||
1587 | if (!(up->port.rs485.flags & SER_RS485_RX_DURING_TX)) | 1594 | if (!(up->port.rs485.flags & SER_RS485_RX_DURING_TX)) |
1588 | serial8250_stop_rx(&up->port); | 1595 | serial8250_stop_rx(&up->port); |
1589 | 1596 | ||
1597 | /* | ||
1598 | * While serial8250_em485_handle_stop_tx() is a noop if | ||
1599 | * em485->active_timer != &em485->stop_tx_timer, it might happen that | ||
1600 | * the timer is still armed and triggers only after the current bunch of | ||
1601 | * chars is send and em485->active_timer == &em485->stop_tx_timer again. | ||
1602 | * So cancel the timer. There is still a theoretical race condition if | ||
1603 | * the timer is already running and only comes around to check for | ||
1604 | * em485->active_timer when &em485->stop_tx_timer is armed again. | ||
1605 | */ | ||
1606 | if (em485->active_timer == &em485->stop_tx_timer) | ||
1607 | hrtimer_try_to_cancel(&em485->stop_tx_timer); | ||
1608 | |||
1590 | em485->active_timer = NULL; | 1609 | em485->active_timer = NULL; |
1591 | 1610 | ||
1592 | mcr = serial8250_in_MCR(up); | 1611 | mcr = serial8250_in_MCR(up); |
@@ -2646,6 +2665,21 @@ static unsigned int serial8250_get_baud_rate(struct uart_port *port, | |||
2646 | struct ktermios *old) | 2665 | struct ktermios *old) |
2647 | { | 2666 | { |
2648 | unsigned int tolerance = port->uartclk / 100; | 2667 | unsigned int tolerance = port->uartclk / 100; |
2668 | unsigned int min; | ||
2669 | unsigned int max; | ||
2670 | |||
2671 | /* | ||
2672 | * Handle magic divisors for baud rates above baud_base on SMSC | ||
2673 | * Super I/O chips. Enable custom rates of clk/4 and clk/8, but | ||
2674 | * disable divisor values beyond 32767, which are unavailable. | ||
2675 | */ | ||
2676 | if (port->flags & UPF_MAGIC_MULTIPLIER) { | ||
2677 | min = port->uartclk / 16 / UART_DIV_MAX >> 1; | ||
2678 | max = (port->uartclk + tolerance) / 4; | ||
2679 | } else { | ||
2680 | min = port->uartclk / 16 / UART_DIV_MAX; | ||
2681 | max = (port->uartclk + tolerance) / 16; | ||
2682 | } | ||
2649 | 2683 | ||
2650 | /* | 2684 | /* |
2651 | * Ask the core to calculate the divisor for us. | 2685 | * Ask the core to calculate the divisor for us. |
@@ -2653,9 +2687,7 @@ static unsigned int serial8250_get_baud_rate(struct uart_port *port, | |||
2653 | * slower than nominal still match standard baud rates without | 2687 | * slower than nominal still match standard baud rates without |
2654 | * causing transmission errors. | 2688 | * causing transmission errors. |
2655 | */ | 2689 | */ |
2656 | return uart_get_baud_rate(port, termios, old, | 2690 | return uart_get_baud_rate(port, termios, old, min, max); |
2657 | port->uartclk / 16 / UART_DIV_MAX, | ||
2658 | (port->uartclk + tolerance) / 16); | ||
2659 | } | 2691 | } |
2660 | 2692 | ||
2661 | void | 2693 | void |
@@ -3241,7 +3273,7 @@ static void serial8250_console_restore(struct uart_8250_port *up) | |||
3241 | 3273 | ||
3242 | serial8250_set_divisor(port, baud, quot, frac); | 3274 | serial8250_set_divisor(port, baud, quot, frac); |
3243 | serial_port_out(port, UART_LCR, up->lcr); | 3275 | serial_port_out(port, UART_LCR, up->lcr); |
3244 | serial8250_out_MCR(up, UART_MCR_DTR | UART_MCR_RTS); | 3276 | serial8250_out_MCR(up, up->mcr | UART_MCR_DTR | UART_MCR_RTS); |
3245 | } | 3277 | } |
3246 | 3278 | ||
3247 | /* | 3279 | /* |