diff options
author | David S. Miller <davem@davemloft.net> | 2010-01-23 01:45:46 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-01-23 01:45:46 -0500 |
commit | 6be325719b3e54624397e413efd4b33a997e55a3 (patch) | |
tree | 57f321a56794cab2222e179b16731e0d76a4a68a /drivers/serial/sh-sci.c | |
parent | 26d92f9276a56d55511a427fb70bd70886af647a (diff) | |
parent | 92dcffb916d309aa01778bf8963a6932e4014d07 (diff) |
Merge branch 'master' of /home/davem/src/GIT/linux-2.6/
Diffstat (limited to 'drivers/serial/sh-sci.c')
-rw-r--r-- | drivers/serial/sh-sci.c | 89 |
1 files changed, 73 insertions, 16 deletions
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index ff38dbdb5c6e..42f3333c4ad0 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c | |||
@@ -222,9 +222,9 @@ static inline void sci_init_pins(struct uart_port *port, unsigned int cflag) | |||
222 | Set SCP6MD1,0 = {01} (output) */ | 222 | Set SCP6MD1,0 = {01} (output) */ |
223 | __raw_writew((data & 0x0fcf) | 0x1000, SCPCR); | 223 | __raw_writew((data & 0x0fcf) | 0x1000, SCPCR); |
224 | 224 | ||
225 | data = ctrl_inb(SCPDR); | 225 | data = __raw_readb(SCPDR); |
226 | /* Set /RTS2 (bit6) = 0 */ | 226 | /* Set /RTS2 (bit6) = 0 */ |
227 | ctrl_outb(data & 0xbf, SCPDR); | 227 | __raw_writeb(data & 0xbf, SCPDR); |
228 | } | 228 | } |
229 | } | 229 | } |
230 | #elif defined(CONFIG_CPU_SUBTYPE_SH7722) | 230 | #elif defined(CONFIG_CPU_SUBTYPE_SH7722) |
@@ -897,11 +897,21 @@ static void sci_shutdown(struct uart_port *port) | |||
897 | static void sci_set_termios(struct uart_port *port, struct ktermios *termios, | 897 | static void sci_set_termios(struct uart_port *port, struct ktermios *termios, |
898 | struct ktermios *old) | 898 | struct ktermios *old) |
899 | { | 899 | { |
900 | unsigned int status, baud, smr_val; | 900 | unsigned int status, baud, smr_val, max_baud; |
901 | int t = -1; | 901 | int t = -1; |
902 | 902 | ||
903 | baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); | 903 | /* |
904 | if (likely(baud)) | 904 | * earlyprintk comes here early on with port->uartclk set to zero. |
905 | * the clock framework is not up and running at this point so here | ||
906 | * we assume that 115200 is the maximum baud rate. please note that | ||
907 | * the baud rate is not programmed during earlyprintk - it is assumed | ||
908 | * that the previous boot loader has enabled required clocks and | ||
909 | * setup the baud rate generator hardware for us already. | ||
910 | */ | ||
911 | max_baud = port->uartclk ? port->uartclk / 16 : 115200; | ||
912 | |||
913 | baud = uart_get_baud_rate(port, termios, old, 0, max_baud); | ||
914 | if (likely(baud && port->uartclk)) | ||
905 | t = SCBRR_VALUE(baud, port->uartclk); | 915 | t = SCBRR_VALUE(baud, port->uartclk); |
906 | 916 | ||
907 | do { | 917 | do { |
@@ -1042,11 +1052,26 @@ static void __devinit sci_init_single(struct platform_device *dev, | |||
1042 | sci_port->port.ops = &sci_uart_ops; | 1052 | sci_port->port.ops = &sci_uart_ops; |
1043 | sci_port->port.iotype = UPIO_MEM; | 1053 | sci_port->port.iotype = UPIO_MEM; |
1044 | sci_port->port.line = index; | 1054 | sci_port->port.line = index; |
1045 | sci_port->port.fifosize = 1; | 1055 | |
1046 | sci_port->iclk = p->clk ? clk_get(&dev->dev, p->clk) : NULL; | 1056 | switch (p->type) { |
1047 | sci_port->dclk = clk_get(&dev->dev, "peripheral_clk"); | 1057 | case PORT_SCIFA: |
1048 | sci_port->enable = sci_clk_enable; | 1058 | sci_port->port.fifosize = 64; |
1049 | sci_port->disable = sci_clk_disable; | 1059 | break; |
1060 | case PORT_SCIF: | ||
1061 | sci_port->port.fifosize = 16; | ||
1062 | break; | ||
1063 | default: | ||
1064 | sci_port->port.fifosize = 1; | ||
1065 | break; | ||
1066 | } | ||
1067 | |||
1068 | if (dev) { | ||
1069 | sci_port->iclk = p->clk ? clk_get(&dev->dev, p->clk) : NULL; | ||
1070 | sci_port->dclk = clk_get(&dev->dev, "peripheral_clk"); | ||
1071 | sci_port->enable = sci_clk_enable; | ||
1072 | sci_port->disable = sci_clk_disable; | ||
1073 | sci_port->port.dev = &dev->dev; | ||
1074 | } | ||
1050 | 1075 | ||
1051 | sci_port->break_timer.data = (unsigned long)sci_port; | 1076 | sci_port->break_timer.data = (unsigned long)sci_port; |
1052 | sci_port->break_timer.function = sci_break_timer; | 1077 | sci_port->break_timer.function = sci_break_timer; |
@@ -1057,7 +1082,6 @@ static void __devinit sci_init_single(struct platform_device *dev, | |||
1057 | 1082 | ||
1058 | sci_port->port.irq = p->irqs[SCIx_TXI_IRQ]; | 1083 | sci_port->port.irq = p->irqs[SCIx_TXI_IRQ]; |
1059 | sci_port->port.flags = p->flags; | 1084 | sci_port->port.flags = p->flags; |
1060 | sci_port->port.dev = &dev->dev; | ||
1061 | sci_port->type = sci_port->port.type = p->type; | 1085 | sci_port->type = sci_port->port.type = p->type; |
1062 | 1086 | ||
1063 | memcpy(&sci_port->irqs, &p->irqs, sizeof(p->irqs)); | 1087 | memcpy(&sci_port->irqs, &p->irqs, sizeof(p->irqs)); |
@@ -1101,7 +1125,7 @@ static void serial_console_write(struct console *co, const char *s, | |||
1101 | sci_port->disable(port); | 1125 | sci_port->disable(port); |
1102 | } | 1126 | } |
1103 | 1127 | ||
1104 | static int __init serial_console_setup(struct console *co, char *options) | 1128 | static int __devinit serial_console_setup(struct console *co, char *options) |
1105 | { | 1129 | { |
1106 | struct sci_port *sci_port; | 1130 | struct sci_port *sci_port; |
1107 | struct uart_port *port; | 1131 | struct uart_port *port; |
@@ -1119,9 +1143,14 @@ static int __init serial_console_setup(struct console *co, char *options) | |||
1119 | if (co->index >= SCI_NPORTS) | 1143 | if (co->index >= SCI_NPORTS) |
1120 | co->index = 0; | 1144 | co->index = 0; |
1121 | 1145 | ||
1122 | sci_port = &sci_ports[co->index]; | 1146 | if (co->data) { |
1123 | port = &sci_port->port; | 1147 | port = co->data; |
1124 | co->data = port; | 1148 | sci_port = to_sci_port(port); |
1149 | } else { | ||
1150 | sci_port = &sci_ports[co->index]; | ||
1151 | port = &sci_port->port; | ||
1152 | co->data = port; | ||
1153 | } | ||
1125 | 1154 | ||
1126 | /* | 1155 | /* |
1127 | * Also need to check port->type, we don't actually have any | 1156 | * Also need to check port->type, we don't actually have any |
@@ -1165,6 +1194,15 @@ static int __init sci_console_init(void) | |||
1165 | return 0; | 1194 | return 0; |
1166 | } | 1195 | } |
1167 | console_initcall(sci_console_init); | 1196 | console_initcall(sci_console_init); |
1197 | |||
1198 | static struct sci_port early_serial_port; | ||
1199 | static struct console early_serial_console = { | ||
1200 | .name = "early_ttySC", | ||
1201 | .write = serial_console_write, | ||
1202 | .flags = CON_PRINTBUFFER, | ||
1203 | }; | ||
1204 | static char early_serial_buf[32]; | ||
1205 | |||
1168 | #endif /* CONFIG_SERIAL_SH_SCI_CONSOLE */ | 1206 | #endif /* CONFIG_SERIAL_SH_SCI_CONSOLE */ |
1169 | 1207 | ||
1170 | #if defined(CONFIG_SERIAL_SH_SCI_CONSOLE) | 1208 | #if defined(CONFIG_SERIAL_SH_SCI_CONSOLE) |
@@ -1250,6 +1288,21 @@ static int __devinit sci_probe(struct platform_device *dev) | |||
1250 | struct sh_sci_priv *priv; | 1288 | struct sh_sci_priv *priv; |
1251 | int i, ret = -EINVAL; | 1289 | int i, ret = -EINVAL; |
1252 | 1290 | ||
1291 | #ifdef CONFIG_SERIAL_SH_SCI_CONSOLE | ||
1292 | if (is_early_platform_device(dev)) { | ||
1293 | if (dev->id == -1) | ||
1294 | return -ENOTSUPP; | ||
1295 | early_serial_console.index = dev->id; | ||
1296 | early_serial_console.data = &early_serial_port.port; | ||
1297 | sci_init_single(NULL, &early_serial_port, dev->id, p); | ||
1298 | serial_console_setup(&early_serial_console, early_serial_buf); | ||
1299 | if (!strstr(early_serial_buf, "keep")) | ||
1300 | early_serial_console.flags |= CON_BOOT; | ||
1301 | register_console(&early_serial_console); | ||
1302 | return 0; | ||
1303 | } | ||
1304 | #endif | ||
1305 | |||
1253 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); | 1306 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); |
1254 | if (!priv) | 1307 | if (!priv) |
1255 | return -ENOMEM; | 1308 | return -ENOMEM; |
@@ -1312,7 +1365,7 @@ static int sci_resume(struct device *dev) | |||
1312 | return 0; | 1365 | return 0; |
1313 | } | 1366 | } |
1314 | 1367 | ||
1315 | static struct dev_pm_ops sci_dev_pm_ops = { | 1368 | static const struct dev_pm_ops sci_dev_pm_ops = { |
1316 | .suspend = sci_suspend, | 1369 | .suspend = sci_suspend, |
1317 | .resume = sci_resume, | 1370 | .resume = sci_resume, |
1318 | }; | 1371 | }; |
@@ -1349,6 +1402,10 @@ static void __exit sci_exit(void) | |||
1349 | uart_unregister_driver(&sci_uart_driver); | 1402 | uart_unregister_driver(&sci_uart_driver); |
1350 | } | 1403 | } |
1351 | 1404 | ||
1405 | #ifdef CONFIG_SERIAL_SH_SCI_CONSOLE | ||
1406 | early_platform_init_buffer("earlyprintk", &sci_driver, | ||
1407 | early_serial_buf, ARRAY_SIZE(early_serial_buf)); | ||
1408 | #endif | ||
1352 | module_init(sci_init); | 1409 | module_init(sci_init); |
1353 | module_exit(sci_exit); | 1410 | module_exit(sci_exit); |
1354 | 1411 | ||