diff options
-rw-r--r-- | drivers/tty/serial/omap-serial.c | 37 |
1 files changed, 21 insertions, 16 deletions
diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index fb06def4d982..170be2b1cdb1 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c @@ -706,9 +706,10 @@ serial_omap_configure_xonxoff serial_out(up, UART_MCR, up->mcr | UART_MCR_TCRTLR); serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); serial_out(up, UART_TI752_TCR, OMAP_UART_TCR_TRIG); - serial_out(up, UART_EFR, up->efr); serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); serial_out(up, UART_MCR, up->mcr & ~UART_MCR_TCRTLR); + serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); + serial_out(up, UART_EFR, up->efr); serial_out(up, UART_LCR, up->lcr); } @@ -729,7 +730,6 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios, { struct uart_omap_port *up = to_uart_omap_port(port); unsigned char cval = 0; - unsigned char efr = 0; unsigned long flags = 0; unsigned int baud, quot; @@ -839,12 +839,12 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios, serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); - up->efr = serial_in(up, UART_EFR); + up->efr = serial_in(up, UART_EFR) & ~UART_EFR_ECB; up->efr &= ~UART_EFR_SCD; serial_out(up, UART_EFR, up->efr | UART_EFR_ECB); serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); - up->mcr = serial_in(up, UART_MCR); + up->mcr = serial_in(up, UART_MCR) & ~UART_MCR_TCRTLR; serial_out(up, UART_MCR, up->mcr | UART_MCR_TCRTLR); /* FIFO ENABLE, DMA MODE */ @@ -863,9 +863,12 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios, serial_out(up, UART_OMAP_SCR, up->scr); - serial_out(up, UART_EFR, up->efr); + /* Reset UART_MCR_TCRTLR: this must be done with the EFR_ECB bit set */ serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); serial_out(up, UART_MCR, up->mcr); + serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); + serial_out(up, UART_EFR, up->efr); + serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); /* Protocol, Baud Rate, and Interrupt Settings */ @@ -903,21 +906,22 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios, /* Hardware Flow Control Configuration */ - if (termios->c_cflag & CRTSCTS) { - efr |= (UART_EFR_CTS | UART_EFR_RTS); - serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); - - up->mcr = serial_in(up, UART_MCR); - serial_out(up, UART_MCR, up->mcr | UART_MCR_TCRTLR); - + if (termios->c_cflag & CRTSCTS && up->port.flags & UPF_HARD_FLOW) { + /* Enable access to TCR/TLR */ serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); - up->efr = serial_in(up, UART_EFR); serial_out(up, UART_EFR, up->efr | UART_EFR_ECB); + serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); + serial_out(up, UART_MCR, up->mcr | UART_MCR_TCRTLR); serial_out(up, UART_TI752_TCR, OMAP_UART_TCR_TRIG); - serial_out(up, UART_EFR, efr); /* Enable AUTORTS and AUTOCTS */ - serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); + + /* Enable AUTORTS and AUTOCTS */ + up->efr |= UART_EFR_CTS | UART_EFR_RTS; + + /* Disable access to TCR/TLR */ serial_out(up, UART_MCR, up->mcr | UART_MCR_RTS); + serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); + serial_out(up, UART_EFR, up->efr); serial_out(up, UART_LCR, cval); } else { /* Disable AUTORTS and AUTOCTS */ @@ -930,7 +934,8 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios, serial_omap_set_mctrl(&up->port, up->port.mctrl); /* Software Flow Control Configuration */ - serial_omap_configure_xonxoff(up, termios); + if (up->port.flags & UPF_SOFT_FLOW) + serial_omap_configure_xonxoff(up, termios); spin_unlock_irqrestore(&up->port.lock, flags); pm_runtime_mark_last_busy(up->dev); |