mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-26 02:39:48 +00:00
serial: core: Consider rs485 settings to drive RTS
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> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
d77dc47fce
commit
a6845e1e1b
1 changed files with 25 additions and 9 deletions
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue