Commit 7b6fd3bf82c4901f6ba0101ba71a5c507c24f9cf

Authored by Magnus Damm
Committed by Paul Mundt
1 parent 0eb37e26ed

sh-sci: Extend sh-sci driver with early console V2

This is V2 of early serial console support for the sh-sci
driver. The early serial console is using early platform
devices and "earlyprintk". To use this feature the early
platform devices must be broken out to one device per port
and the desired port should be selected on the kernel command
line like: "earlyprintk=sh-sci.N[,baudrate][,keep]"

Signed-off-by: Magnus Damm <damm@opensource.se>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>

Showing 3 changed files with 49 additions and 18 deletions Side-by-side Diff

arch/sh/kernel/early_printk.c
... ... @@ -191,15 +191,7 @@
191 191 * Setup a default console, if more than one is compiled in, rely on the
192 192 * earlyprintk= parsing to give priority.
193 193 */
194   -static struct console *early_console =
195   -#ifdef CONFIG_SH_STANDARD_BIOS
196   - &bios_console
197   -#elif defined(CONFIG_EARLY_SCIF_CONSOLE)
198   - &scif_console
199   -#else
200   - NULL
201   -#endif
202   - ;
  194 +static struct console *early_console;
203 195  
204 196 static int __init setup_early_printk(char *buf)
205 197 {
arch/sh/kernel/setup.c
... ... @@ -423,6 +423,9 @@
423 423  
424 424 plat_early_device_setup();
425 425  
  426 + /* Let earlyprintk output early console messages */
  427 + early_platform_driver_probe("earlyprintk", 1, 1);
  428 +
426 429 sh_mv_setup();
427 430  
428 431 /*
drivers/serial/sh-sci.c
... ... @@ -1043,11 +1043,15 @@
1043 1043 sci_port->port.iotype = UPIO_MEM;
1044 1044 sci_port->port.line = index;
1045 1045 sci_port->port.fifosize = 1;
1046   - sci_port->iclk = p->clk ? clk_get(&dev->dev, p->clk) : NULL;
1047   - sci_port->dclk = clk_get(&dev->dev, "peripheral_clk");
1048   - sci_port->enable = sci_clk_enable;
1049   - sci_port->disable = sci_clk_disable;
1050 1046  
  1047 + if (dev) {
  1048 + sci_port->iclk = p->clk ? clk_get(&dev->dev, p->clk) : NULL;
  1049 + sci_port->dclk = clk_get(&dev->dev, "peripheral_clk");
  1050 + sci_port->enable = sci_clk_enable;
  1051 + sci_port->disable = sci_clk_disable;
  1052 + sci_port->port.dev = &dev->dev;
  1053 + }
  1054 +
1051 1055 sci_port->break_timer.data = (unsigned long)sci_port;
1052 1056 sci_port->break_timer.function = sci_break_timer;
1053 1057 init_timer(&sci_port->break_timer);
... ... @@ -1057,7 +1061,6 @@
1057 1061  
1058 1062 sci_port->port.irq = p->irqs[SCIx_TXI_IRQ];
1059 1063 sci_port->port.flags = p->flags;
1060   - sci_port->port.dev = &dev->dev;
1061 1064 sci_port->type = sci_port->port.type = p->type;
1062 1065  
1063 1066 memcpy(&sci_port->irqs, &p->irqs, sizeof(p->irqs));
... ... @@ -1101,7 +1104,7 @@
1101 1104 sci_port->disable(port);
1102 1105 }
1103 1106  
1104   -static int __init serial_console_setup(struct console *co, char *options)
  1107 +static int __devinit serial_console_setup(struct console *co, char *options)
1105 1108 {
1106 1109 struct sci_port *sci_port;
1107 1110 struct uart_port *port;
... ... @@ -1119,9 +1122,14 @@
1119 1122 if (co->index >= SCI_NPORTS)
1120 1123 co->index = 0;
1121 1124  
1122   - sci_port = &sci_ports[co->index];
1123   - port = &sci_port->port;
1124   - co->data = port;
  1125 + if (co->data) {
  1126 + port = co->data;
  1127 + sci_port = to_sci_port(port);
  1128 + } else {
  1129 + sci_port = &sci_ports[co->index];
  1130 + port = &sci_port->port;
  1131 + co->data = port;
  1132 + }
1125 1133  
1126 1134 /*
1127 1135 * Also need to check port->type, we don't actually have any
... ... @@ -1165,6 +1173,15 @@
1165 1173 return 0;
1166 1174 }
1167 1175 console_initcall(sci_console_init);
  1176 +
  1177 +static struct sci_port early_serial_port;
  1178 +static struct console early_serial_console = {
  1179 + .name = "early_ttySC",
  1180 + .write = serial_console_write,
  1181 + .flags = CON_PRINTBUFFER,
  1182 +};
  1183 +static char early_serial_buf[32];
  1184 +
1168 1185 #endif /* CONFIG_SERIAL_SH_SCI_CONSOLE */
1169 1186  
1170 1187 #if defined(CONFIG_SERIAL_SH_SCI_CONSOLE)
... ... @@ -1250,6 +1267,21 @@
1250 1267 struct sh_sci_priv *priv;
1251 1268 int i, ret = -EINVAL;
1252 1269  
  1270 +#ifdef CONFIG_SERIAL_SH_SCI_CONSOLE
  1271 + if (is_early_platform_device(dev)) {
  1272 + if (dev->id == -1)
  1273 + return -ENOTSUPP;
  1274 + early_serial_console.index = dev->id;
  1275 + early_serial_console.data = &early_serial_port.port;
  1276 + sci_init_single(NULL, &early_serial_port, dev->id, p);
  1277 + serial_console_setup(&early_serial_console, early_serial_buf);
  1278 + if (!strstr(early_serial_buf, "keep"))
  1279 + early_serial_console.flags |= CON_BOOT;
  1280 + register_console(&early_serial_console);
  1281 + return 0;
  1282 + }
  1283 +#endif
  1284 +
1253 1285 priv = kzalloc(sizeof(*priv), GFP_KERNEL);
1254 1286 if (!priv)
1255 1287 return -ENOMEM;
... ... @@ -1349,6 +1381,10 @@
1349 1381 uart_unregister_driver(&sci_uart_driver);
1350 1382 }
1351 1383  
  1384 +#ifdef CONFIG_SERIAL_SH_SCI_CONSOLE
  1385 +early_platform_init_buffer("earlyprintk", &sci_driver,
  1386 + early_serial_buf, ARRAY_SIZE(early_serial_buf));
  1387 +#endif
1352 1388 module_init(sci_init);
1353 1389 module_exit(sci_exit);
1354 1390