aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/serial/sh-sci.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2010-01-23 01:45:46 -0500
committerDavid S. Miller <davem@davemloft.net>2010-01-23 01:45:46 -0500
commit6be325719b3e54624397e413efd4b33a997e55a3 (patch)
tree57f321a56794cab2222e179b16731e0d76a4a68a /drivers/serial/sh-sci.c
parent26d92f9276a56d55511a427fb70bd70886af647a (diff)
parent92dcffb916d309aa01778bf8963a6932e4014d07 (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.c89
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)
897static void sci_set_termios(struct uart_port *port, struct ktermios *termios, 897static 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
1104static int __init serial_console_setup(struct console *co, char *options) 1128static 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}
1167console_initcall(sci_console_init); 1196console_initcall(sci_console_init);
1197
1198static struct sci_port early_serial_port;
1199static struct console early_serial_console = {
1200 .name = "early_ttySC",
1201 .write = serial_console_write,
1202 .flags = CON_PRINTBUFFER,
1203};
1204static 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
1315static struct dev_pm_ops sci_dev_pm_ops = { 1368static 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
1406early_platform_init_buffer("earlyprintk", &sci_driver,
1407 early_serial_buf, ARRAY_SIZE(early_serial_buf));
1408#endif
1352module_init(sci_init); 1409module_init(sci_init);
1353module_exit(sci_exit); 1410module_exit(sci_exit);
1354 1411