diff options
| author | Peter Hurley <peter@hurleysoftware.com> | 2015-04-06 10:48:49 -0400 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2015-04-10 08:39:54 -0400 |
| commit | 87515772c33ee8a0cc08d984a7d2401eeff074cd (patch) | |
| tree | bde94a76edccf59cfe72e3858337a211ec098257 /drivers/tty | |
| parent | 99492c39f39fc2d8c4ae36ecfb88d7de5d8106b5 (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')
| -rw-r--r-- | drivers/tty/serial/8250/8250_core.c | 31 | ||||
| -rw-r--r-- | drivers/tty/serial/8250/8250_early.c | 19 |
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 | ||
| 3415 | static int serial8250_console_setup(struct uart_8250_port *up, char *options) | 3415 | static 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 | |||
| 3430 | static 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 | ||
| 3432 | static int univ8250_console_setup(struct console *co, char *options) | 3448 | static 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 | ||
| 108 | static 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 | |||
| 123 | static void __init init_port(struct earlycon_device *device) | 108 | static 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); |
