aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/tty/serial/8250/8250_port.c')
-rw-r--r--drivers/tty/serial/8250/8250_port.c48
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 */
314static int default_serial_dl_read(struct uart_8250_port *up) 315static 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
2661void 2693void
@@ -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/*