Re: [PATCH v2] earlycon: 8250: Fix command line regression

Yinghai Lu
2015-04-04T06:05:13Z

[-- Attachment #1: Type: text/plain, Size: 1027 bytes --]

On Fri, Apr 3, 2015 at 8:32 PM, Peter Hurley <peter@hurleysoftware.com> wrote:
> On 04/03/2015 11:24 PM, Yinghai Lu wrote:
>> On Fri, Apr 3, 2015 at 8:15 PM, Peter Hurley <peter@hurleysoftware.com> wrote:
>>> On 04/03/2015 11:09 PM, Yinghai Lu wrote:
>>>> On Fri, Apr 3, 2015 at 7:19 PM, Yinghai Lu <yinghai@kernel.org> wrote:
>>>>> On Fri, Apr 3, 2015 at 5:04 PM, Peter Hurley <peter@hurleysoftware.com> wrote:
>>>>>> 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.
>>>>>
>>>>>
>>>>> This patch fix regression for the hand over. Thanks.
>>>>
>>>> Just now noticed, this patch only fix partial problem. Kernel console is ok.
>>>>
>>>> But later initrd/init scripts revert back to 9600 again.
>>>

I updated my fix a little bit. please check attached.

Thanks

Yinghai

[-- Attachment #2: fix_earlycon_console_handover_v2.patch --]
[-- Type: text/x-patch, Size: 3050 bytes --]

Subject: [PATCH -v2] earlycon: Fix earlycon/console handover without options

commit c7cef0a84912 ("console: Add extensible console matching")
broke the earlycon/handover when booting
console=uart8250,io,0x3f8

the bootloader is using 115200, and the earlycon continue
use 115200, but console revert back to 9600.

Before the commit, probed baud rate is passed via console_cmdline
from earlycon to normal console.
That commit remove that and only check boot command line.

This patch use port match to get hold earlycon, and use earlycon
device options to update options for console.

Fixes: commit c7cef0a84912 ("console: Add extensible console matching")
Signed-off-by: Yinghai Lu <yinghai@kernel.org>

---
-v2: simplify serial8250_get_earlycon_options and don't update
console_cmdline.
---
drivers/tty/serial/8250/8250_core.c | 4 ++++
drivers/tty/serial/8250/8250_early.c | 17 +++++++++++++++++
include/linux/serial_8250.h | 1 +
3 files changed, 22 insertions(+)

Index: linux-2.6/drivers/tty/serial/8250/8250_core.c
===================================================================
--- linux-2.6.orig/drivers/tty/serial/8250/8250_core.c
+++ linux-2.6/drivers/tty/serial/8250/8250_core.c
@@ -3491,6 +3491,10 @@ static int univ8250_console_match(struct
continue;

co->index = i;
+
+ if (!options)
+ options = serial8250_get_earlycon_options(port);
+
return univ8250_console_setup(co, options);
}

Index: linux-2.6/drivers/tty/serial/8250/8250_early.c
===================================================================
--- linux-2.6.orig/drivers/tty/serial/8250/8250_early.c
+++ linux-2.6/drivers/tty/serial/8250/8250_early.c
@@ -105,6 +105,22 @@ static void __init early_serial8250_writ
serial8250_early_out(port, UART_IER, ier);
}

+static struct earlycon_device *early_device;
+
+char *serial8250_get_earlycon_options(struct uart_port *up)
+{
+ struct earlycon_device *device = early_device;
+ struct uart_port *port = device ? &device->port : NULL;
+
+ if (!port || (!port->membase && !port->iobase))
+ return NULL;
+
+ if (!uart_match_port(up, port))
+ return NULL;
+
+ return device->options;
+}
+
static unsigned int __init probe_baud(struct uart_port *port)
{
unsigned char lcr, dll, dlm;
@@ -161,6 +177,7 @@ static int __init early_serial8250_setup
} else
init_port(device);

+ early_device = device;
device->con->write = early_serial8250_write;
return 0;
}
Index: linux-2.6/include/linux/serial_8250.h
===================================================================
--- linux-2.6.orig/include/linux/serial_8250.h
+++ linux-2.6/include/linux/serial_8250.h
@@ -135,6 +135,7 @@ void serial8250_resume_port(int line);

extern int early_serial_setup(struct uart_port *port);

+extern char *serial8250_get_earlycon_options(struct uart_port *up);
extern unsigned int serial8250_early_in(struct uart_port *port, int offset);
extern void serial8250_early_out(struct uart_port *port, int offset, int value);
extern void serial8250_do_set_termios(struct uart_port *port,