aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty/serial/sh-sci.c
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2011-11-24 04:35:49 -0500
committerPaul Mundt <lethal@linux-sh.org>2011-11-24 04:35:49 -0500
commit0979e0e641d21d3bb318da90a64fc0024a95f50e (patch)
tree0f91fe576992c8e95af6a7a43c39374a68f48d8e /drivers/tty/serial/sh-sci.c
parenta9098b372606a15745cdeb012de4ee91c0df82c4 (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.c33
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,
1652 1652
1653static void sci_reset(struct uart_port *port) 1653static void sci_reset(struct uart_port *port)
1654{ 1654{
1655 struct plat_sci_reg *reg;
1655 unsigned int status; 1656 unsigned int status;
1656 1657
1657 do { 1658 do {
@@ -1660,7 +1661,8 @@ static void sci_reset(struct uart_port *port)
1660 1661
1661 sci_out(port, SCSCR, 0x00); /* TE=0, RE=0, CKE1=0 */ 1662 sci_out(port, SCSCR, 0x00); /* TE=0, RE=0, CKE1=0 */
1662 1663
1663 if (port->type != PORT_SCI) 1664 reg = sci_getreg(port, SCFCR);
1665 if (reg->size)
1664 sci_out(port, SCFCR, SCFCR_RFRST | SCFCR_TFRST); 1666 sci_out(port, SCFCR, SCFCR_RFRST | SCFCR_TFRST);
1665} 1667}
1666 1668
@@ -1668,9 +1670,9 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
1668 struct ktermios *old) 1670 struct ktermios *old)
1669{ 1671{
1670 struct sci_port *s = to_sci_port(port); 1672 struct sci_port *s = to_sci_port(port);
1673 struct plat_sci_reg *reg;
1671 unsigned int baud, smr_val, max_baud; 1674 unsigned int baud, smr_val, max_baud;
1672 int t = -1; 1675 int t = -1;
1673 u16 scfcr = 0;
1674 1676
1675 /* 1677 /*
1676 * earlyprintk comes here early on with port->uartclk set to zero. 1678 * 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,
1720 } 1722 }
1721 1723
1722 sci_init_pins(port, termios->c_cflag); 1724 sci_init_pins(port, termios->c_cflag);
1723 sci_out(port, SCFCR, scfcr | ((termios->c_cflag & CRTSCTS) ? SCFCR_MCE : 0)); 1725
1726 reg = sci_getreg(port, SCFCR);
1727 if (reg->size) {
1728 unsigned short ctrl;
1729
1730 ctrl = sci_in(port, SCFCR);
1731 if (termios->c_cflag & CRTSCTS)
1732 ctrl |= SCFCR_MCE;
1733 else
1734 ctrl &= ~SCFCR_MCE;
1735 sci_out(port, SCFCR, ctrl);
1736 }
1724 1737
1725 sci_out(port, SCSCR, s->cfg->scscr); 1738 sci_out(port, SCSCR, s->cfg->scscr);
1726 1739
@@ -2113,9 +2126,16 @@ static int sci_runtime_suspend(struct device *dev)
2113 struct uart_port *port = &sci_port->port; 2126 struct uart_port *port = &sci_port->port;
2114 2127
2115 if (uart_console(port)) { 2128 if (uart_console(port)) {
2129 struct plat_sci_reg *reg;
2130
2116 sci_port->saved_smr = sci_in(port, SCSMR); 2131 sci_port->saved_smr = sci_in(port, SCSMR);
2117 sci_port->saved_brr = sci_in(port, SCBRR); 2132 sci_port->saved_brr = sci_in(port, SCBRR);
2118 sci_port->saved_fcr = sci_in(port, SCFCR); 2133
2134 reg = sci_getreg(port, SCFCR);
2135 if (reg->size)
2136 sci_port->saved_fcr = sci_in(port, SCFCR);
2137 else
2138 sci_port->saved_fcr = 0;
2119 } 2139 }
2120 return 0; 2140 return 0;
2121} 2141}
@@ -2129,7 +2149,10 @@ static int sci_runtime_resume(struct device *dev)
2129 sci_reset(port); 2149 sci_reset(port);
2130 sci_out(port, SCSMR, sci_port->saved_smr); 2150 sci_out(port, SCSMR, sci_port->saved_smr);
2131 sci_out(port, SCBRR, sci_port->saved_brr); 2151 sci_out(port, SCBRR, sci_port->saved_brr);
2132 sci_out(port, SCFCR, sci_port->saved_fcr); 2152
2153 if (sci_port->saved_fcr)
2154 sci_out(port, SCFCR, sci_port->saved_fcr);
2155
2133 sci_out(port, SCSCR, sci_port->cfg->scscr); 2156 sci_out(port, SCSCR, sci_port->cfg->scscr);
2134 } 2157 }
2135 return 0; 2158 return 0;