From 04c6c826947fe0a25dfa5a87f0b53f25fe154434 Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 17 Apr 2012 17:23:14 +0100 Subject: [PATCH] --- yaml --- r: 339162 b: refs/heads/master c: 9aba8d5b011193c8e01d565c5b585df5b94f1db2 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/drivers/tty/serial/serial_core.c | 31 ++++++++++++++++++++++---- trunk/include/linux/serial_core.h | 2 ++ 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/[refs] b/[refs] index f5023b86025c..d9d31eb1ace3 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: dba05832cbe4f305dfd998fb26d7c685d91fbbd8 +refs/heads/master: 9aba8d5b011193c8e01d565c5b585df5b94f1db2 diff --git a/trunk/drivers/tty/serial/serial_core.c b/trunk/drivers/tty/serial/serial_core.c index 9d8796e77188..098bb99c2b9f 100644 --- a/trunk/drivers/tty/serial/serial_core.c +++ b/trunk/drivers/tty/serial/serial_core.c @@ -610,27 +610,50 @@ static void uart_send_xchar(struct tty_struct *tty, char ch) static void uart_throttle(struct tty_struct *tty) { struct uart_state *state = tty->driver_data; + struct uart_port *port = state->uart_port; + uint32_t mask = 0; if (I_IXOFF(tty)) + mask |= UPF_SOFT_FLOW; + if (tty->termios.c_cflag & CRTSCTS) + mask |= UPF_HARD_FLOW; + + if (port->flags & mask) { + port->ops->throttle(port); + mask &= ~port->flags; + } + + if (mask & UPF_SOFT_FLOW) uart_send_xchar(tty, STOP_CHAR(tty)); - if (tty->termios.c_cflag & CRTSCTS) - uart_clear_mctrl(state->uart_port, TIOCM_RTS); + if (mask & UPF_HARD_FLOW) + uart_clear_mctrl(port, TIOCM_RTS); } static void uart_unthrottle(struct tty_struct *tty) { struct uart_state *state = tty->driver_data; struct uart_port *port = state->uart_port; + uint32_t mask = 0; - if (I_IXOFF(tty)) { + if (I_IXOFF(tty)) + mask |= UPF_SOFT_FLOW; + if (tty->termios.c_cflag & CRTSCTS) + mask |= UPF_HARD_FLOW; + + if (port->flags & mask) { + port->ops->unthrottle(port); + mask &= ~port->flags; + } + + if (mask & UPF_SOFT_FLOW) { if (port->x_char) port->x_char = 0; else uart_send_xchar(tty, START_CHAR(tty)); } - if (tty->termios.c_cflag & CRTSCTS) + if (mask & UPF_HARD_FLOW) uart_set_mctrl(port, TIOCM_RTS); } diff --git a/trunk/include/linux/serial_core.h b/trunk/include/linux/serial_core.h index e2cda5d04e48..c6690a2a27fb 100644 --- a/trunk/include/linux/serial_core.h +++ b/trunk/include/linux/serial_core.h @@ -46,6 +46,8 @@ struct uart_ops { unsigned int (*get_mctrl)(struct uart_port *); void (*stop_tx)(struct uart_port *); void (*start_tx)(struct uart_port *); + void (*throttle)(struct uart_port *); + void (*unthrottle)(struct uart_port *); void (*send_xchar)(struct uart_port *, char ch); void (*stop_rx)(struct uart_port *); void (*enable_ms)(struct uart_port *);