aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/serial_core.h
diff options
context:
space:
mode:
authorPeter Hurley <peter@hurleysoftware.com>2015-01-25 14:44:51 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-02-02 13:11:28 -0500
commit391f93f2ec9f857c83bdd21a14dcf7e699f38579 (patch)
tree72cdba8b46c6fe2700e9fd1b8ed1fe84210cd9ac /include/linux/serial_core.h
parenta4c639b04f301ddc3f71bc0f2600c3759846db43 (diff)
serial: core: Rework hw-assisted flow control support
hw-assisted flow control support was added to the serial core in v3.8 with commits, dba05832cbe4f ("SERIAL: core: add hardware assisted h/w flow control support") 2cbacafd7af0f ("SERIAL: core: add hardware assisted s/w flow control support") 9aba8d5b01119 ("SERIAL: core: add throttle/unthrottle callbacks for hardware assisted flow control") Since then, additional requirements for serial core support have arisen. Specifically, 1. Separate tx and rx flow control settings for UARTs which only support tx flow control (ie., autoCTS). 2. Disable sw-assisted CTS flow control in autoCTS mode 3. Support for RTS flow control by serial core and userspace in autoRTS mode Distinguish mode from capability; introduce UPSTAT_AUTORTS, UPSTAT_AUTOCTS and UPSTAT_AUTOXOFF which, when set by the uart driver, enable serial core support for hw-assisted rx, hw-assisted tx and hw-assisted in-band/IXOFF rx flow control, respectively. [Note: hw-assisted in-band/IXON tx flow control does not require serial core support/intervention and can be enabled by the uart driver when required.] These modes must be set/reset in the driver's set_termios() method, based on termios settings, and thus can be safely queried in any context in which one of the port lock, port mutex or termios rwsem are held. Set these modes in the 2 in-tree drivers, omap-serial and 8250_omap, which currently use UPF_HARD_FLOW/UPF_SOFT_FLOW support. Retain UPF_HARD_FLOW and UPF_SOFT_FLOW as capabilities; re-define UPF_HARD_FLOW as both UPF_AUTO_RTS and UPF_AUTO_CTS to allow for distinct and separate rx and tx flow control capabilities. Disable sw-assisted CTS flow control when UPSTAT_AUTOCTS is enabled. Signed-off-by: Peter Hurley <peter@hurleysoftware.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'include/linux/serial_core.h')
-rw-r--r--include/linux/serial_core.h21
1 files changed, 18 insertions, 3 deletions
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index a0c7033d5f91..baf3e1d08416 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -191,8 +191,10 @@ struct uart_port {
191#define UPF_NO_TXEN_TEST ((__force upf_t) (1 << 15)) 191#define UPF_NO_TXEN_TEST ((__force upf_t) (1 << 15))
192#define UPF_MAGIC_MULTIPLIER ((__force upf_t) ASYNC_MAGIC_MULTIPLIER /* 16 */ ) 192#define UPF_MAGIC_MULTIPLIER ((__force upf_t) ASYNC_MAGIC_MULTIPLIER /* 16 */ )
193 193
194/* Port has hardware-assisted h/w flow control (iow, auto-RTS *not* auto-CTS) */ 194/* Port has hardware-assisted h/w flow control */
195#define UPF_HARD_FLOW ((__force upf_t) (1 << 21)) 195#define UPF_AUTO_CTS ((__force upf_t) (1 << 20))
196#define UPF_AUTO_RTS ((__force upf_t) (1 << 21))
197#define UPF_HARD_FLOW ((__force upf_t) (UPF_AUTO_CTS | UPF_AUTO_RTS))
196/* Port has hardware-assisted s/w flow control */ 198/* Port has hardware-assisted s/w flow control */
197#define UPF_SOFT_FLOW ((__force upf_t) (1 << 22)) 199#define UPF_SOFT_FLOW ((__force upf_t) (1 << 22))
198#define UPF_CONS_FLOW ((__force upf_t) (1 << 23)) 200#define UPF_CONS_FLOW ((__force upf_t) (1 << 23))
@@ -214,11 +216,17 @@ struct uart_port {
214#error Change mask not equivalent to userspace-visible bit defines 216#error Change mask not equivalent to userspace-visible bit defines
215#endif 217#endif
216 218
217 /* status must be updated while holding port lock */ 219 /*
220 * Must hold termios_rwsem, port mutex and port lock to change;
221 * can hold any one lock to read.
222 */
218 upstat_t status; 223 upstat_t status;
219 224
220#define UPSTAT_CTS_ENABLE ((__force upstat_t) (1 << 0)) 225#define UPSTAT_CTS_ENABLE ((__force upstat_t) (1 << 0))
221#define UPSTAT_DCD_ENABLE ((__force upstat_t) (1 << 1)) 226#define UPSTAT_DCD_ENABLE ((__force upstat_t) (1 << 1))
227#define UPSTAT_AUTORTS ((__force upstat_t) (1 << 2))
228#define UPSTAT_AUTOCTS ((__force upstat_t) (1 << 3))
229#define UPSTAT_AUTOXOFF ((__force upstat_t) (1 << 4))
222 230
223 int hw_stopped; /* sw-assisted CTS flow state */ 231 int hw_stopped; /* sw-assisted CTS flow state */
224 unsigned int mctrl; /* current modem ctrl settings */ 232 unsigned int mctrl; /* current modem ctrl settings */
@@ -392,6 +400,13 @@ static inline bool uart_cts_enabled(struct uart_port *uport)
392 return !!(uport->status & UPSTAT_CTS_ENABLE); 400 return !!(uport->status & UPSTAT_CTS_ENABLE);
393} 401}
394 402
403static inline bool uart_softcts_mode(struct uart_port *uport)
404{
405 upstat_t mask = UPSTAT_CTS_ENABLE | UPSTAT_AUTOCTS;
406
407 return ((uport->status & mask) == UPSTAT_CTS_ENABLE);
408}
409
395/* 410/*
396 * The following are helper functions for the low level drivers. 411 * The following are helper functions for the low level drivers.
397 */ 412 */