diff options
author | Paul Mundt <lethal@linux-sh.org> | 2011-11-24 18:35:49 +0900 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2011-11-24 18:35:49 +0900 |
commit | 0979e0e641d21d3bb318da90a64fc0024a95f50e (patch) | |
tree | 0f91fe576992c8e95af6a7a43c39374a68f48d8e /drivers/tty/serial/sh-sci.c | |
parent | a9098b372606a15745cdeb012de4ee91c0df82c4 (diff) |
serial: sh-sci: Fix up SCFCR handling.
Presently there are a few places that make assumptions about the
existence of SCFCR, which doesn't hold true for several port types. While
generally harmless, this does lead to bogus reads/writes in both the
termios/runtime PM cases that are better off simply never being made in
the first place.
While we're at it, also get rid of a straggling PORT_SCI check that
infers all non-SCI ports contain SCFCR. This doesn't presently have any
impact, but as we're now able to test for the existence of registers
without defering to the port type we future proof for additional port
types.
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'drivers/tty/serial/sh-sci.c')
-rw-r--r-- | drivers/tty/serial/sh-sci.c | 33 |
1 files changed, 28 insertions, 5 deletions
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index aff9d612dff0..c13910587bc3 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -1652,6 +1652,7 @@ static unsigned int sci_scbrr_calc(unsigned int algo_id, unsigned int bps, static void sci_reset(struct uart_port *port) { + struct plat_sci_reg *reg; unsigned int status; do { @@ -1660,7 +1661,8 @@ static void sci_reset(struct uart_port *port) sci_out(port, SCSCR, 0x00); /* TE=0, RE=0, CKE1=0 */ - if (port->type != PORT_SCI) + reg = sci_getreg(port, SCFCR); + if (reg->size) sci_out(port, SCFCR, SCFCR_RFRST | SCFCR_TFRST); } @@ -1668,9 +1670,9 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) { struct sci_port *s = to_sci_port(port); + struct plat_sci_reg *reg; unsigned int baud, smr_val, max_baud; int t = -1; - u16 scfcr = 0; /* * earlyprintk comes here early on with port->uartclk set to zero. @@ -1720,7 +1722,18 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, } sci_init_pins(port, termios->c_cflag); - sci_out(port, SCFCR, scfcr | ((termios->c_cflag & CRTSCTS) ? SCFCR_MCE : 0)); + + reg = sci_getreg(port, SCFCR); + if (reg->size) { + unsigned short ctrl; + + ctrl = sci_in(port, SCFCR); + if (termios->c_cflag & CRTSCTS) + ctrl |= SCFCR_MCE; + else + ctrl &= ~SCFCR_MCE; + sci_out(port, SCFCR, ctrl); + } sci_out(port, SCSCR, s->cfg->scscr); @@ -2113,9 +2126,16 @@ static int sci_runtime_suspend(struct device *dev) struct uart_port *port = &sci_port->port; if (uart_console(port)) { + struct plat_sci_reg *reg; + sci_port->saved_smr = sci_in(port, SCSMR); sci_port->saved_brr = sci_in(port, SCBRR); - sci_port->saved_fcr = sci_in(port, SCFCR); + + reg = sci_getreg(port, SCFCR); + if (reg->size) + sci_port->saved_fcr = sci_in(port, SCFCR); + else + sci_port->saved_fcr = 0; } return 0; } @@ -2129,7 +2149,10 @@ static int sci_runtime_resume(struct device *dev) sci_reset(port); sci_out(port, SCSMR, sci_port->saved_smr); sci_out(port, SCBRR, sci_port->saved_brr); - sci_out(port, SCFCR, sci_port->saved_fcr); + + if (sci_port->saved_fcr) + sci_out(port, SCFCR, sci_port->saved_fcr); + sci_out(port, SCSCR, sci_port->cfg->scscr); } return 0; |