Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Magnus Damm and committed by
Paul Mundt
7b6fd3bf 0eb37e26

+49 -18
+1 -9
arch/sh/kernel/early_printk.c
··· 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 {
+3
arch/sh/kernel/setup.c
··· 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 /*
+45 -9
drivers/serial/sh-sci.c
··· 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; 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 + } 1050 1054 1051 1055 sci_port->break_timer.data = (unsigned long)sci_port; 1052 1056 sci_port->break_timer.function = sci_break_timer; ··· 1061 1057 1062 1058 sci_port->port.irq = p->irqs[SCIx_TXI_IRQ]; 1063 1059 sci_port->port.flags = p->flags; 1064 - sci_port->port.dev = &dev->dev; 1065 1060 sci_port->type = sci_port->port.type = p->type; 1066 1061 1067 1062 memcpy(&sci_port->irqs, &p->irqs, sizeof(p->irqs)); ··· 1104 1101 sci_port->disable(port); 1105 1102 } 1106 1103 1107 - static int __init serial_console_setup(struct console *co, char *options) 1104 + static int __devinit serial_console_setup(struct console *co, char *options) 1108 1105 { 1109 1106 struct sci_port *sci_port; 1110 1107 struct uart_port *port; ··· 1122 1119 if (co->index >= SCI_NPORTS) 1123 1120 co->index = 0; 1124 1121 1125 - sci_port = &sci_ports[co->index]; 1126 - port = &sci_port->port; 1127 - co->data = port; 1122 + if (co->data) { 1123 + port = co->data; 1124 + sci_port = to_sci_port(port); 1125 + } else { 1126 + sci_port = &sci_ports[co->index]; 1127 + port = &sci_port->port; 1128 + co->data = port; 1129 + } 1128 1130 1129 1131 /* 1130 1132 * Also need to check port->type, we don't actually have any ··· 1173 1165 return 0; 1174 1166 } 1175 1167 console_initcall(sci_console_init); 1168 + 1169 + static struct sci_port early_serial_port; 1170 + static struct console early_serial_console = { 1171 + .name = "early_ttySC", 1172 + .write = serial_console_write, 1173 + .flags = CON_PRINTBUFFER, 1174 + }; 1175 + static char early_serial_buf[32]; 1176 + 1176 1177 #endif /* CONFIG_SERIAL_SH_SCI_CONSOLE */ 1177 1178 1178 1179 #if defined(CONFIG_SERIAL_SH_SCI_CONSOLE) ··· 1266 1249 struct plat_sci_port *p = dev->dev.platform_data; 1267 1250 struct sh_sci_priv *priv; 1268 1251 int i, ret = -EINVAL; 1252 + 1253 + #ifdef CONFIG_SERIAL_SH_SCI_CONSOLE 1254 + if (is_early_platform_device(dev)) { 1255 + if (dev->id == -1) 1256 + return -ENOTSUPP; 1257 + early_serial_console.index = dev->id; 1258 + early_serial_console.data = &early_serial_port.port; 1259 + sci_init_single(NULL, &early_serial_port, dev->id, p); 1260 + serial_console_setup(&early_serial_console, early_serial_buf); 1261 + if (!strstr(early_serial_buf, "keep")) 1262 + early_serial_console.flags |= CON_BOOT; 1263 + register_console(&early_serial_console); 1264 + return 0; 1265 + } 1266 + #endif 1269 1267 1270 1268 priv = kzalloc(sizeof(*priv), GFP_KERNEL); 1271 1269 if (!priv) ··· 1381 1349 uart_unregister_driver(&sci_uart_driver); 1382 1350 } 1383 1351 1352 + #ifdef CONFIG_SERIAL_SH_SCI_CONSOLE 1353 + early_platform_init_buffer("earlyprintk", &sci_driver, 1354 + early_serial_buf, ARRAY_SIZE(early_serial_buf)); 1355 + #endif 1384 1356 module_init(sci_init); 1385 1357 module_exit(sci_exit); 1386 1358