diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c index 40ad49d562d7..81c1d3a3ad96 100644 --- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c @@ -2603,6 +2603,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) { @@ -2622,6 +2626,13 @@ void serial8250_do_set_divisor(struct uart_port *port, unsigned int baud, serial_port_out(port, UART_LCR, up->lcr | UART_LCR_DLAB); 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 } EXPORT_SYMBOL_GPL(serial8250_do_set_divisor); @@ -2775,6 +2786,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 */ @@ -2788,6 +2800,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; @@ -2806,7 +2819,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 baud 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 @@ -2825,6 +2844,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);