Re: [PATCH v3 -next 11/11] serial: 8250_early: Remove setup_early_serial8250_console()

From: Yinghai Lu
Date: Thu Apr 02 2015 - 22:38:24 EST


On Thu, Apr 2, 2015 at 5:22 PM, Yinghai Lu <yinghai@xxxxxxxxxx> wrote:

>>>> still have another problem.
>>>> when using console=uart8250,io,0x3f8
>>>> it works as earlycon at first.
>>>> but after handover to normal console
>>>> it will revert back to 9600 again.
>>>
>>> this regression should be caused by:
>>>
>>> commit c7cef0a84912cab3c9df8949b034e4aa62982ec9
>>> Author: Peter Hurley <peter@xxxxxxxxxxxxxxxxxx>
>>> Date: Mon Mar 9 16:27:12 2015 -0400
>>>
>>> console: Add extensible console matching
>>
> So your whole patchset will need the first patch ?
>
> or can you just drop the first one patch ?

Please check attached patch that fix regresion by. commit c7cef0a849
("console: Add extensible console matching")

or you have better way?

Thanks

Yinghai
Subject: [PATCH] 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@xxxxxxxxxx>

---
drivers/tty/serial/8250/8250_core.c | 14 ++++++++++++--
drivers/tty/serial/8250/8250_early.c | 19 +++++++++++++++++++
include/linux/console.h | 2 +-
include/linux/serial_8250.h | 1 +
kernel/printk/printk.c | 2 +-
5 files changed, 34 insertions(+), 4 deletions(-)

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
@@ -3452,7 +3452,7 @@ static int univ8250_console_setup(struct
* @co: registering console
* @name: name from console command line
* @idx: index from console command line
- * @options: ptr to option string from console command line
+ * @options_p: ptr to ptr to option string from console command line
*
* Only attempts to match console command lines of the form:
* console=uart<>,io|mmio|mmio32,<addr>,<options>
@@ -3465,11 +3465,12 @@ static int univ8250_console_setup(struct
* Returns 0 if console matches; otherwise non-zero to use default matching
*/
static int univ8250_console_match(struct console *co, char *name, int idx,
- char *options)
+ char **options_p)
{
char match[] = "uart"; /* 8250-specific earlycon name */
unsigned char iotype;
unsigned long addr;
+ char *options = *options_p;
int i;

if (strncmp(name, match, 4) != 0)
@@ -3491,6 +3492,15 @@ static int univ8250_console_match(struct
continue;

co->index = i;
+
+ if (!options || !options[0]) {
+ char *new_options = NULL;
+
+ if (!serial8250_get_earlycon_options(port,
+ &new_options))
+ options = *options_p = new_options;
+ }
+
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,24 @@ static void __init early_serial8250_writ
serial8250_early_out(port, UART_IER, ier);
}

+static struct earlycon_device *early_device;
+
+int serial8250_get_earlycon_options(struct uart_port *up, char **options_p)
+{
+ struct earlycon_device *device = early_device;
+ struct uart_port *port = device ? &device->port : NULL;
+
+ if (!port || (!port->membase && !port->iobase))
+ return -ENODEV;
+
+ if (!uart_match_port(up, port))
+ return -ENODEV;
+
+ *options_p = device->options;
+
+ return 0;
+}
+
static unsigned int __init probe_baud(struct uart_port *port)
{
unsigned char lcr, dll, dlm;
@@ -161,6 +179,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 int serial8250_get_earlycon_options(struct uart_port *up, char **p);
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,
Index: linux-2.6/kernel/printk/printk.c
===================================================================
--- linux-2.6.orig/kernel/printk/printk.c
+++ linux-2.6/kernel/printk/printk.c
@@ -2444,7 +2444,7 @@ void register_console(struct console *ne
i < MAX_CMDLINECONSOLES && c->name[0];
i++, c++) {
if (!newcon->match ||
- newcon->match(newcon, c->name, c->index, c->options) != 0) {
+ !newcon->match(newcon, c->name, c->index, &c->options)) {
/* default matching */
BUILD_BUG_ON(sizeof(c->name) != sizeof(newcon->name));
if (strcmp(c->name, newcon->name) != 0)
Index: linux-2.6/include/linux/console.h
===================================================================
--- linux-2.6.orig/include/linux/console.h
+++ linux-2.6/include/linux/console.h
@@ -123,7 +123,7 @@ struct console {
struct tty_driver *(*device)(struct console *, int *);
void (*unblank)(void);
int (*setup)(struct console *, char *);
- int (*match)(struct console *, char *name, int idx, char *options);
+ int (*match)(struct console *, char *name, int idx, char **p);
short flags;
short index;
int cflag;