mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 19:30:30 +09:00
serial: 8250: reset uart when set baud rate
If external device sends data continuously, then uart is always busy, and baud rate can't be set. It is useful to reset uart and set loop back mode to make sure it is idle. Change-Id: I87286711870ff685ea29e36e61c97d45be5a6d08 Signed-off-by: Huibin Hong <huibin.hong@rock-chips.com>
This commit is contained in:
@@ -2587,6 +2587,10 @@ void serial8250_do_set_divisor(struct uart_port *port, unsigned int baud,
|
||||
{
|
||||
struct uart_8250_port *up = up_to_u8250p(port);
|
||||
|
||||
#ifdef CONFIG_ARCH_ROCKCHIP
|
||||
serial_port_out(port, UART_MCR, UART_MCR_LOOP);
|
||||
#endif
|
||||
|
||||
/* Workaround to enable 115200 baud on OMAP1510 internal ports */
|
||||
if (is_omap1510_8250(up)) {
|
||||
if (baud == 115200) {
|
||||
@@ -2607,6 +2611,13 @@ void serial8250_do_set_divisor(struct uart_port *port, unsigned int baud,
|
||||
|
||||
serial_dl_write(up, quot);
|
||||
|
||||
#ifdef CONFIG_ARCH_ROCKCHIP
|
||||
serial_port_out(port, UART_MCR, up->mcr);
|
||||
if (quot != serial_dl_read(up))
|
||||
pr_warn_ratelimited("ttyS%d set divisor fail, quot:%d != dll,dlh:%d\n",
|
||||
serial_index(port), quot, serial_dl_read(up));
|
||||
#endif
|
||||
|
||||
/* XR17V35x UARTs have an extra fractional divisor register (DLD) */
|
||||
if (up->port.type == PORT_XR17V35X) {
|
||||
/* Preserve bits not related to baudrate; DLD[7:4]. */
|
||||
@@ -2721,6 +2732,7 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios,
|
||||
if ((termios->c_cflag & CREAD) == 0)
|
||||
port->ignore_status_mask |= UART_LSR_DR;
|
||||
|
||||
#ifndef CONFIG_ARCH_ROCKCHIP
|
||||
/*
|
||||
* CTS flow control flag and modem status interrupts
|
||||
*/
|
||||
@@ -2734,6 +2746,7 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios,
|
||||
up->ier |= UART_IER_RTOIE;
|
||||
|
||||
serial_port_out(port, UART_IER, up->ier);
|
||||
#endif
|
||||
|
||||
if (up->capabilities & UART_CAP_EFR) {
|
||||
unsigned char efr = 0;
|
||||
@@ -2752,7 +2765,13 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios,
|
||||
serial_port_out(port, UART_EFR, efr);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ARCH_ROCKCHIP
|
||||
/* Reset uart to make sure it is idle, then set buad rate */
|
||||
serial_port_out(port, 0x88 >> 2, 0x7);
|
||||
#endif
|
||||
|
||||
serial8250_set_divisor(port, baud, quot, frac);
|
||||
|
||||
#ifdef CONFIG_ARCH_ROCKCHIP
|
||||
up->fcr = UART_FCR_ENABLE_FIFO | UART_FCR_T_TRIG_10 | UART_FCR_R_TRIG_10;
|
||||
#endif
|
||||
@@ -2771,6 +2790,23 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios,
|
||||
serial_port_out(port, UART_FCR, up->fcr); /* set fcr */
|
||||
}
|
||||
serial8250_set_mctrl(port, port->mctrl);
|
||||
|
||||
#ifdef CONFIG_ARCH_ROCKCHIP
|
||||
/*
|
||||
* CTS flow control flag and modem status interrupts
|
||||
*/
|
||||
up->ier &= ~UART_IER_MSI;
|
||||
if (!(up->bugs & UART_BUG_NOMSR) &&
|
||||
UART_ENABLE_MS(&up->port, termios->c_cflag))
|
||||
up->ier |= UART_IER_MSI;
|
||||
if (up->capabilities & UART_CAP_UUE)
|
||||
up->ier |= UART_IER_UUE;
|
||||
if (up->capabilities & UART_CAP_RTOIE)
|
||||
up->ier |= UART_IER_RTOIE;
|
||||
|
||||
serial_port_out(port, UART_IER, up->ier);
|
||||
#endif
|
||||
|
||||
spin_unlock_irqrestore(&port->lock, flags);
|
||||
serial8250_rpm_put(up);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user