aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Hurley <peter@hurleysoftware.com>2015-04-06 10:48:49 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-04-10 08:39:54 -0400
commit87515772c33ee8a0cc08d984a7d2401eeff074cd (patch)
treebde94a76edccf59cfe72e3858337a211ec098257
parent99492c39f39fc2d8c4ae36ecfb88d7de5d8106b5 (diff)
earlycon: 8250: Fix command line regression
Restore undocumented behavior of kernel command line parameters of the forms: console=uart[8250],io|mmio|mmio32,<addr>[,options] console=uart[8250],<addr>[,options] where 'options' have not been specified; in this case, the hardware is assumed to be initialized. Fixes: c7cef0a84912cab3c9df8 ("console: Add extensible console matching") Reported-by: Yinghai Lu <yinghai@kernel.org> Signed-off-by: Peter Hurley <peter@hurleysoftware.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/tty/serial/8250/8250_core.c31
-rw-r--r--drivers/tty/serial/8250/8250_early.c19
2 files changed, 24 insertions, 26 deletions
diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c
index e0fb5f053d09..18142ee3c013 100644
--- a/drivers/tty/serial/8250/8250_core.c
+++ b/drivers/tty/serial/8250/8250_core.c
@@ -3412,9 +3412,23 @@ static void univ8250_console_write(struct console *co, const char *s,
3412 serial8250_console_write(up, s, count); 3412 serial8250_console_write(up, s, count);
3413} 3413}
3414 3414
3415static int serial8250_console_setup(struct uart_8250_port *up, char *options) 3415static unsigned int probe_baud(struct uart_port *port)
3416{
3417 unsigned char lcr, dll, dlm;
3418 unsigned int quot;
3419
3420 lcr = serial_port_in(port, UART_LCR);
3421 serial_port_out(port, UART_LCR, lcr | UART_LCR_DLAB);
3422 dll = serial_port_in(port, UART_DLL);
3423 dlm = serial_port_in(port, UART_DLM);
3424 serial_port_out(port, UART_LCR, lcr);
3425
3426 quot = (dlm << 8) | dll;
3427 return (port->uartclk / 16) / quot;
3428}
3429
3430static int serial8250_console_setup(struct uart_port *port, char *options, bool probe)
3416{ 3431{
3417 struct uart_port *port = &up->port;
3418 int baud = 9600; 3432 int baud = 9600;
3419 int bits = 8; 3433 int bits = 8;
3420 int parity = 'n'; 3434 int parity = 'n';
@@ -3425,13 +3439,15 @@ static int serial8250_console_setup(struct uart_8250_port *up, char *options)
3425 3439
3426 if (options) 3440 if (options)
3427 uart_parse_options(options, &baud, &parity, &bits, &flow); 3441 uart_parse_options(options, &baud, &parity, &bits, &flow);
3442 else if (probe)
3443 baud = probe_baud(port);
3428 3444
3429 return uart_set_options(port, port->cons, baud, parity, bits, flow); 3445 return uart_set_options(port, port->cons, baud, parity, bits, flow);
3430} 3446}
3431 3447
3432static int univ8250_console_setup(struct console *co, char *options) 3448static int univ8250_console_setup(struct console *co, char *options)
3433{ 3449{
3434 struct uart_8250_port *up; 3450 struct uart_port *port;
3435 3451
3436 /* 3452 /*
3437 * Check whether an invalid uart number has been specified, and 3453 * Check whether an invalid uart number has been specified, and
@@ -3440,11 +3456,11 @@ static int univ8250_console_setup(struct console *co, char *options)
3440 */ 3456 */
3441 if (co->index >= nr_uarts) 3457 if (co->index >= nr_uarts)
3442 co->index = 0; 3458 co->index = 0;
3443 up = &serial8250_ports[co->index]; 3459 port = &serial8250_ports[co->index].port;
3444 /* link port to console */ 3460 /* link port to console */
3445 up->port.cons = co; 3461 port->cons = co;
3446 3462
3447 return serial8250_console_setup(up, options); 3463 return serial8250_console_setup(port, options, false);
3448} 3464}
3449 3465
3450/** 3466/**
@@ -3491,7 +3507,8 @@ static int univ8250_console_match(struct console *co, char *name, int idx,
3491 continue; 3507 continue;
3492 3508
3493 co->index = i; 3509 co->index = i;
3494 return univ8250_console_setup(co, options); 3510 port->cons = co;
3511 return serial8250_console_setup(port, options, true);
3495 } 3512 }
3496 3513
3497 return -ENODEV; 3514 return -ENODEV;
diff --git a/drivers/tty/serial/8250/8250_early.c b/drivers/tty/serial/8250/8250_early.c
index e95ebfe8427f..8e119682266a 100644
--- a/drivers/tty/serial/8250/8250_early.c
+++ b/drivers/tty/serial/8250/8250_early.c
@@ -105,21 +105,6 @@ static void __init early_serial8250_write(struct console *console,
105 serial8250_early_out(port, UART_IER, ier); 105 serial8250_early_out(port, UART_IER, ier);
106} 106}
107 107
108static unsigned int __init probe_baud(struct uart_port *port)
109{
110 unsigned char lcr, dll, dlm;
111 unsigned int quot;
112
113 lcr = serial8250_early_in(port, UART_LCR);
114 serial8250_early_out(port, UART_LCR, lcr | UART_LCR_DLAB);
115 dll = serial8250_early_in(port, UART_DLL);
116 dlm = serial8250_early_in(port, UART_DLM);
117 serial8250_early_out(port, UART_LCR, lcr);
118
119 quot = (dlm << 8) | dll;
120 return (port->uartclk / 16) / quot;
121}
122
123static void __init init_port(struct earlycon_device *device) 108static void __init init_port(struct earlycon_device *device)
124{ 109{
125 struct uart_port *port = &device->port; 110 struct uart_port *port = &device->port;
@@ -151,10 +136,6 @@ static int __init early_serial8250_setup(struct earlycon_device *device,
151 struct uart_port *port = &device->port; 136 struct uart_port *port = &device->port;
152 unsigned int ier; 137 unsigned int ier;
153 138
154 device->baud = probe_baud(&device->port);
155 snprintf(device->options, sizeof(device->options), "%u",
156 device->baud);
157
158 /* assume the device was initialized, only mask interrupts */ 139 /* assume the device was initialized, only mask interrupts */
159 ier = serial8250_early_in(port, UART_IER); 140 ier = serial8250_early_in(port, UART_IER);
160 serial8250_early_out(port, UART_IER, ier & UART_IER_UUE); 141 serial8250_early_out(port, UART_IER, ier & UART_IER_UUE);