|
@@ -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);
|
|
|
}
|
|
|
|