static void serial_omap_set_mctrl(struct uart_port *port, unsigned int mctrl)
{
struct uart_omap_port *up = to_uart_omap_port(port);
- unsigned char mcr = 0, old_mcr;
+ unsigned char mcr = 0, old_mcr, lcr;
dev_dbg(up->port.dev, "serial_omap_set_mctrl+%d\n", up->port.line);
if (mctrl & TIOCM_RTS)
UART_MCR_DTR | UART_MCR_RTS);
up->mcr = old_mcr | mcr;
serial_out(up, UART_MCR, up->mcr);
+
+ /* Turn off autoRTS if RTS is lowered; restore autoRTS if RTS raised */
+ lcr = serial_in(up, UART_LCR);
+ serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
+ if ((mctrl & TIOCM_RTS) && (port->status & UPSTAT_AUTORTS))
+ up->efr |= UART_EFR_RTS;
+ else
+ up->efr &= UART_EFR_RTS;
+ serial_out(up, UART_EFR, up->efr);
+ serial_out(up, UART_LCR, lcr);
+
pm_runtime_mark_last_busy(up->dev);
pm_runtime_put_autosuspend(up->dev);
}
* (they will be reenabled in set_termios())
*/
serial_omap_clear_fifos(up);
- /* For Hardware flow control */
- serial_out(up, UART_MCR, UART_MCR_RTS);
/*
* Clear the interrupt registers.
up->port.status &= ~(UPSTAT_AUTOCTS | UPSTAT_AUTORTS | UPSTAT_AUTOXOFF);
if (termios->c_cflag & CRTSCTS && up->port.flags & UPF_HARD_FLOW) {
- /* Enable AUTORTS and AUTOCTS */
+ /* Enable AUTOCTS (autoRTS is enabled when RTS is raised) */
up->port.status |= UPSTAT_AUTOCTS | UPSTAT_AUTORTS;
- up->efr |= UART_EFR_CTS | UART_EFR_RTS;
-
- /* Ensure MCR RTS is asserted */
- up->mcr |= UART_MCR_RTS;
+ up->efr |= UART_EFR_CTS;
} else {
/* Disable AUTORTS and AUTOCTS */
up->efr &= ~(UART_EFR_CTS | UART_EFR_RTS);