aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty/serial
diff options
context:
space:
mode:
authorPeter Hurley <peter@hurleysoftware.com>2015-03-09 16:27:12 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-03-26 11:16:20 -0400
commitc7cef0a84912cab3c9df8949b034e4aa62982ec9 (patch)
tree5e3d7761af96a243ac7460cbbd4e6b20f4eb00c2 /drivers/tty/serial
parente13cb72beeada6f6ac12058b9129334e3bb5ce85 (diff)
console: Add extensible console matching
Add match() method to struct console which allows the console to perform console command line matching instead of (or in addition to) default console matching (ie., by fixed name and index). The match() method returns 0 to indicate a successful match; normal console matching occurs if no match() method is defined or the match() method returns non-zero. The match() method is expected to set the console index if required. Re-implement earlycon-to-console-handoff with direct matching of "console=uart|uart8250,..." to the 8250 ttyS console. Acked-by: Rob Herring <robh@kernel.org> Signed-off-by: Peter Hurley <peter@hurleysoftware.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty/serial')
-rw-r--r--drivers/tty/serial/8250/8250_core.c64
-rw-r--r--drivers/tty/serial/8250/8250_early.c23
2 files changed, 48 insertions, 39 deletions
diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c
index bd06ab790c64..924ee1e13828 100644
--- a/drivers/tty/serial/8250/8250_core.c
+++ b/drivers/tty/serial/8250/8250_core.c
@@ -3322,9 +3322,54 @@ static int serial8250_console_setup(struct console *co, char *options)
3322 return uart_set_options(port, co, baud, parity, bits, flow); 3322 return uart_set_options(port, co, baud, parity, bits, flow);
3323} 3323}
3324 3324
3325static int serial8250_console_early_setup(void) 3325/**
3326 * serial8250_console_match - non-standard console matching
3327 * @co: registering console
3328 * @name: name from console command line
3329 * @idx: index from console command line
3330 * @options: ptr to option string from console command line
3331 *
3332 * Only attempts to match console command lines of the form:
3333 * console=uart<>,io|mmio|mmio32,<addr>,<options>
3334 * console=uart<>,<addr>,options
3335 * This form is used to register an initial earlycon boot console and
3336 * replace it with the serial8250_console at 8250 driver init.
3337 *
3338 * Performs console setup for a match (as required by interface)
3339 *
3340 * Returns 0 if console matches; otherwise non-zero to use default matching
3341 */
3342static int serial8250_console_match(struct console *co, char *name, int idx,
3343 char *options)
3326{ 3344{
3327 return serial8250_find_port_for_earlycon(); 3345 char match[] = "uart"; /* 8250-specific earlycon name */
3346 unsigned char iotype;
3347 unsigned long addr;
3348 int i;
3349
3350 if (strncmp(name, match, 4) != 0)
3351 return -ENODEV;
3352
3353 if (uart_parse_earlycon(options, &iotype, &addr, &options))
3354 return -ENODEV;
3355
3356 /* try to match the port specified on the command line */
3357 for (i = 0; i < nr_uarts; i++) {
3358 struct uart_port *port = &serial8250_ports[i].port;
3359
3360 if (port->iotype != iotype)
3361 continue;
3362 if ((iotype == UPIO_MEM || iotype == UPIO_MEM32) &&
3363 (port->mapbase != addr))
3364 continue;
3365 if (iotype == UPIO_PORT && port->iobase != addr)
3366 continue;
3367
3368 co->index = i;
3369 return serial8250_console_setup(co, options);
3370 }
3371
3372 return -ENODEV;
3328} 3373}
3329 3374
3330static struct console serial8250_console = { 3375static struct console serial8250_console = {
@@ -3332,7 +3377,7 @@ static struct console serial8250_console = {
3332 .write = serial8250_console_write, 3377 .write = serial8250_console_write,
3333 .device = uart_console_device, 3378 .device = uart_console_device,
3334 .setup = serial8250_console_setup, 3379 .setup = serial8250_console_setup,
3335 .early_setup = serial8250_console_early_setup, 3380 .match = serial8250_console_match,
3336 .flags = CON_PRINTBUFFER | CON_ANYTIME, 3381 .flags = CON_PRINTBUFFER | CON_ANYTIME,
3337 .index = -1, 3382 .index = -1,
3338 .data = &serial8250_reg, 3383 .data = &serial8250_reg,
@@ -3346,19 +3391,6 @@ static int __init serial8250_console_init(void)
3346} 3391}
3347console_initcall(serial8250_console_init); 3392console_initcall(serial8250_console_init);
3348 3393
3349int serial8250_find_port(struct uart_port *p)
3350{
3351 int line;
3352 struct uart_port *port;
3353
3354 for (line = 0; line < nr_uarts; line++) {
3355 port = &serial8250_ports[line].port;
3356 if (uart_match_port(p, port))
3357 return line;
3358 }
3359 return -ENODEV;
3360}
3361
3362#define SERIAL8250_CONSOLE &serial8250_console 3394#define SERIAL8250_CONSOLE &serial8250_console
3363#else 3395#else
3364#define SERIAL8250_CONSOLE NULL 3396#define SERIAL8250_CONSOLE NULL
diff --git a/drivers/tty/serial/8250/8250_early.c b/drivers/tty/serial/8250/8250_early.c
index c31a22b4f845..49bca65057e6 100644
--- a/drivers/tty/serial/8250/8250_early.c
+++ b/drivers/tty/serial/8250/8250_early.c
@@ -173,26 +173,3 @@ int __init setup_early_serial8250_console(char *cmdline)
173 173
174 return setup_earlycon(cmdline, match, early_serial8250_setup); 174 return setup_earlycon(cmdline, match, early_serial8250_setup);
175} 175}
176
177int serial8250_find_port_for_earlycon(void)
178{
179 struct earlycon_device *device = early_device;
180 struct uart_port *port = device ? &device->port : NULL;
181 int line;
182 int ret;
183
184 if (!port || (!port->membase && !port->iobase))
185 return -ENODEV;
186
187 line = serial8250_find_port(port);
188 if (line < 0)
189 return -ENODEV;
190
191 ret = update_console_cmdline("uart", 8250,
192 "ttyS", line, device->options);
193 if (ret < 0)
194 ret = update_console_cmdline("uart", 0,
195 "ttyS", line, device->options);
196
197 return ret;
198}