diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c index 6b6909d9c005..bc968143fb97 100644 --- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c @@ -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);