@@ -165,6 +165,27 @@ uart_update_mctrl(struct uart_port *port, unsigned int set, unsigned int clear)
#define uart_set_mctrl(port, set) uart_update_mctrl(port, set, 0)
#define uart_clear_mctrl(port, clear) uart_update_mctrl(port, 0, clear)
+static void uart_port_dtr_rts(struct uart_port *uport, int raise)
+{
+ int rs485_on = uport->rs485_config &&
+ (uport->rs485.flags & SER_RS485_ENABLED);
+ int RTS_after_send = !!(uport->rs485.flags & SER_RS485_RTS_AFTER_SEND);
+
+ if (raise) {
+ if (rs485_on && !RTS_after_send) {
+ uart_set_mctrl(uport, TIOCM_DTR);
+ uart_clear_mctrl(uport, TIOCM_RTS);
+ } else {
+ uart_set_mctrl(uport, TIOCM_DTR | TIOCM_RTS);
+ }
+ } else {
+ unsigned int clear = TIOCM_DTR;
+
+ clear |= (!rs485_on || !RTS_after_send) ? TIOCM_RTS : 0;
+ uart_clear_mctrl(uport, clear);
+ }
+}
+
/*
* Startup the port. This will be called once per open. All calls
* will be serialised by the per-port mutex.
@@ -214,7 +235,7 @@ static int uart_port_startup(struct tty_struct *tty, struct uart_state *state,
* port is open and ready to respond.
*/
if (init_hw && C_BAUD(tty))
- uart_set_mctrl(uport, TIOCM_RTS | TIOCM_DTR);
+ uart_port_dtr_rts(uport, 1);
}
/*
@@ -272,7 +293,7 @@ static void uart_shutdown(struct tty_struct *tty, struct uart_state *state)
uport->cons->cflag = tty->termios.c_cflag;
if (!tty || C_HUPCL(tty))
- uart_clear_mctrl(uport, TIOCM_DTR | TIOCM_RTS);
+ uart_port_dtr_rts(uport, 0);
uart_port_shutdown(port);
}
@@ -1658,7 +1679,7 @@ static int uart_carrier_raised(struct tty_port *port)
return 0;
}
-static void uart_dtr_rts(struct tty_port *port, int onoff)
+static void uart_dtr_rts(struct tty_port *port, int raise)
{
struct uart_state *state = container_of(port, struct uart_state, port);
struct uart_port *uport;
@@ -1666,12 +1687,7 @@ static void uart_dtr_rts(struct tty_port *port, int onoff)
uport = uart_port_ref(state);
if (!uport)
return;
-
- if (onoff)
- uart_set_mctrl(uport, TIOCM_DTR | TIOCM_RTS);
- else
- uart_clear_mctrl(uport, TIOCM_DTR | TIOCM_RTS);
-
+ uart_port_dtr_rts(uport, raise);
uart_port_deref(uport);
}
Previously the rs485 settings weren't considered when setting the RTS line, so e.g. closing and reopening a port made serial_core to drive the line as if rs485 was disabled. This patch fixes those issues. Signed-off-by: Rafael Gago Castano <rgc@hms.se> --- drivers/tty/serial/serial_core.c | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-)