diff options
author | Baurzhan Ismagulov <ibr@radix50.net> | 2010-11-11 10:53:03 +0100 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-11-11 11:35:59 -0800 |
commit | 5b04ec4ad8e2ffdc9d1f27fd6eb5118e919bc87d (patch) | |
tree | 5e5b6ce308c019c9d8e0e3ace7afcae16e6acedc /drivers/serial/cpm_uart | |
parent | 63295cb2ff4329f563579f3d20c5855a96a866d5 (diff) |
serial: cpm_uat: reducing CPM serial latency
Setting Rx FIFO size to 1 reduces reader process wakeup latency up to
20x for baud rates <= 9600. This patch sets the Rx FIFO size to 1 for
baud rates <= 9600 or if low latency has been requested for the tty.
Signed-off-by: Michael Trimarchi <michael@gandalf.sssup.it>
Signed-off-by: Bruno Morelli <bruno@evidence.eu.com>
Signed-off-by: Baurzhan Ismagulov <ibr@radix50.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/serial/cpm_uart')
-rw-r--r-- | drivers/serial/cpm_uart/cpm_uart_core.c | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c index f2b8adcc6c92..8692ff98fc07 100644 --- a/drivers/serial/cpm_uart/cpm_uart_core.c +++ b/drivers/serial/cpm_uart/cpm_uart_core.c @@ -72,6 +72,8 @@ static void cpm_uart_initbd(struct uart_cpm_port *pinfo); /**************************************************************/ +#define HW_BUF_SPD_THRESHOLD 9600 + /* * Check, if transmit buffers are processed */ @@ -503,6 +505,11 @@ static void cpm_uart_set_termios(struct uart_port *port, pr_debug("CPM uart[%d]:set_termios\n", port->line); baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 16); + if (baud <= HW_BUF_SPD_THRESHOLD || + (pinfo->port.state && pinfo->port.state->port.tty->low_latency)) + pinfo->rx_fifosize = 1; + else + pinfo->rx_fifosize = RX_BUF_SIZE; /* Character length programmed into the mode register is the * sum of: 1 start bit, number of data bits, 0 or 1 parity bit, @@ -594,6 +601,17 @@ static void cpm_uart_set_termios(struct uart_port *port, */ bits++; if (IS_SMC(pinfo)) { + /* + * MRBLR can be changed while an SMC/SCC is operating only + * if it is done in a single bus cycle with one 16-bit move + * (not two 8-bit bus cycles back-to-back). This occurs when + * the cp shifts control to the next RxBD, so the change does + * not take effect immediately. To guarantee the exact RxBD + * on which the change occurs, change MRBLR only while the + * SMC/SCC receiver is disabled. + */ + out_be16(&pinfo->smcup->smc_mrblr, pinfo->rx_fifosize); + /* Set the mode register. We want to keep a copy of the * enables, because we want to put them back if they were * present. @@ -604,6 +622,7 @@ static void cpm_uart_set_termios(struct uart_port *port, out_be16(&smcp->smc_smcmr, smcr_mk_clen(bits) | cval | SMCMR_SM_UART | prev_mode); } else { + out_be16(&pinfo->sccup->scc_genscc.scc_mrblr, pinfo->rx_fifosize); out_be16(&sccp->scc_psmr, (sbits << 12) | scval); } |