summaryrefslogtreecommitdiffstats
path: root/drivers/tty/serial/8250/8250_core.c
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 14:39:54 +0200
commit87515772c33ee8a0cc08d984a7d2401eeff074cd (patch)
treebde94a76edccf59cfe72e3858337a211ec098257 /drivers/tty/serial/8250/8250_core.c
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>
Diffstat (limited to 'drivers/tty/serial/8250/8250_core.c')
-rw-r--r--drivers/tty/serial/8250/8250_core.c31
1 files changed, 24 insertions, 7 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,
serial8250_console_write(up, s, count);
}
-static int serial8250_console_setup(struct uart_8250_port *up, char *options)
+static unsigned int probe_baud(struct uart_port *port)
+{
+ unsigned char lcr, dll, dlm;
+ unsigned int quot;
+
+ lcr = serial_port_in(port, UART_LCR);
+ serial_port_out(port, UART_LCR, lcr | UART_LCR_DLAB);
+ dll = serial_port_in(port, UART_DLL);
+ dlm = serial_port_in(port, UART_DLM);
+ serial_port_out(port, UART_LCR, lcr);
+
+ quot = (dlm << 8) | dll;
+ return (port->uartclk / 16) / quot;
+}
+
+static int serial8250_console_setup(struct uart_port *port, char *options, bool probe)
{
- struct uart_port *port = &up->port;
int baud = 9600;
int bits = 8;
int parity = 'n';
@@ -3425,13 +3439,15 @@ static int serial8250_console_setup(struct uart_8250_port *up, char *options)
if (options)
uart_parse_options(options, &baud, &parity, &bits, &flow);
+ else if (probe)
+ baud = probe_baud(port);
return uart_set_options(port, port->cons, baud, parity, bits, flow);
}
static int univ8250_console_setup(struct console *co, char *options)
{
- struct uart_8250_port *up;
+ struct uart_port *port;
/*
* Check whether an invalid uart number has been specified, and
@@ -3440,11 +3456,11 @@ static int univ8250_console_setup(struct console *co, char *options)
*/
if (co->index >= nr_uarts)
co->index = 0;
- up = &serial8250_ports[co->index];
+ port = &serial8250_ports[co->index].port;
/* link port to console */
- up->port.cons = co;
+ port->cons = co;
- return serial8250_console_setup(up, options);
+ return serial8250_console_setup(port, options, false);
}
/**
@@ -3491,7 +3507,8 @@ static int univ8250_console_match(struct console *co, char *name, int idx,
continue;
co->index = i;
- return univ8250_console_setup(co, options);
+ port->cons = co;
+ return serial8250_console_setup(port, options, true);
}
return -ENODEV;