summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2012-04-17 16:34:13 +0100
committerRussell King <rmk+kernel@arm.linux.org.uk>2012-11-04 11:25:54 +0000
commit2cbacafd7af0f1cc7a433668c662a91ba6aabc1b (patch)
treebe2e5735b395cba0bfcaf89c312a3fbdce7b05c3
parentdec94e70e12c39440e63159e0050d46795dfcf09 (diff)
downloadlinux-2cbacafd7af0f1cc7a433668c662a91ba6aabc1b.tar.gz
linux-2cbacafd7af0f1cc7a433668c662a91ba6aabc1b.tar.bz2
linux-2cbacafd7af0f1cc7a433668c662a91ba6aabc1b.zip
SERIAL: core: add hardware assisted s/w flow control support
Ports which are capable of handling s/w flow control in hardware to know when the s/w flow control termios settings are changed. Add a flag to allow the low level serial drivers to indicate that they support this, and these changes should be propagated to them. Acked-by: Alan Cox <alan@linux.intel.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r--drivers/tty/serial/serial_core.c16
-rw-r--r--include/linux/serial_core.h2
2 files changed, 16 insertions, 2 deletions
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
index bc2065d323b9..bd10bbd56446 100644
--- a/drivers/tty/serial/serial_core.c
+++ b/drivers/tty/serial/serial_core.c
@@ -1213,7 +1213,19 @@ static void uart_set_termios(struct tty_struct *tty,
struct uart_port *uport = state->uart_port;
unsigned long flags;
unsigned int cflag = tty->termios.c_cflag;
+ unsigned int iflag_mask = IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK;
+ bool sw_changed = false;
+ /*
+ * Drivers doing software flow control also need to know
+ * about changes to these input settings.
+ */
+ if (uport->flags & UPF_SOFT_FLOW) {
+ iflag_mask |= IXANY|IXON|IXOFF;
+ sw_changed =
+ tty->termios.c_cc[VSTART] != old_termios->c_cc[VSTART] ||
+ tty->termios.c_cc[VSTOP] != old_termios->c_cc[VSTOP];
+ }
/*
* These are the bits that are used to setup various
@@ -1221,11 +1233,11 @@ static void uart_set_termios(struct tty_struct *tty,
* bits in c_cflag; c_[io]speed will always be set
* appropriately by set_termios() in tty_ioctl.c
*/
-#define RELEVANT_IFLAG(iflag) ((iflag) & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
if ((cflag ^ old_termios->c_cflag) == 0 &&
tty->termios.c_ospeed == old_termios->c_ospeed &&
tty->termios.c_ispeed == old_termios->c_ispeed &&
- RELEVANT_IFLAG(tty->termios.c_iflag ^ old_termios->c_iflag) == 0) {
+ ((tty->termios.c_iflag ^ old_termios->c_iflag) & iflag_mask) == 0 &&
+ !sw_changed) {
return;
}
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index 3c430228d232..00051388de3c 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -163,6 +163,8 @@ struct uart_port {
#define UPF_BUGGY_UART ((__force upf_t) (1 << 14))
#define UPF_NO_TXEN_TEST ((__force upf_t) (1 << 15))
#define UPF_MAGIC_MULTIPLIER ((__force upf_t) (1 << 16))
+/* Port has hardware-assisted s/w flow control */
+#define UPF_SOFT_FLOW ((__force upf_t) (1 << 22))
#define UPF_CONS_FLOW ((__force upf_t) (1 << 23))
#define UPF_SHARE_IRQ ((__force upf_t) (1 << 24))
#define UPF_EXAR_EFR ((__force upf_t) (1 << 25))