aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty/serial/serial_core.c
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2012-04-17 12:23:14 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2012-11-04 06:25:56 -0500
commit9aba8d5b011193c8e01d565c5b585df5b94f1db2 (patch)
tree4f45580d7310ea7ea7dba87a237732f0580ecb36 /drivers/tty/serial/serial_core.c
parentdba05832cbe4f305dfd998fb26d7c685d91fbbd8 (diff)
SERIAL: core: add throttle/unthrottle callbacks for hardware assisted flow control
Add two callbacks for hardware assisted flow control; we need to know when the tty layers want us to stop and restart due to their buffer levels. Call a driver specific throttle/unthrottle function if and only if the driver indicates that it is using an enabled hardware assisted flow control method, otherwise fall back to the non-hardware assisted methods. Acked-by: Alan Cox <alan@linux.intel.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'drivers/tty/serial/serial_core.c')
-rw-r--r--drivers/tty/serial/serial_core.c31
1 files changed, 27 insertions, 4 deletions
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
index 9d8796e77188..098bb99c2b9f 100644
--- a/drivers/tty/serial/serial_core.c
+++ b/drivers/tty/serial/serial_core.c
@@ -610,27 +610,50 @@ static void uart_send_xchar(struct tty_struct *tty, char ch)
610static void uart_throttle(struct tty_struct *tty) 610static void uart_throttle(struct tty_struct *tty)
611{ 611{
612 struct uart_state *state = tty->driver_data; 612 struct uart_state *state = tty->driver_data;
613 struct uart_port *port = state->uart_port;
614 uint32_t mask = 0;
613 615
614 if (I_IXOFF(tty)) 616 if (I_IXOFF(tty))
617 mask |= UPF_SOFT_FLOW;
618 if (tty->termios.c_cflag & CRTSCTS)
619 mask |= UPF_HARD_FLOW;
620
621 if (port->flags & mask) {
622 port->ops->throttle(port);
623 mask &= ~port->flags;
624 }
625
626 if (mask & UPF_SOFT_FLOW)
615 uart_send_xchar(tty, STOP_CHAR(tty)); 627 uart_send_xchar(tty, STOP_CHAR(tty));
616 628
617 if (tty->termios.c_cflag & CRTSCTS) 629 if (mask & UPF_HARD_FLOW)
618 uart_clear_mctrl(state->uart_port, TIOCM_RTS); 630 uart_clear_mctrl(port, TIOCM_RTS);
619} 631}
620 632
621static void uart_unthrottle(struct tty_struct *tty) 633static void uart_unthrottle(struct tty_struct *tty)
622{ 634{
623 struct uart_state *state = tty->driver_data; 635 struct uart_state *state = tty->driver_data;
624 struct uart_port *port = state->uart_port; 636 struct uart_port *port = state->uart_port;
637 uint32_t mask = 0;
625 638
626 if (I_IXOFF(tty)) { 639 if (I_IXOFF(tty))
640 mask |= UPF_SOFT_FLOW;
641 if (tty->termios.c_cflag & CRTSCTS)
642 mask |= UPF_HARD_FLOW;
643
644 if (port->flags & mask) {
645 port->ops->unthrottle(port);
646 mask &= ~port->flags;
647 }
648
649 if (mask & UPF_SOFT_FLOW) {
627 if (port->x_char) 650 if (port->x_char)
628 port->x_char = 0; 651 port->x_char = 0;
629 else 652 else
630 uart_send_xchar(tty, START_CHAR(tty)); 653 uart_send_xchar(tty, START_CHAR(tty));
631 } 654 }
632 655
633 if (tty->termios.c_cflag & CRTSCTS) 656 if (mask & UPF_HARD_FLOW)
634 uart_set_mctrl(port, TIOCM_RTS); 657 uart_set_mctrl(port, TIOCM_RTS);
635} 658}
636 659