Skip to contentSkip to conversation

Extensible console matching & direct earlycon

PATCH In review Peter Hurley 3 participants 63 messages Mar 9, 2015 – Apr 6, 2015

Subsystems (8)
lore
Share & tools
lore
#0 lore raw

v3 cover Extensible console matching & direct earlycon

Changes from v2:
* remainder of unapplied series
* Changed the title and commit log for
"serial: earlycon: Allow earlycon params with name only" to "serial: earlycon: Skip parse_options() for empty string" per Rob's comment.

Changes from v1:
* rebased on and requires "console: Fix console name size mismatch"

Hi Greg & Andrew,

This patch series implements:
1. console-definable (aka extensible) matching
2. generic earlycon-to-console handoff via extensible matching
3. arch/prom support for direct earlycon

Extensible console matching

Extensible console matching enables the console itself to define the conditions for a "command line" match. This mimics the design of device matching in the driver model. Two important use-cases which this feature enables are generic earlycon-to-console handoff and support for driver migration.

Earlycon-to-console handoff was implemented in 2007. Console command lines of the form:
console=uart,io,0x3f8,115200n8
start an earlycon and later allow the 8250 driver console to takeover. Unfortunately this implementation requires direct coupling between the earlycon and the console and is facilitated by ugly hacks like editing the console command line in-place.

Extensible console matching allows the 8250 driver to directly match that console command line instead, and enables other serial drivers to trivially support console handoff themselves.

In addition, extensible console matching allows a new driver to provide support for a different driver's console. This requirement stems from needing to minimize breakage when migrating serial drivers. Since many devices are based on the original 8250/16550 designs but sometimes have features incompatible with the existing 8250 driver support, the initial driver is often standalone. When/if the standalone driver is migrated to the 8250 driver, the problem of console names in the command line remains. Extensible console matching enables a simple migration path.

Direct earlycon

This feature enables arches and proms to start an earlycon directly, rather than requiring an "earlycon=" command line parameter. Devicetree can already do this via the 'linux,stdout-path' property, but arch and prom code requires direct coupling to the serial driver.

This support is implemented by judicious refactoring and the same construct that devicetree and early_param use: a link table containing the necessary information (name and setup() function) to find and bind the appropriate earlycon "driver".

NB: I combined these two features in this series because their implementations heavily overlap in the same source files.

Regards,

Peter Hurley (11):
console: Add extensible console matching
serial: core: Fix kernel doc for uart_console_write()
serial: 8250_early: Remove early_device variable
serial: earlycon: Move ->uartclk initialize
serial: 8250_early: Assume uart already initialized if no baud option
serial: 8250_early: Fix setup() error code
serial: earlycon: Ignore parse_options() error code
serial: earlycon: Skip parse_options() if empty string
serial: earlycon: Refactor earlycon registration
serial: earlycon: Enable earlycon without command line param
serial: 8250_early: Remove setup_early_serial8250_console()

 arch/mips/mti-malta/malta-init.c     |   4 +-
 drivers/firmware/pcdp.c              |   4 +-
 drivers/tty/serial/8250/8250_core.c  |  64 ++++++++++++++++------
 drivers/tty/serial/8250/8250_early.c |  51 ++++--------------
 drivers/tty/serial/earlycon.c        | 101 ++++++++++++++++++++++++++++-------
 drivers/tty/serial/serial_core.c     |   2 +-
 include/asm-generic/vmlinux.lds.h    |   9 ++++
 include/linux/console.h              |   3 +-
 include/linux/serial_8250.h          |   3 --
 include/linux/serial_core.h          |  19 ++++---
 kernel/printk/printk.c               |  52 +++++++-----------
 11 files changed, 185 insertions(+), 127 deletions(-)
Signature · 1 line
2.3.1
#1 lore raw

PATCH v3 1/11 console: Add extensible console matching

Add match() method to struct console which allows the console to perform console command line matching instead of (or in addition to) default console matching (ie., by fixed name and index).

The match() method returns 0 to indicate a successful match; normal console matching occurs if no match() method is defined or the match() method returns non-zero. The match() method is expected to set the console index if required.

Re-implement earlycon-to-console-handoff with direct matching of "console=uart|uart8250,..." to the 8250 ttyS console.

---
 drivers/tty/serial/8250/8250_core.c  | 64 +++++++++++++++++++++++++++---------
 drivers/tty/serial/8250/8250_early.c | 23 -------------
 include/linux/console.h              |  3 +-
 include/linux/serial_8250.h          |  2 --
 kernel/printk/printk.c               | 52 ++++++++++-------------------
 5 files changed, 67 insertions(+), 77 deletions(-)
drivers/tty/serial/8250/8250_core.c +48 -16
index e3b9570a..5eb95fd 100644
@@ -3337,9 +3337,54 @@ static int serial8250_console_setup(struct console *co, char *options)
 	return uart_set_options(port, co, baud, parity, bits, flow);
 }
 
-static int serial8250_console_early_setup(void)
+/**
+ *	serial8250_console_match - non-standard console matching
+ *	@co:	  registering console
+ *	@name:	  name from console command line
+ *	@idx:	  index from console command line
+ *	@options: 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>
+ *	    console=uart<>,<addr>,options
+ *	This form is used to register an initial earlycon boot console and
+ *	replace it with the serial8250_console at 8250 driver init.
+ *
+ *	Performs console setup for a match (as required by interface)
+ *
+ *	Returns 0 if console matches; otherwise non-zero to use default matching
+ */
+static int serial8250_console_match(struct console *co, char *name, int idx,
+				    char *options)
 {
-	return serial8250_find_port_for_earlycon();
+	char match[] = "uart";	/* 8250-specific earlycon name */
+	unsigned char iotype;
+	unsigned long addr;
+	int i;
+
+	if (strncmp(name, match, 4) != 0)
+		return -ENODEV;
+
+	if (uart_parse_earlycon(options, &iotype, &addr, &options))
+		return -ENODEV;
+
+	/* try to match the port specified on the command line */
+	for (i = 0; i < nr_uarts; i++) {
+		struct uart_port *port = &serial8250_ports[i].port;
+
+		if (port->iotype != iotype)
+			continue;
+		if ((iotype == UPIO_MEM || iotype == UPIO_MEM32) &&
+		    (port->mapbase != addr))
+			continue;
+		if (iotype == UPIO_PORT && port->iobase != addr)
+			continue;
+
+		co->index = i;
+		return serial8250_console_setup(co, options);
+	}
+
+	return -ENODEV;
 }
 
 static struct console serial8250_console = {
@@ -3347,7 +3392,7 @@ static struct console serial8250_console = {
 	.write		= serial8250_console_write,
 	.device		= uart_console_device,
 	.setup		= serial8250_console_setup,
-	.early_setup	= serial8250_console_early_setup,
+	.match		= serial8250_console_match,
 	.flags		= CON_PRINTBUFFER | CON_ANYTIME,
 	.index		= -1,
 	.data		= &serial8250_reg,
@@ -3361,19 +3406,6 @@ static int __init serial8250_console_init(void)
 }
 console_initcall(serial8250_console_init);
 
-int serial8250_find_port(struct uart_port *p)
-{
-	int line;
-	struct uart_port *port;
-
-	for (line = 0; line < nr_uarts; line++) {
-		port = &serial8250_ports[line].port;
-		if (uart_match_port(p, port))
-			return line;
-	}
-	return -ENODEV;
-}
-
 #define SERIAL8250_CONSOLE	&serial8250_console
 #else
 #define SERIAL8250_CONSOLE	NULL
drivers/tty/serial/8250/8250_early.c +0 -23
index c31a22b..49bca65 100644
@@ -173,26 +173,3 @@ int __init setup_early_serial8250_console(char *cmdline)
 
 	return setup_earlycon(cmdline, match, early_serial8250_setup);
 }
-
-int serial8250_find_port_for_earlycon(void)
-{
-	struct earlycon_device *device = early_device;
-	struct uart_port *port = device ? &device->port : NULL;
-	int line;
-	int ret;
-
-	if (!port || (!port->membase && !port->iobase))
-		return -ENODEV;
-
-	line = serial8250_find_port(port);
-	if (line < 0)
-		return -ENODEV;
-
-	ret = update_console_cmdline("uart", 8250,
-			     "ttyS", line, device->options);
-	if (ret < 0)
-		ret = update_console_cmdline("uart", 0,
-				     "ttyS", line, device->options);
-
-	return ret;
-}
include/linux/console.h +1 -2
index 7571a16..9f50fb4 100644
@@ -123,7 +123,7 @@ struct console {
 	struct tty_driver *(*device)(struct console *, int *);
 	void	(*unblank)(void);
 	int	(*setup)(struct console *, char *);
-	int	(*early_setup)(void);
+	int	(*match)(struct console *, char *name, int idx, char *options);
 	short	flags;
 	short	index;
 	int	cflag;
@@ -141,7 +141,6 @@ extern int console_set_on_cmdline;
 extern struct console *early_console;
 
 extern int add_preferred_console(char *name, int idx, char *options);
-extern int update_console_cmdline(char *name, int idx, char *name_new, int idx_new, char *options);
 extern void register_console(struct console *);
 extern int unregister_console(struct console *);
 extern struct console *console_drivers;
include/linux/serial_8250.h +0 -2
index a8efa23..f26ae7f 100644
@@ -118,8 +118,6 @@ void serial8250_resume_port(int line);
 
 extern int early_serial_setup(struct uart_port *port);
 
-extern int serial8250_find_port(struct uart_port *p);
-extern int serial8250_find_port_for_earlycon(void);
 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 int setup_early_serial8250_console(char *cmdline);
kernel/printk/printk.c +18 -34

72 lines not on this page · raw message

Signature · 1 line
2.3.1
#2 lore raw

PATCH v3 2/11 serial: core: Fix kernel doc for uart_console_write()

In reply to Peter Hurley

'/**' is required to start a kernel-doc comment block.

---
 drivers/tty/serial/serial_core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/tty/serial/serial_core.c +1 -1
index 3f823c26..373cfde 100644
@@ -1766,7 +1766,7 @@ static const struct file_operations uart_proc_fops = {
 #endif
 
 #if defined(CONFIG_SERIAL_CORE_CONSOLE) || defined(CONFIG_CONSOLE_POLL)
-/*
+/**
  *	uart_console_write - write a console message to a serial port
  *	@port: the port to write the message
  *	@s: array of characters
Signature · 1 line
2.3.1
#3 lore raw

PATCH v3 3/11 serial: 8250_early: Remove early_device variable

In reply to Peter Hurley

early_device was only required for serial8250_find_port_for_earlycon(), which was replaced by extensible console matching.

Fixup early_serial8250_write() to get the earlycon_device * from console->data (which is initialized by {of_}setup_earlycon()).

---
 drivers/tty/serial/8250/8250_early.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)
drivers/tty/serial/8250/8250_early.c +2 -4
index 49bca65..d7b831b 100644
@@ -36,8 +36,6 @@
 #include <asm/io.h>
 #include <asm/serial.h>
 
-static struct earlycon_device *early_device;
-
 unsigned int __weak __init serial8250_early_in(struct uart_port *port, int offset)
 {
 	switch (port->iotype) {
@@ -90,7 +88,8 @@ static void __init serial_putc(struct uart_port *port, int c)
 static void __init early_serial8250_write(struct console *console,
 					const char *s, unsigned int count)
 {
-	struct uart_port *port = &early_device->port;
+	struct earlycon_device *device = console->data;
+	struct uart_port *port = &device->port;
 	unsigned int ier;
 
 	/* Save the IER and disable interrupts preserving the UUE bit */
@@ -157,7 +156,6 @@ static int __init early_serial8250_setup(struct earlycon_device *device,
 
 	init_port(device);
 
-	early_device = device;
 	device->con->write = early_serial8250_write;
 	return 0;
 }
Signature · 1 line
2.3.1
#4 lore raw

PATCH v3 4/11 serial: earlycon: Move ->uartclk initialize

In reply to Peter Hurley

Initializing the ->uartclk field is not related to option parsing; relocate from parse_options() to setup_earlycon() (which mirrors the behavior of of_setup_earlycon()).

---
 drivers/tty/serial/earlycon.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/tty/serial/earlycon.c +1 -2
index 58d6bcd..0480c8f 100644
@@ -76,8 +76,6 @@ static int __init parse_options(struct earlycon_device *device, char *options)
 		return -EINVAL;
 	}
 
-	port->uartclk = BASE_BAUD * 16;
-
 	if (options) {
 		device->baud = simple_strtoul(options, NULL, 0);
 		length = min(strcspn(options, " ") + 1,
@@ -121,6 +119,7 @@ int __init setup_earlycon(char *buf, const char *match,
 	if (!err)
 		buf = NULL;
 
+	port->uartclk = BASE_BAUD * 16;
 	if (port->mapbase)
 		port->membase = earlycon_map(port->mapbase, 64);
 
Signature · 1 line
2.3.1
#5 lore raw

PATCH v3 5/11 serial: 8250_early: Assume uart already initialized if no baud option

In reply to Peter Hurley

The <baud><parity><bit> option string is not supplied if the earlycon is started via devicetree and OF_EARLYCON_DECLARE(). The option string is also not required if started via kernel command line parameters of the form:
earlycon=uart,mmio,<addr>
console=uart,mmio,<addr>

If earlycon_device->baud is 0, then an option string was not supplied. In this case, assume the uart has already been initialized by the bootloader or firmware.

---
 drivers/tty/serial/8250/8250_early.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)
drivers/tty/serial/8250/8250_early.c +8 -2
index d7b831b..1701d00 100644
@@ -149,12 +149,18 @@ static int __init early_serial8250_setup(struct earlycon_device *device,
 		return 0;
 
 	if (!device->baud) {
+		struct uart_port *port = &device->port;
+		unsigned int ier;
+
 		device->baud = probe_baud(&device->port);
 		snprintf(device->options, sizeof(device->options), "%u",
 			 device->baud);
-	}
 
-	init_port(device);
+		/* assume the device was initialized, only mask interrupts */
+		ier = serial8250_early_in(port, UART_IER);
+		serial8250_early_out(port, UART_IER, ier & UART_IER_UUE);
+	} else
+		init_port(device);
 
 	device->con->write = early_serial8250_write;
 	return 0;
Signature · 1 line
2.3.1
#6 lore raw

PATCH v3 6/11 serial: 8250_early: Fix setup() error code

In reply to Peter Hurley

If parsing failed to decode a valid uart addr, return -ENODEV instead of success. Although setup_earlycon() will detect the failure anyway (because the write() method has not been set), that behavior is not obvious and should not be relied on.

---
 drivers/tty/serial/8250/8250_early.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/tty/serial/8250/8250_early.c +1 -1
index 1701d00..b199c10 100644
@@ -146,7 +146,7 @@ static int __init early_serial8250_setup(struct earlycon_device *device,
 					 const char *options)
 {
 	if (!(device->port.membase || device->port.iobase))
-		return 0;
+		return -ENODEV;
 
 	if (!device->baud) {
 		struct uart_port *port = &device->port;
Signature · 1 line
2.3.1
#7 lore raw

PATCH v3 7/11 serial: earlycon: Ignore parse_options() error code

In reply to Peter Hurley

Because setup_earlycon() continues to attempt console registration if an error occurred parsing the option string, the actual value of the error code from parse_options() is ignored.

---
 drivers/tty/serial/earlycon.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/tty/serial/earlycon.c +1 -2
index 0480c8f..da5e8c8 100644
@@ -114,9 +114,8 @@ int __init setup_earlycon(char *buf, const char *match,
 
 	buf += len + 1;
 
-	err = parse_options(&early_console_dev, buf);
 	/* On parsing error, pass the options buf to the setup function */
-	if (!err)
+	if (!parse_options(&early_console_dev, buf))
 		buf = NULL;
 
 	port->uartclk = BASE_BAUD * 16;
Signature · 1 line
2.3.1
#8 lore raw

PATCH v3 8/11 serial: earlycon: Skip parse_options() if empty string

In reply to Peter Hurley

Earlycon param strings of the form
earlycon=<name>
are rejected from parse_options() with an error (which, in turn, results in a NULL argument for the setup() method options parameter).

Only pass non-empty string to parse_options(); this will enable handling actual parse errors differently than expected and allow formats.

---
 drivers/tty/serial/earlycon.c | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)
drivers/tty/serial/earlycon.c +7 -4
index da5e8c8..025ea01 100644
@@ -109,13 +109,16 @@ int __init setup_earlycon(char *buf, const char *match,
 	len = strlen(match);
 	if (strncmp(buf, match, len))
 		return 0;
-	if (buf[len] && (buf[len] != ','))
-		return 0;
 
-	buf += len + 1;
+	if (buf[len]) {
+		if (buf[len] != ',')
+			return 0;
+		buf += len + 1;
+	} else
+		buf = NULL;
 
 	/* On parsing error, pass the options buf to the setup function */
-	if (!parse_options(&early_console_dev, buf))
+	if (buf && !parse_options(&early_console_dev, buf))
 		buf = NULL;
 
 	port->uartclk = BASE_BAUD * 16;
Signature · 1 line
2.3.1
#9 lore raw

PATCH v3 9/11 serial: earlycon: Refactor earlycon registration

In reply to Peter Hurley

Separate earlycon matching from registration; add register_earlycon which initializes and registers the matched earlycon.

---
 drivers/tty/serial/earlycon.c | 42 +++++++++++++++++++++++++-----------------
 1 file changed, 25 insertions(+), 17 deletions(-)
drivers/tty/serial/earlycon.c +25 -17
index 025ea01..9fb76b6 100644
@@ -96,27 +96,13 @@ static int __init parse_options(struct earlycon_device *device, char *options)
 	return 0;
 }
 
-int __init setup_earlycon(char *buf, const char *match,
-			  int (*setup)(struct earlycon_device *, const char *))
+
+static int __init
+register_earlycon(char *buf, int (*setup)(struct earlycon_device *, const char *))
 {
 	int err;
-	size_t len;
 	struct uart_port *port = &early_console_dev.port;
 
-	if (!buf || !match || !setup)
-		return 0;
-
-	len = strlen(match);
-	if (strncmp(buf, match, len))
-		return 0;
-
-	if (buf[len]) {
-		if (buf[len] != ',')
-			return 0;
-		buf += len + 1;
-	} else
-		buf = NULL;
-
 	/* On parsing error, pass the options buf to the setup function */
 	if (buf && !parse_options(&early_console_dev, buf))
 		buf = NULL;
@@ -136,6 +122,28 @@ int __init setup_earlycon(char *buf, const char *match,
 	return 0;
 }
 
+int __init setup_earlycon(char *buf, const char *match,
+			  int (*setup)(struct earlycon_device *, const char *))
+{
+	size_t len;
+
+	if (!buf || !match || !setup)
+		return 0;
+
+	len = strlen(match);
+	if (strncmp(buf, match, len))
+		return 0;
+
+	if (buf[len]) {
+		if (buf[len] != ',')
+			return 0;
+		buf += len + 1;
+	} else
+		buf = NULL;
+
+	return register_earlycon(buf, setup);
+}
+
 int __init of_setup_earlycon(unsigned long addr,
 			     int (*setup)(struct earlycon_device *, const char *))
 {
Signature · 1 line
2.3.1
#10 lore raw

PATCH v3 10/11 serial: earlycon: Enable earlycon without command line param

In reply to Peter Hurley

Earlycon matching can only be triggered if 'earlycon=...' has been specified on the kernel command line. To workaround this limitation requires tight coupling between arches and specific serial drivers in order to start an earlycon. Devicetree avoids this limitation with a link table that contains the required data to match earlycons.

Mirror this approach for earlycon match by name. Re-purpose EARLYCON_DECLARE to generate a table entry which associates name with setup() function. Re-purpose setup_earlycon() to scan this table for an earlycon match, which is registered if found.

Declare one "earlycon" early_param, which calls setup_earlycon().

This design allows setup_earlycon() to be called directly with a param string (as if 'earlycon=...' had been set on the command line). Re-registration (either directly or by early_param) is prevented.

---
 drivers/tty/serial/8250/8250_early.c |  7 +--
 drivers/tty/serial/earlycon.c        | 92 ++++++++++++++++++++++++++++--------
 include/asm-generic/vmlinux.lds.h    |  9 ++++
 include/linux/serial_core.h          | 19 ++++----
 4 files changed, 94 insertions(+), 33 deletions(-)
drivers/tty/serial/8250/8250_early.c +1 -6
index b199c10..d272139 100644
@@ -170,10 +170,5 @@ EARLYCON_DECLARE(uart, early_serial8250_setup);
 
 int __init setup_early_serial8250_console(char *cmdline)
 {
-	char match[] = "uart8250";
-
-	if (cmdline && cmdline[4] == ',')
-		match[4] = '\0';
-
-	return setup_earlycon(cmdline, match, early_serial8250_setup);
+	return setup_earlycon(cmdline);
 }
drivers/tty/serial/earlycon.c +73 -19

128 lines not on this page · raw message

include/asm-generic/vmlinux.lds.h +9 -0
index ac78910..87e5b6f 100644
@@ -150,6 +150,14 @@
 #define TRACE_SYSCALLS()
 #endif
 
+#ifdef CONFIG_SERIAL_EARLYCON
+#define EARLYCON_TABLE() . = ALIGN(8);				\
+			 VMLINUX_SYMBOL(__earlycon_table) = .;	\
+			 *(__earlycon_table)			\
+			 *(__earlycon_table_end)
+#else
+#define EARLYCON_TABLE()
+#endif
 
 #define ___OF_TABLE(cfg, name)	_OF_TABLE_##cfg(name)
 #define __OF_TABLE(cfg, name)	___OF_TABLE(cfg, name)
@@ -503,6 +511,7 @@
 	CPU_METHOD_OF_TABLES()						\
 	KERNEL_DTB()							\
 	IRQCHIP_OF_MATCH_TABLE()					\
+	EARLYCON_TABLE()						\
 	EARLYCON_OF_TABLES()
 
 #define INIT_TEXT							\
include/linux/serial_core.h +11 -8
index cc5c506..a3fd182 100644
@@ -336,18 +336,21 @@ struct earlycon_device {
 	char options[16];		/* e.g., 115200n8 */
 	unsigned int baud;
 };
-int setup_earlycon(char *buf, const char *match,
-		   int (*setup)(struct earlycon_device *, const char *));
 
+struct earlycon_id {
+	char	name[16];
+	int	(*setup)(struct earlycon_device *, const char *options);
+};
+
+extern int setup_earlycon(char *buf);
 extern int of_setup_earlycon(unsigned long addr,
 			     int (*setup)(struct earlycon_device *, const char *));
 
-#define EARLYCON_DECLARE(name, func) \
-static int __init name ## _setup_earlycon(char *buf) \
-{ \
-	return setup_earlycon(buf, __stringify(name), func); \
-} \
-early_param("earlycon", name ## _setup_earlycon);
+#define EARLYCON_DECLARE(_name, func)					\
+	static const struct earlycon_id __earlycon_##_name		\
+		__used __section(__earlycon_table)			\
+		 = { .name  = __stringify(_name),			\
+		     .setup = func  }
 
 #define OF_EARLYCON_DECLARE(name, compat, fn)				\
 	_OF_DECLARE(earlycon, name, compat, fn, void *)
Signature · 1 line
2.3.1
#11 lore raw

PATCH v3 11/11 serial: 8250_early: Remove setup_early_serial8250_console()

In reply to Peter Hurley

setup_earlycon() will now match and register the desired earlycon from the param string (as if 'earlycon=...' had been set on the command line). Use setup_earlycon() from existing arch call sites which start an earlycon directly.

---
 arch/mips/mti-malta/malta-init.c     | 4 ++--
 drivers/firmware/pcdp.c              | 4 ++--
 drivers/tty/serial/8250/8250_early.c | 5 -----
 include/linux/serial_8250.h          | 1 -
 4 files changed, 4 insertions(+), 10 deletions(-)
arch/mips/mti-malta/malta-init.c +2 -2
index 6849f53..cec3e18 100644
@@ -14,7 +14,7 @@
 #include <linux/init.h>
 #include <linux/string.h>
 #include <linux/kernel.h>
-#include <linux/serial_8250.h>
+#include <linux/serial_core.h>
 
 #include <asm/cacheflush.h>
 #include <asm/smp-ops.h>
@@ -75,7 +75,7 @@ static void __init console_config(void)
 	if ((strstr(fw_getcmdline(), "earlycon=")) == NULL) {
 		sprintf(console_string, "uart8250,io,0x3f8,%d%c%c", baud,
 			parity, bits);
-		setup_early_serial8250_console(console_string);
+		setup_earlycon(console_string);
 	}
 
 	if ((strstr(fw_getcmdline(), "console=")) == NULL) {
drivers/firmware/pcdp.c +2 -2
index a330492..75273a25 100644
@@ -15,7 +15,7 @@
 #include <linux/console.h>
 #include <linux/efi.h>
 #include <linux/serial.h>
-#include <linux/serial_8250.h>
+#include <linux/serial_core.h>
 #include <asm/vga.h>
 #include "pcdp.h"
 
@@ -43,7 +43,7 @@ setup_serial_console(struct pcdp_uart *uart)
 	}
 
 	add_preferred_console("uart", 8250, &options[9]);
-	return setup_early_serial8250_console(options);
+	return setup_earlycon(options);
 #else
 	return -ENODEV;
 #endif
drivers/tty/serial/8250/8250_early.c +0 -5
index d272139..a2b4e58 100644
@@ -167,8 +167,3 @@ static int __init early_serial8250_setup(struct earlycon_device *device,
 }
 EARLYCON_DECLARE(uart8250, early_serial8250_setup);
 EARLYCON_DECLARE(uart, early_serial8250_setup);
-
-int __init setup_early_serial8250_console(char *cmdline)
-{
-	return setup_earlycon(cmdline);
-}
include/linux/serial_8250.h +0 -1
index f26ae7f..ca9f87b 100644
@@ -120,7 +120,6 @@ extern int early_serial_setup(struct uart_port *port);
 
 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 int setup_early_serial8250_console(char *cmdline);
 extern void serial8250_do_set_termios(struct uart_port *port,
 		struct ktermios *termios, struct ktermios *old);
 extern int serial8250_do_startup(struct uart_port *port);
Signature · 1 line
2.3.1
#12 lore raw

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

Quoted 5 lines · Peter Hurley

setup_earlycon() will now match and register the desired earlycon from the param string (as if 'earlycon=...' had been set on the command line). Use setup_earlycon() from existing arch call sites which start an earlycon directly.

Hi,

Looks like this patcheset cause regression:
when set grub console to 115200, and later kernel only have

console=uart8250,io,0x3f8

the kernel will revert baud rate to 9600 instead of keeping 115200.

in setup_earlycon: you say:

* Registers the earlycon console matching the earlycon specified
* in the param string @buf. Acceptable param strings are of the form

 *         <name>,io|mmio|mmio32,<addr>,<options>
 *         <name>,0x<addr>,<options>
 *         <name>,<options>
 *         <name>
 *
 *      Only for the third form does the earlycon setup() method receive the
 *      <options> string in the 'options' parameter; all other forms set
 *      the parameter to NULL.

so that change the old behavior that we defined in Documentation/kernel-parameters.txt

uart[8250],io,<addr>[,options] uart[8250],mmio,<addr>[,options] uart[8250],mmio32,<addr>[,options]
Start an early, polled-mode console on the 8250/16550 UART at the specified I/O port or MMIO address. MMIO inter-register address stride is either 8-bit (mmio) or 32-bit (mmio32).
The options are the same as for ttyS, above.

The old behavior: options is optional , and will use baud rate that is set by bootloader.

Please fix the problem and restore to old behavior.

Thanks

Yinghai

#13 lore raw

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

Hi Yinghai,

Quoted 42 lines · Yinghai Lu
Quoted 5 lines · Peter Hurley

setup_earlycon() will now match and register the desired earlycon from the param string (as if 'earlycon=...' had been set on the command line). Use setup_earlycon() from existing arch call sites which start an earlycon directly.

Hi,

Looks like this patcheset cause regression:
when set grub console to 115200, and later kernel only have

console=uart8250,io,0x3f8

the kernel will revert baud rate to 9600 instead of keeping 115200.

in setup_earlycon: you say:

* Registers the earlycon console matching the earlycon specified
* in the param string @buf. Acceptable param strings are of the form

 *         <name>,io|mmio|mmio32,<addr>,<options>
 *         <name>,0x<addr>,<options>
 *         <name>,<options>
 *         <name>
 *
 *      Only for the third form does the earlycon setup() method receive the
 *      <options> string in the 'options' parameter; all other forms set
 *      the parameter to NULL.

so that change the old behavior that we defined in Documentation/kernel-parameters.txt

uart[8250],io,<addr>[,options] uart[8250],mmio,<addr>[,options] uart[8250],mmio32,<addr>[,options]
Start an early, polled-mode console on the 8250/16550 UART at the specified I/O port or MMIO address. MMIO inter-register address stride is either 8-bit (mmio) or 32-bit (mmio32).

Quoted 1 line

The options are the same as for ttyS, above.

                                      ^^^^^^^^^^^^

The documented behavior of console=ttyS options, to which your quote refers, clearly states:

		Default is "9600n8".
Quoted 2 lines

The old behavior: options is optional , and will use baud rate that is set by bootloader.

so the previous behavior was actually at odds with the documentation.

Quoted 1 line

Please fix the problem and restore to old behavior.

Is this really necessary (or even desirable)?
I think it's a bad idea to have one console type (ttyS) initialize its options to default settings, but yet allow another console type (uart) to probe the existing state.

Also, this expectation is an impediment when adding support for other 8250-like designs that don't have the same 8250 divisor registers (ie., _every_ new design). To properly support this requirement for just the existing 8250 hardware will require special probe_baud() functions for: dw_8250, intel byt, intel mid, omap_8250, exar 17v35 series, omap 1510.

Is specifying the line speed on the command line really a burden?

Regards,
Peter Hurley

#14 lore raw

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

Quoted 4 lines · Peter Hurley

The documented behavior of console=ttyS options, to which your quote refers, clearly states:

                Default is "9600n8".

drivers/tty/serial/8250/8250_early.c:early_serial8250_setup still have calling to probe_baud, but it is not triggered.

Here is root cause.
The gap between entries in earlycon_table cause iteration fail to find next entry, so uart8250 handler is not called proplerly.

attached patch fix the problem.

Thanks

Yinghai

Subject: [PATCH] serial: Fix earlycon section iteration

Found when booting with console=uart8250,io,0x3f8
the kernel will revert baud rate to 9600 instead of keeping 115200.

root causes: The gap between entries in earlycon_table cause iteration fail to find next entry, so uart8250 handler is not called proplerly.

commit d2fd6810a823 ("tty/serial: convert 8250 to generic earlycon") add two entries into earlycon_table.
EARLYCON_DECLARE(uart8250, early_serial8250_setup); EARLYCON_DECLARE(uart, early_serial8250_setup);

and according to System.map, earlycon_uart is before earlycon_uart8250.
ffffffff832049a0 t __earlycon_uart
ffffffff832049c0 t __earlycon_uart8250
And offset between two entries is 0x20.

commit 470ca0de69fe ("serial: earlycon: Enable earlycon without command line param") setup_earlycon() will loop __earlycon_table with pointer to earlycon_id,

	for (match = __earlycon_table; match->name[0]; match++) {
               size_t len = strlen(match->name);

               if (strncmp(buf, match->name, len))
                       continue;

but match size (size of struct earlycon_id) is only 0x18. so will point to wrong place for next match and will get random result.

Make the earlycon_table section have pointer to earlycon_id struct instead.

Fixes commit 470ca0de69fe ("serial: earlycon: Enable earlycon without command line param")
---
 drivers/tty/serial/earlycon.c     |   13 +++++++------
 include/asm-generic/vmlinux.lds.h |    8 ++++----
 include/linux/serial_core.h       |    8 +++++---
 3 files changed, 16 insertions(+), 13 deletions(-)
include/linux/serial_core.h +5 -3
Index: linux-2.6/include/linux/serial_core.h
===================================================================
@@ -349,10 +349,12 @@ extern int of_setup_earlycon(unsigned lo
 			     int (*setup)(struct earlycon_device *, const char *));
 
 #define EARLYCON_DECLARE(_name, func)					\
-	static const struct earlycon_id __earlycon_##_name		\
-		__used __section(__earlycon_table)			\
+	static struct earlycon_id __earlycon_##_name __initdata	\
 		 = { .name  = __stringify(_name),			\
-		     .setup = func  }
+		     .setup = func  };					\
+	static struct earlycon_id *__p_earlycon_##_name	__used		\
+		__aligned(sizeof(struct earlycon_id *))			\
+		__section(__earlycon_table) = { &__earlycon_##_name }
 
 #define OF_EARLYCON_DECLARE(name, compat, fn)				\
 	_OF_DECLARE(earlycon, name, compat, fn, void *)
drivers/tty/serial/earlycon.c +7 -6
Index: linux-2.6/drivers/tty/serial/earlycon.c
===================================================================
@@ -37,9 +37,8 @@ static struct earlycon_device early_cons
 	.con = &early_con,
 };
 
-extern struct earlycon_id __earlycon_table[];
-static const struct earlycon_id __earlycon_table_sentinel
-	__used __section(__earlycon_table_end);
+extern struct earlycon_id *__start_earlycon_table[];
+extern struct earlycon_id *__stop_earlycon_table[];
 
 static const struct of_device_id __earlycon_of_table_sentinel
 	__used __section(__earlycon_of_table_end);
@@ -103,7 +102,7 @@ static int __init parse_options(struct e
 	return 0;
 }
 
-static int __init register_earlycon(char *buf, const struct earlycon_id *match)
+static int __init register_earlycon(char *buf, struct earlycon_id *match)
 {
 	int err;
 	struct uart_port *port = &early_console_dev.port;
@@ -147,7 +146,7 @@ static int __init register_earlycon(char
  */
 int __init setup_earlycon(char *buf)
 {
-	const struct earlycon_id *match;
+	struct earlycon_id **pmatch;
 
 	if (!buf || !buf[0])
 		return -EINVAL;
@@ -155,7 +154,9 @@ int __init setup_earlycon(char *buf)
 	if (early_con.flags & CON_ENABLED)
 		return -EALREADY;
 
-	for (match = __earlycon_table; match->name[0]; match++) {
+	for (pmatch = __start_earlycon_table; pmatch < __stop_earlycon_table;
+	     pmatch++) {
+		struct earlycon_id *match = *pmatch;
 		size_t len = strlen(match->name);
 
 		if (strncmp(buf, match->name, len))
include/asm-generic/vmlinux.lds.h +4 -4
Index: linux-2.6/include/asm-generic/vmlinux.lds.h
===================================================================
@@ -151,10 +151,10 @@
 #endif
 
 #ifdef CONFIG_SERIAL_EARLYCON
-#define EARLYCON_TABLE() . = ALIGN(8);				\
-			 VMLINUX_SYMBOL(__earlycon_table) = .;	\
-			 *(__earlycon_table)			\
-			 *(__earlycon_table_end)
+#define EARLYCON_TABLE() . = ALIGN(8);					\
+			 VMLINUX_SYMBOL(__start_earlycon_table) = .;	\
+			 *(__earlycon_table)				\
+			 VMLINUX_SYMBOL(__stop_earlycon_table) = .;
 #else
 #define EARLYCON_TABLE()
 #endif
#15 lore raw

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

Hi Yinghai,

Quoted 6 lines · Yinghai Lu
Quoted 4 lines · Peter Hurley

The documented behavior of console=ttyS options, to which your quote refers, clearly states:

                Default is "9600n8".
Quoted 7 lines

drivers/tty/serial/8250/8250_early.c:early_serial8250_setup still have calling to probe_baud, but it is not triggered.

Here is root cause.
The gap between entries in earlycon_table cause iteration fail to find next entry, so uart8250 handler is not called proplerly.

Thanks for finding that bug; so the earlycon never started, right?

Quoted 1 line

attached patch fix the problem.

Would you please try the patch below instead?

Regards,
Peter Hurley

--- >% ---
From: Peter Hurley <[email protected]>
Subject: [PATCH] earlycon: Fix __earlycon_table stride

---
 include/asm-generic/vmlinux.lds.h | 2 +-
 include/linux/serial_core.h       | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)
include/asm-generic/vmlinux.lds.h +1 -1
index 7b0ef49..2e11f31 100644
@@ -151,7 +151,7 @@
 #endif
 
 #ifdef CONFIG_SERIAL_EARLYCON
-#define EARLYCON_TABLE() . = ALIGN(8);				\
+#define EARLYCON_TABLE() STRUCT_ALIGN();			\
 			 VMLINUX_SYMBOL(__earlycon_table) = .;	\
 			 *(__earlycon_table)			\
 			 *(__earlycon_table_end)
include/linux/serial_core.h +1 -1
index 34de168..025dad9 100644
@@ -342,7 +342,7 @@ struct earlycon_device {
 struct earlycon_id {
 	char	name[16];
 	int	(*setup)(struct earlycon_device *, const char *options);
-};
+} __aligned(32);
 
 extern int setup_earlycon(char *buf);
 extern int of_setup_earlycon(unsigned long addr,
Signature · 1 line
2.3.5
#16 lore raw

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

Quoted 30 lines · Peter Hurley

Would you please try the patch below instead?

--- >% ---
From: Peter Hurley <[email protected]>
Subject: [PATCH] earlycon: Fix __earlycon_table stride

---
 include/asm-generic/vmlinux.lds.h | 2 +-
 include/linux/serial_core.h       | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)
include/asm-generic/vmlinux.lds.h +1 -1
index 7b0ef49..2e11f31 100644
@@ -151,7 +151,7 @@
 #endif
 
 #ifdef CONFIG_SERIAL_EARLYCON
-#define EARLYCON_TABLE() . = ALIGN(8);                         \
+#define EARLYCON_TABLE() STRUCT_ALIGN();                       \
                         VMLINUX_SYMBOL(__earlycon_table) = .;  \
                         *(__earlycon_table)                    \
                         *(__earlycon_table_end)
include/linux/serial_core.h +0 -0
index 34de168..025dad9 100644

include/linux/serial_core.h struct earlycon_device {

Quoted 9 lines
include/linux/serial_core.h +1 -2
@@ -342,7 +342,7 @@ struct earlycon_device {
 struct earlycon_id {
        char    name[16];
        int     (*setup)(struct earlycon_device *, const char *options);
-};
+} __aligned(32);
 
 extern int setup_earlycon(char *buf);
 extern int of_setup_earlycon(unsigned long addr,
--

Great. that works, and less lines change than my version.

ffffffff832049a0 T __earlycon_table
ffffffff832049a0 t __earlycon_uart
ffffffff832049c0 t __earlycon_uart8250
ffffffff832049e0 t __earlycon_table_sentinel

[    0.000000] bootconsole [uart0] enabled
[    0.000000] uart8250 probed_baud_rate: 115200
[    0.000000] size of earlycon_id: 0x20

Thanks

Yinghai

#17 lore raw

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

Quoted 6 lines · Yinghai Lu
Quoted 2 lines · Peter Hurley

Would you please try the patch below instead?

Great. that works, and less lines change than my version.

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.

#18 lore raw

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

Quoted 5 lines · Yinghai Lu
Quoted 4 lines · Yinghai Lu
Quoted 2 lines · Peter Hurley

Would you please try the patch below instead?

Quoted 8 lines
Quoted 2 lines

Great. that works, and less lines change than my version.

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 <[email protected]>
Date:   Mon Mar 9 16:27:12 2015 -0400

console: Add extensible console matching

#19 lore raw

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

Quoted 15 lines · Yinghai Lu
Quoted 5 lines · Yinghai Lu
Quoted 4 lines · Yinghai Lu
Quoted 2 lines · Peter Hurley

Would you please try the patch below instead?

Quoted 8 lines
Quoted 2 lines

Great. that works, and less lines change than my version.

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.

Quoted 7 lines

this regression should be caused by:

commit c7cef0a84912cab3c9df8949b034e4aa62982ec9

Author: Peter Hurley <[email protected]>
Date:   Mon Mar 9 16:27:12 2015 -0400

console: Add extensible console matching

current code will:
for earlycon, will probe baud rate, and save it back to device->options.

and later update the command line
uart to ttyS, update the options with baud rate.

And your change will not try to find the exact port to have baud rate. and just use command.
So will have have that probed baud rate passed.

Please check if you can fix this regression. Maybe you have to put back command line update code back.

Thanks

Yinghai

#20 lore raw

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

Quoted 16 lines · Yinghai Lu
Quoted 15 lines · Yinghai Lu
Quoted 13 lines · Yinghai Lu
Quoted 6 lines · Yinghai Lu
Quoted 2 lines · Peter Hurley

Would you please try the patch below instead?

Great. that works, and less lines change than my version.

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.

Quoted 8 lines
Quoted 7 lines

this regression should be caused by:

commit c7cef0a84912cab3c9df8949b034e4aa62982ec9

Author: Peter Hurley <[email protected]>
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 ?

Thanks

Yinghai

#21 lore raw

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

Quoted 12 lines · Yinghai Lu
Quoted 12 lines
Quoted 12 lines
Quoted 5 lines

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 <[email protected]>
Date:   Mon Mar 9 16:27:12 2015 -0400
Quoted 5 lines
Quoted 2 lines
Quoted 1 line

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")
---
 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(-)
drivers/tty/serial/8250/8250_core.c +12 -2
Index: 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);
 	}
 
drivers/tty/serial/8250/8250_early.c +19 -0
Index: 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;
 }
include/linux/serial_8250.h +1 -0
Index: 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,
kernel/printk/printk.c +1 -1
Index: 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)
include/linux/console.h +1 -1
Index: 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;
#22 lore raw

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

Quoted 16 lines · Yinghai Lu
Quoted 14 lines · Yinghai Lu
Quoted 14 lines
Quoted 13 lines
Quoted 5 lines

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 <[email protected]>
Date:   Mon Mar 9 16:27:12 2015 -0400

console: Add extensible console matching

Quoted 8 lines
Quoted 3 lines

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?

Please re-read my first response to this problem.

Regards,
Peter Hurley

#23 lore raw

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

Quoted 29 lines · Peter Hurley
Quoted 16 lines · Yinghai Lu
Quoted 14 lines · Yinghai Lu
Quoted 14 lines
Quoted 13 lines
Quoted 5 lines

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 <[email protected]>
Date:   Mon Mar 9 16:27:12 2015 -0400

console: Add extensible console matching

Quoted 8 lines
Quoted 3 lines

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?

Please re-read my first response to this problem.

Quoted 6 lines

Also, this expectation is an impediment when adding support for other 8250-like designs that don't have the same 8250 divisor registers (ie., _every_ new design). To properly support this requirement for just the existing 8250 hardware will require special probe_baud() functions for: dw_8250, intel byt, intel mid, omap_8250, exar 17v35 series, omap 1510.

But you can not break old setup!

old behavior: console=uart8250,io,0x3f8

when bootloader or firmware has 115200 used already, earlycon, and console all keep 115200.

Now with your change, earlycon will use 115200 still, but console will switch to 9600.

Quoted 3 lines

Is specifying the line speed on the command line really a burden?

Yes. We have two setups, and two BIOS versions. product version is using 9600 and devel/debug is using 115200.

This is a regression, and must be addressed.

Greg,

Please don't send merge request for tty-next to Linus before this regression get resolved.

Thanks

Yinghai

#24 lore raw

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

Quoted 48 lines · Yinghai Lu
Quoted 29 lines · Peter Hurley
Quoted 16 lines · Yinghai Lu
Quoted 14 lines · Yinghai Lu
Quoted 14 lines
Quoted 13 lines
Quoted 5 lines

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 <[email protected]>
Date:   Mon Mar 9 16:27:12 2015 -0400

console: Add extensible console matching

Quoted 8 lines
Quoted 3 lines

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?

Please re-read my first response to this problem.

Quoted 6 lines

Also, this expectation is an impediment when adding support for other 8250-like designs that don't have the same 8250 divisor registers (ie., _every_ new design). To properly support this requirement for just the existing 8250 hardware will require special probe_baud() functions for: dw_8250, intel byt, intel mid, omap_8250, exar 17v35 series, omap 1510.

But you can not break old setup!

old behavior: console=uart8250,io,0x3f8

when bootloader or firmware has 115200 used already, earlycon, and console all keep 115200.

Now with your change, earlycon will use 115200 still, but console will switch to 9600.

Quoted 1 line
Quoted 5 lines
Quoted 2 lines

Is specifying the line speed on the command line really a burden?

Yes. We have two setups, and two BIOS versions. product version is using 9600 and devel/debug is using 115200.

Wait -- you have earlycon in a product??

Quoted 6 lines

This is a regression, and must be addressed.

Greg,

Please don't send merge request for tty-next to Linus before this regression get resolved.

#25 lore raw

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

Quoted 3 lines · Peter Hurley

On 04/03/2015 12:57 PM, Yinghai Lu wrote:

Wait -- you have earlycon in a product??

What do you mean?

when you are using "console=uart8250,io,0x3f8" you will have earlycon at first, and handover to console.

#26 lore raw

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

Quoted 6 lines · Yinghai Lu
Quoted 3 lines · Peter Hurley

On 04/03/2015 12:57 PM, Yinghai Lu wrote:

Wait -- you have earlycon in a product??

What do you mean?

I mean, what will happen if I put in a big debug banner like Steven did for ftrace?

Kernel developers need earlycon for debugging arch code; often the earlycon is just hacked together especially when it requires fixmap support.

Putting it in a product and _relying on undocumented behavior_ is a bad idea.

Quoted 2 lines

when you are using "console=uart8250,io,0x3f8" you will have earlycon at first, and handover to console.

which means you have to have CONFIG_SERIAL_EARLYCON to get a serial console at all.

I have no problem fixing this _if this is causing actual regressions_, and not simply some minor inconvenience that can be fixed by editing your grub command line.

However, I see this undocumented behavior as a cautionary tale for why not every kernel command line hack should be accepted in mainline.

Regards,
Peter Hurley

#27 lore raw

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

Quoted 3 lines · Peter Hurley

I have no problem fixing this _if this is causing actual regressions_, and not simply some minor inconvenience that can be fixed by editing your grub command line.

But, you can't break working command lines from previous kernel releases. Undocumented or not, sorry. It's a working configuration. Upgrading a kernel can not break that.

sorry,

greg k-h

#28 lore raw

PATCH 1/1 earlycon: 8250: Fix command line regression

Restore undocumented behavior of kernel command line parameters of the forms:

    console=uart[####],io|mmio|mmio32,<addr>[,options]
    console=uart[####],<addr>[,options]

where 'options' have not been specified; in this case, the hardware is assumed to be initialized.

Document the required behavior of the original implementation.

---
 Documentation/kernel-parameters.txt  | 15 +++++++++++----
 drivers/tty/serial/8250/8250_core.c  | 15 ++++++++++++++-
 drivers/tty/serial/8250/8250_early.c | 19 -------------------
 3 files changed, 25 insertions(+), 24 deletions(-)
Documentation/kernel-parameters.txt +11 -4
index bfcb1a6..59c9832 100644
@@ -711,12 +711,19 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 			Documentation/networking/netconsole.txt for an
 			alternative.
 
-		uart[8250],io,<addr>[,options]
-		uart[8250],mmio,<addr>[,options]
+		uart[<n>],io,<addr>[,options]
+		uart[<n>],mmio,<addr>[,options]
+		uart[<n>],mmio32,<addr>[,options]
+		uart[<n>],0x<addr>[,options]
 			Start an early, polled-mode console on the 8250/16550
 			UART at the specified I/O port or MMIO address,
-			switching to the matching ttyS device later.  The
-			options are the same as for ttyS, above.
+			switching to the matching ttyS device later.
+			Any optional number <n> is accepted and ignored.
+			If none of [io|mmio|mmio32], <addr> is assumed to be
+			equivalent to 'mmio'. 'options' are specified in the
+			same format described for ttyS above; if unspecified,
+			the h/w is not re-initialized.
+
 		hvc<n>	Use the hypervisor console device <n>. This is for
 			both Xen and PowerPC hypervisors.
 
drivers/tty/serial/8250/8250_core.c +14 -1
index e0fb5f0..5f41a9c 100644
@@ -3456,12 +3456,17 @@ static int univ8250_console_setup(struct console *co, char *options)
  *
  *	Only attempts to match console command lines of the form:
  *	    console=uart<>,io|mmio|mmio32,<addr>,<options>
- *	    console=uart<>,<addr>,options
+ *	    console=uart<>,0x<addr>,<options>
  *	This form is used to register an initial earlycon boot console and
  *	replace it with the serial8250_console at 8250 driver init.
  *
  *	Performs console setup for a match (as required by interface)
  *
+ *	** HACK ALERT **
+ *	If no <options> are specified, then assume the h/w is already setup.
+ *	This was the undocumented behavior of the original implementation so
+ *	it is cast in stone forever.
+ *
  *	Returns 0 if console matches; otherwise non-zero to use default matching
  */
 static int univ8250_console_match(struct console *co, char *name, int idx,
@@ -3491,6 +3496,14 @@ static int univ8250_console_match(struct console *co, char *name, int idx,
 			continue;
 
 		co->index = i;
+
+		/* if no line settings, then assume h/w was setup */
+		if (!options) {
+			/* link port to console */
+			port->cons = co;
+			return 0;
+		}
+
 		return univ8250_console_setup(co, options);
 	}
 
drivers/tty/serial/8250/8250_early.c +0 -19
index e95ebfe..8e11968 100644
@@ -105,21 +105,6 @@ static void __init early_serial8250_write(struct console *console,
 		serial8250_early_out(port, UART_IER, ier);
 }
 
-static unsigned int __init probe_baud(struct uart_port *port)
-{
-	unsigned char lcr, dll, dlm;
-	unsigned int quot;
-
-	lcr = serial8250_early_in(port, UART_LCR);
-	serial8250_early_out(port, UART_LCR, lcr | UART_LCR_DLAB);
-	dll = serial8250_early_in(port, UART_DLL);
-	dlm = serial8250_early_in(port, UART_DLM);
-	serial8250_early_out(port, UART_LCR, lcr);
-
-	quot = (dlm << 8) | dll;
-	return (port->uartclk / 16) / quot;
-}
-
 static void __init init_port(struct earlycon_device *device)
 {
 	struct uart_port *port = &device->port;
@@ -151,10 +136,6 @@ static int __init early_serial8250_setup(struct earlycon_device *device,
 		struct uart_port *port = &device->port;
 		unsigned int ier;
 
-		device->baud = probe_baud(&device->port);
-		snprintf(device->options, sizeof(device->options), "%u",
-			 device->baud);
-
 		/* assume the device was initialized, only mask interrupts */
 		ier = serial8250_early_in(port, UART_IER);
 		serial8250_early_out(port, UART_IER, ier & UART_IER_UUE);
Signature · 1 line
2.3.5
#29 lore raw

PATCH v2 1/1 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.

Document the required behavior of the original implementation.

---

v2: Fixed regression which allowed "console=uart1337,..." to start a
console (but not an earlycon)
+ fixed earlycon= documentation related required behavior fixed by this patch

 Documentation/kernel-parameters.txt  | 18 +++++++++++++++---
 drivers/tty/serial/8250/8250_core.c  | 20 ++++++++++++++++++--
 drivers/tty/serial/8250/8250_early.c | 19 -------------------
 3 files changed, 33 insertions(+), 24 deletions(-)
Documentation/kernel-parameters.txt +15 -3
index bfcb1a6..1facf0b 100644
@@ -713,10 +713,18 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 
 		uart[8250],io,<addr>[,options]
 		uart[8250],mmio,<addr>[,options]
+		uart[8250],mmio32,<addr>[,options]
+		uart[8250],0x<addr>[,options]
 			Start an early, polled-mode console on the 8250/16550
 			UART at the specified I/O port or MMIO address,
-			switching to the matching ttyS device later.  The
-			options are the same as for ttyS, above.
+			switching to the matching ttyS device later.
+			MMIO inter-register address stride is either 8-bit
+			(mmio) or 32-bit (mmio32).
+			If none of [io|mmio|mmio32], <addr> is assumed to be
+			equivalent to 'mmio'. 'options' are specified in the
+			same format described for ttyS above; if unspecified,
+			the h/w is not re-initialized.
+
 		hvc<n>	Use the hypervisor console device <n>. This is for
 			both Xen and PowerPC hypervisors.
 
@@ -944,11 +952,15 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 		uart[8250],io,<addr>[,options]
 		uart[8250],mmio,<addr>[,options]
 		uart[8250],mmio32,<addr>[,options]
+		uart[8250],0x<addr>[,options]
 			Start an early, polled-mode console on the 8250/16550
 			UART at the specified I/O port or MMIO address.
 			MMIO inter-register address stride is either 8-bit
 			(mmio) or 32-bit (mmio32).
-			The options are the same as for ttyS, above.
+			If none of [io|mmio|mmio32], <addr> is assumed to be
+			equivalent to 'mmio'. 'options' are specified in the
+			same format described for "console=ttyS<n>"; if
+			unspecified, the h/w is not initialized.
 
 		pl011,<addr>
 			Start an early, polled-mode console on a pl011 serial
drivers/tty/serial/8250/8250_core.c +18 -2
index e0fb5f0..bda2a57 100644
@@ -3455,13 +3455,18 @@ static int univ8250_console_setup(struct console *co, char *options)
  *	@options: 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>
- *	    console=uart<>,<addr>,options
+ *	    console=uart[8250],io|mmio|mmio32,<addr>[,<options>]
+ *	    console=uart[8250],0x<addr>[,<options>]
  *	This form is used to register an initial earlycon boot console and
  *	replace it with the serial8250_console at 8250 driver init.
  *
  *	Performs console setup for a match (as required by interface)
  *
+ *	** HACK ALERT **
+ *	If no <options> are specified, then assume the h/w is already setup.
+ *	This was the undocumented behavior of the original implementation so
+ *	it is cast in stone forever.
+ *
  *	Returns 0 if console matches; otherwise non-zero to use default matching
  */
 static int univ8250_console_match(struct console *co, char *name, int idx,
@@ -3475,6 +3480,9 @@ static int univ8250_console_match(struct console *co, char *name, int idx,
 	if (strncmp(name, match, 4) != 0)
 		return -ENODEV;
 
+	if (idx && idx != 8250)
+		return -ENODEV;
+
 	if (uart_parse_earlycon(options, &iotype, &addr, &options))
 		return -ENODEV;
 
@@ -3491,6 +3499,14 @@ static int univ8250_console_match(struct console *co, char *name, int idx,
 			continue;
 
 		co->index = i;
+
+		/* if no line settings, then assume h/w was setup */
+		if (!options) {
+			/* link port to console */
+			port->cons = co;
+			return 0;
+		}
+
 		return univ8250_console_setup(co, options);
 	}
 
drivers/tty/serial/8250/8250_early.c +0 -19
index e95ebfe..8e11968 100644
@@ -105,21 +105,6 @@ static void __init early_serial8250_write(struct console *console,
 		serial8250_early_out(port, UART_IER, ier);
 }
 
-static unsigned int __init probe_baud(struct uart_port *port)
-{
-	unsigned char lcr, dll, dlm;
-	unsigned int quot;
-
-	lcr = serial8250_early_in(port, UART_LCR);
-	serial8250_early_out(port, UART_LCR, lcr | UART_LCR_DLAB);
-	dll = serial8250_early_in(port, UART_DLL);
-	dlm = serial8250_early_in(port, UART_DLM);
-	serial8250_early_out(port, UART_LCR, lcr);
-
-	quot = (dlm << 8) | dll;
-	return (port->uartclk / 16) / quot;
-}
-
 static void __init init_port(struct earlycon_device *device)
 {
 	struct uart_port *port = &device->port;
@@ -151,10 +136,6 @@ static int __init early_serial8250_setup(struct earlycon_device *device,
 		struct uart_port *port = &device->port;
 		unsigned int ier;
 
-		device->baud = probe_baud(&device->port);
-		snprintf(device->options, sizeof(device->options), "%u",
-			 device->baud);
-
 		/* assume the device was initialized, only mask interrupts */
 		ier = serial8250_early_in(port, UART_IER);
 		serial8250_early_out(port, UART_IER, ier & UART_IER_UUE);
Signature · 1 line
2.3.5
#30 lore raw

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

Quoted 6 lines · Peter Hurley

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.

Please separated bug fix and other documentation change to different patches.

also fix the patch title to make it clear and you need to mention which commit cause the regression.

This patch fix regression for the hand over. Thanks.

Another regression.
when user have
console=uart8250,io,0x3f8 console=uart8250,io,0x2f8

before your patchset:
port_0x3f8 is early console, and will be console later. and port_0x2f8 is ignored, because only ONE early console is allowed.
and old console setup, only handle ttyS0.

after your patchset:
port_0x3f8 is early console, and will be console later. port_0x2f8 will become default console, as new console with match method
treat all uart8250 as ttyS0.

Please fix that too.

#31 lore raw

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

Quoted 10 lines · Yinghai Lu
Quoted 6 lines · Peter Hurley

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.

Please separated bug fix and other documentation change to different patches.

No. The documentation reflects exactly what the bug fix is for.

Quoted 2 lines

also fix the patch title to make it clear and you need to mention which commit cause the regression.

Please bisect and send bisect log so I know which commit broke your setup.

Quoted 11 lines

This patch fix regression for the hand over. Thanks.

Another regression.
when user have
console=uart8250,io,0x3f8 console=uart8250,io,0x2f8

before your patchset:
port_0x3f8 is early console, and will be console later. and port_0x2f8 is ignored, because only ONE early console is allowed.
and old console setup, only handle ttyS0.

Quoted 6 lines

after your patchset:
port_0x3f8 is early console, and will be console later. port_0x2f8 will become default console, as new console with match method
treat all uart8250 as ttyS0.

Please fix that too.

That's a new feature, not a regression.

#32 lore raw

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

Quoted 10 lines · Peter Hurley
Quoted 9 lines · Yinghai Lu

Another regression.
when user have
console=uart8250,io,0x3f8 console=uart8250,io,0x2f8

before your patchset:
port_0x3f8 is early console, and will be console later. and port_0x2f8 is ignored, because only ONE early console is allowed.
and old console setup, only handle ttyS0.

Quoted 8 lines
Quoted 6 lines

after your patchset:
port_0x3f8 is early console, and will be console later. port_0x2f8 will become default console, as new console with match method
treat all uart8250 as ttyS0.

Please fix that too.

That's a new feature, not a regression.

So, in all seriousness, you actually have this setup and want me to fix this?

IOW, to support more than 1 earlycon in the future will require using a totally different command line parameter. Awesome.

#33 lore raw

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

Quoted 16 lines · Peter Hurley
Quoted 15 lines · Peter Hurley
Quoted 14 lines · Yinghai Lu

Another regression.
when user have
console=uart8250,io,0x3f8 console=uart8250,io,0x2f8

before your patchset:
port_0x3f8 is early console, and will be console later. and port_0x2f8 is ignored, because only ONE early console is allowed.
and old console setup, only handle ttyS0.

after your patchset:
port_0x3f8 is early console, and will be console later. port_0x2f8 will become default console, as new console with match method
treat all uart8250 as ttyS0.

Quoted 6 lines
Quoted 3 lines
Quoted 1 line

Please fix that too.

That's a new feature, not a regression.

So, in all seriousness, you actually have this setup and want me to fix this?

No.

Just add one count in the console match for it.

Quoted 4 lines

IOW, to support more than 1 earlycon in the future will require using a totally different command line parameter. Awesome.

That is future, right? Show me patch.

Thanks

Yinghai

#34 lore raw

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

In reply to Peter Hurley
Quoted 10 lines · Peter Hurley
Quoted 9 lines · Yinghai Lu
Quoted 6 lines · Peter Hurley

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.

Quoted 3 lines
Quoted 1 line

Please separated bug fix and other documentation change to different patches.

No. The documentation reflects exactly what the bug fix is for.

what is

+ uart[<n>],mmio,<addr>[,options]
+ uart[<n>],mmio32,<addr>[,options]

Quoted 6 lines
Quoted 3 lines

also fix the patch title to make it clear and you need to mention which commit cause the regression.

Please bisect and send bisect log so I know which commit broke your setup.

I already gave your the patch "title". Here it is again:

commit c7cef0a84912cab3c9df8949b034e4aa62982ec9

Author: Peter Hurley <[email protected]>
Date:   Mon Mar 9 16:27:12 2015 -0400

console: Add extensible console matching

Quoted 12 lines
Quoted 12 lines

This patch fix regression for the hand over. Thanks.

Another regression.
when user have
console=uart8250,io,0x3f8 console=uart8250,io,0x2f8

before your patchset:
port_0x3f8 is early console, and will be console later. and port_0x2f8 is ignored, because only ONE early console is allowed.
and old console setup, only handle ttyS0.

Quoted 8 lines
Quoted 6 lines

after your patchset:
port_0x3f8 is early console, and will be console later. port_0x2f8 will become default console, as new console with match method
treat all uart8250 as ttyS0.

Please fix that too.

That's a new feature, not a regression.

ok, think that more.

with this patch:

[PATCH] earlycon: 8250: Fix command line regression

When you have console=uart8250,io,0x3f8 console=uart,io,0x2f8

you will skip the setup to 0x2f8, as the options is null. then if the bios or bootloader only setup baud rate for 0x3f8. the user could get nothing from 0x2f8.

Do you need to call univ8250_console_setup(co, options) to set the default baud rate ?

#35 lore raw

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

Quoted 17 lines · Yinghai Lu
Quoted 10 lines · Peter Hurley
Quoted 9 lines · Yinghai Lu
Quoted 6 lines · Peter Hurley

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.

Quoted 3 lines
Quoted 1 line

Please separated bug fix and other documentation change to different patches.

No. The documentation reflects exactly what the bug fix is for.

what is

Review

Quoted 2 lines
(quoted diff) +2 -0
+               uart[<n>],mmio,<addr>[,options]
+               uart[<n>],mmio32,<addr>[,options]

Wrong patch version; that's v1.

Quoted 6 lines
Quoted 5 lines
Quoted 2 lines

also fix the patch title to make it clear and you need to mention which commit cause the regression.

Please bisect and send bisect log so I know which commit broke your setup.

Quoted 7 lines

I already gave your the patch "title". Here it is again:

commit c7cef0a84912cab3c9df8949b034e4aa62982ec9

Author: Peter Hurley <[email protected]>
Date:   Mon Mar 9 16:27:12 2015 -0400

console: Add extensible console matching

Ok.

Quoted 26 lines
Quoted 11 lines
Quoted 11 lines

This patch fix regression for the hand over. Thanks.

Another regression.
when user have
console=uart8250,io,0x3f8 console=uart8250,io,0x2f8

before your patchset:
port_0x3f8 is early console, and will be console later. and port_0x2f8 is ignored, because only ONE early console is allowed.
and old console setup, only handle ttyS0.

Quoted 8 lines
Quoted 6 lines

after your patchset:
port_0x3f8 is early console, and will be console later. port_0x2f8 will become default console, as new console with match method
treat all uart8250 as ttyS0.

Please fix that too.

That's a new feature, not a regression.

ok, think that more.

with this patch:

[PATCH] earlycon: 8250: Fix command line regression

Quoted 8 lines

When you have console=uart8250,io,0x3f8 console=uart,io,0x2f8

you will skip the setup to 0x2f8, as the options is null. then if the bios or bootloader only setup baud rate for 0x3f8. the user could get nothing from 0x2f8.

Do you need to call univ8250_console_setup(co, options) to set the default baud rate ?

No. The user specified that the console had already been initialized by leaving out the option string. Isn't that what this whole email thread has been about?

All this automatic behavior and aliases for the same things just adds unnecessary complexity and maintenance burden, without measurable gain.

The real tragedy is that all this was totally unnecessary; what was wrong with "earlycon=uart,io,0x3f8 console=ttyS0"?

Regards,
Peter Hurley

#36 lore raw

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

Quoted 7 lines · Peter Hurley

All this automatic behavior and aliases for the same things just adds unnecessary complexity and maintenance burden, without measurable gain.

The real tragedy is that all this was totally unnecessary; what was wrong with "earlycon=uart,io,0x3f8 console=ttyS0"?

When I worked on the patch

| commit 18a8bd949d6adb311ea816125ff65050df1f3f6e
| Date:   Sun Jul 15 23:37:59 2007 -0700
|
|    serial: convert early_uart to earlycon for 8250

Andrew requested that.

Thanks

Yinghai

#37 lore raw

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

In reply to Yinghai Lu
Quoted 10 lines · Yinghai Lu
Quoted 6 lines · Peter Hurley

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.

So the patch does not fix the regression from

commit c7cef0a84912cab3c9df8949b034e4aa62982ec9

Author: Peter Hurley <[email protected]>
Date:   Mon Mar 9 16:27:12 2015 -0400

console: Add extensible console matching

#38 lore raw

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

Quoted 10 lines · Yinghai Lu
Quoted 9 lines · Yinghai Lu
Quoted 6 lines · Peter Hurley

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.

Quoted 5 lines
Quoted 1 line

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.

Please share the init scripts.

#39 lore raw

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

Quoted 11 lines · Peter Hurley
Quoted 10 lines · Yinghai Lu
Quoted 9 lines · Yinghai Lu
Quoted 6 lines · Peter Hurley

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.

Quoted 7 lines
Quoted 5 lines
Quoted 1 line

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.

Please share the init scripts.

I am using opensuse 13.1 rescue disk as ramdisk.

#40 lore raw

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

Quoted 14 lines · Yinghai Lu
Quoted 13 lines · Peter Hurley
Quoted 12 lines · Yinghai Lu
Quoted 10 lines · Yinghai Lu
Quoted 6 lines · Peter Hurley

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.

Quoted 7 lines
Quoted 5 lines
Quoted 3 lines

Just now noticed, this patch only fix partial problem. Kernel console is ok.

But later initrd/init scripts revert back to 9600 again.

Please share the init scripts.

I am using opensuse 13.1 rescue disk as ramdisk.

or opensuse 12.3 rescue disk.

#41 lore raw

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

In reply to Yinghai Lu
Quoted 14 lines · Yinghai Lu
Quoted 13 lines · Peter Hurley
Quoted 12 lines · Yinghai Lu
Quoted 10 lines · Yinghai Lu
Quoted 6 lines · Peter Hurley

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.

Quoted 7 lines
Quoted 5 lines
Quoted 3 lines

Just now noticed, this patch only fix partial problem. Kernel console is ok.

But later initrd/init scripts revert back to 9600 again.

Please share the init scripts.

I am using opensuse 13.1 rescue disk as ramdisk.

NVM, I know what the problem is.

#42 lore raw

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

Quoted 11 lines · Peter Hurley
Quoted 8 lines
Quoted 6 lines
Quoted 4 lines

Just now noticed, this patch only fix partial problem. Kernel console is ok.

But later initrd/init scripts revert back to 9600 again.

Please share the init scripts.

I am using opensuse 13.1 rescue disk as ramdisk.

NVM, I know what the problem is.

What is NVM here?

#43 lore raw

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

Quoted 1 line · Yinghai Lu

What is NVM here?

nvm == nevermind

#44 lore raw

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

In reply to Peter Hurley
Quoted 13 lines · Peter Hurley
Quoted 12 lines · Yinghai Lu
Quoted 11 lines · Peter Hurley
Quoted 10 lines · Yinghai Lu
Quoted 9 lines · Yinghai Lu
Quoted 6 lines · Peter Hurley

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.

Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
Quoted 5 lines
Quoted 1 line

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

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")

---
-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(+)
drivers/tty/serial/8250/8250_core.c +4 -0
Index: 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);
 	}
 
drivers/tty/serial/8250/8250_early.c +17 -0
Index: 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;
 }
include/linux/serial_8250.h +1 -0
Index: 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,
#45 lore raw

PATCH v3 1/1 earlycon: 8250: Fix command line regression

In reply to Peter Hurley

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.

Document the required behavior of the original implementation.

Fixes c7cef0a84912cab3c9df8 ("console: Add extensible console matching")

---

v3: Fixed automatic console to port line settings initialization;
open-coded serial8250_console_setup() so the baud can be probed; added sha reference in commit log

v2: Fixed regression which allowed "console=uart1337,..." to start a
console (but not an earlycon)
+ fixed earlycon= documentation related required behavior fixed by this patch

 Documentation/kernel-parameters.txt  | 18 ++++++++++++++---
 drivers/tty/serial/8250/8250_core.c  | 38 +++++++++++++++++++++++++++++++++---
 drivers/tty/serial/8250/8250_early.c | 19 ------------------
 3 files changed, 50 insertions(+), 25 deletions(-)
Documentation/kernel-parameters.txt +15 -3
index bfcb1a6..1facf0b 100644
@@ -713,10 +713,18 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 
 		uart[8250],io,<addr>[,options]
 		uart[8250],mmio,<addr>[,options]
+		uart[8250],mmio32,<addr>[,options]
+		uart[8250],0x<addr>[,options]
 			Start an early, polled-mode console on the 8250/16550
 			UART at the specified I/O port or MMIO address,
-			switching to the matching ttyS device later.  The
-			options are the same as for ttyS, above.
+			switching to the matching ttyS device later.
+			MMIO inter-register address stride is either 8-bit
+			(mmio) or 32-bit (mmio32).
+			If none of [io|mmio|mmio32], <addr> is assumed to be
+			equivalent to 'mmio'. 'options' are specified in the
+			same format described for ttyS above; if unspecified,
+			the h/w is not re-initialized.
+
 		hvc<n>	Use the hypervisor console device <n>. This is for
 			both Xen and PowerPC hypervisors.
 
@@ -944,11 +952,15 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 		uart[8250],io,<addr>[,options]
 		uart[8250],mmio,<addr>[,options]
 		uart[8250],mmio32,<addr>[,options]
+		uart[8250],0x<addr>[,options]
 			Start an early, polled-mode console on the 8250/16550
 			UART at the specified I/O port or MMIO address.
 			MMIO inter-register address stride is either 8-bit
 			(mmio) or 32-bit (mmio32).
-			The options are the same as for ttyS, above.
+			If none of [io|mmio|mmio32], <addr> is assumed to be
+			equivalent to 'mmio'. 'options' are specified in the
+			same format described for "console=ttyS<n>"; if
+			unspecified, the h/w is not initialized.
 
 		pl011,<addr>
 			Start an early, polled-mode console on a pl011 serial
drivers/tty/serial/8250/8250_core.c +35 -3
index e0fb5f0..f59c7a0 100644
@@ -3447,6 +3447,22 @@ static int univ8250_console_setup(struct console *co, char *options)
 	return serial8250_console_setup(up, options);
 }
 
+/* FIXME: this is broken on most other 8250 h/w */
+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;
+}
+
 /**
  *	univ8250_console_match - non-standard console matching
  *	@co:	  registering console
@@ -3455,13 +3471,18 @@ static int univ8250_console_setup(struct console *co, char *options)
  *	@options: 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>
- *	    console=uart<>,<addr>,options
+ *	    console=uart[8250],io|mmio|mmio32,<addr>[,<options>]
+ *	    console=uart[8250],0x<addr>[,<options>]
  *	This form is used to register an initial earlycon boot console and
  *	replace it with the serial8250_console at 8250 driver init.
  *
  *	Performs console setup for a match (as required by interface)
  *
+ *	** HACK ALERT **
+ *	If no <options> are specified, then assume the h/w is already setup.
+ *	This was the undocumented behavior of the original implementation so
+ *	it is cast in stone forever.
+ *
  *	Returns 0 if console matches; otherwise non-zero to use default matching
  */
 static int univ8250_console_match(struct console *co, char *name, int idx,
@@ -3475,12 +3496,16 @@ static int univ8250_console_match(struct console *co, char *name, int idx,
 	if (strncmp(name, match, 4) != 0)
 		return -ENODEV;
 
+	if (idx && idx != 8250)
+		return -ENODEV;
+
 	if (uart_parse_earlycon(options, &iotype, &addr, &options))
 		return -ENODEV;
 
 	/* try to match the port specified on the command line */
 	for (i = 0; i < nr_uarts; i++) {
 		struct uart_port *port = &serial8250_ports[i].port;
+		int baud, bits = 8, parity = 'n', flow = 'n';
 
 		if (port->iotype != iotype)
 			continue;
@@ -3490,8 +3515,15 @@ static int univ8250_console_match(struct console *co, char *name, int idx,
 		if (iotype == UPIO_PORT && port->iobase != addr)
 			continue;
 
+		/* link port to console */
 		co->index = i;
-		return univ8250_console_setup(co, options);
+		port->cons = co;
+
+		if (options && *options)
+			uart_parse_options(options, &baud, &parity, &bits, &flow);
+		else
+			baud = probe_baud(port);
+		return uart_set_options(port, port->cons, baud, parity, bits, flow);
 	}
 
 	return -ENODEV;
drivers/tty/serial/8250/8250_early.c +0 -19
index e95ebfe..8e11968 100644
@@ -105,21 +105,6 @@ static void __init early_serial8250_write(struct console *console,
 		serial8250_early_out(port, UART_IER, ier);
 }
 
-static unsigned int __init probe_baud(struct uart_port *port)
-{
-	unsigned char lcr, dll, dlm;
-	unsigned int quot;
-
-	lcr = serial8250_early_in(port, UART_LCR);
-	serial8250_early_out(port, UART_LCR, lcr | UART_LCR_DLAB);
-	dll = serial8250_early_in(port, UART_DLL);
-	dlm = serial8250_early_in(port, UART_DLM);
-	serial8250_early_out(port, UART_LCR, lcr);
-
-	quot = (dlm << 8) | dll;
-	return (port->uartclk / 16) / quot;
-}
-
 static void __init init_port(struct earlycon_device *device)
 {
 	struct uart_port *port = &device->port;
@@ -151,10 +136,6 @@ static int __init early_serial8250_setup(struct earlycon_device *device,
 		struct uart_port *port = &device->port;
 		unsigned int ier;
 
-		device->baud = probe_baud(&device->port);
-		snprintf(device->options, sizeof(device->options), "%u",
-			 device->baud);
-
 		/* assume the device was initialized, only mask interrupts */
 		ier = serial8250_early_in(port, UART_IER);
 		serial8250_early_out(port, UART_IER, ier & UART_IER_UUE);
Signature · 1 line
2.3.5
#46 lore raw

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

Quoted 75 lines · Peter Hurley

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.

Document the required behavior of the original implementation.

Fixes c7cef0a84912cab3c9df8 ("console: Add extensible console matching")

---

v3: Fixed automatic console to port line settings initialization;
open-coded serial8250_console_setup() so the baud can be probed; added sha reference in commit log

v2: Fixed regression which allowed "console=uart1337,..." to start a
console (but not an earlycon)
+ fixed earlycon= documentation related required behavior fixed by this patch

 Documentation/kernel-parameters.txt  | 18 ++++++++++++++---
 drivers/tty/serial/8250/8250_core.c  | 38 +++++++++++++++++++++++++++++++++---
 drivers/tty/serial/8250/8250_early.c | 19 ------------------
 3 files changed, 50 insertions(+), 25 deletions(-)
Documentation/kernel-parameters.txt +15 -3
index bfcb1a6..1facf0b 100644
@@ -713,10 +713,18 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 
 		uart[8250],io,<addr>[,options]
 		uart[8250],mmio,<addr>[,options]
+		uart[8250],mmio32,<addr>[,options]
+		uart[8250],0x<addr>[,options]
 			Start an early, polled-mode console on the 8250/16550
 			UART at the specified I/O port or MMIO address,
-			switching to the matching ttyS device later.  The
-			options are the same as for ttyS, above.
+			switching to the matching ttyS device later.
+			MMIO inter-register address stride is either 8-bit
+			(mmio) or 32-bit (mmio32).
+			If none of [io|mmio|mmio32], <addr> is assumed to be
+			equivalent to 'mmio'. 'options' are specified in the
+			same format described for ttyS above; if unspecified,
+			the h/w is not re-initialized.
+
 		hvc<n>	Use the hypervisor console device <n>. This is for
 			both Xen and PowerPC hypervisors.
 
@@ -944,11 +952,15 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 		uart[8250],io,<addr>[,options]
 		uart[8250],mmio,<addr>[,options]
 		uart[8250],mmio32,<addr>[,options]
+		uart[8250],0x<addr>[,options]
 			Start an early, polled-mode console on the 8250/16550
 			UART at the specified I/O port or MMIO address.
 			MMIO inter-register address stride is either 8-bit
 			(mmio) or 32-bit (mmio32).
-			The options are the same as for ttyS, above.
+			If none of [io|mmio|mmio32], <addr> is assumed to be
+			equivalent to 'mmio'. 'options' are specified in the
+			same format described for "console=ttyS<n>"; if
+			unspecified, the h/w is not initialized.
 
 		pl011,<addr>
 			Start an early, polled-mode console on a pl011 serial
drivers/tty/serial/8250/8250_core.c +0 -0
index e0fb5f0..f59c7a0 100644

drivers/tty/serial/8250/8250_core.c static int univ8250_console_setup(struct console *co, char *options) · line 3450

Quoted 4 lines
drivers/tty/serial/8250/8250_core.c +1 -0
@@ -3447,6 +3447,22 @@ static int univ8250_console_setup(struct console *co, char *options)
 	return serial8250_console_setup(up, options);
 }
 
+/* FIXME: this is broken on most other 8250 h/w */

What do you mean by "most other"? What hardware does this work for? What is it broken for? What is someone supposed to think/do with this comment?

thanks,

greg k-h

#47 lore raw

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

Quoted 79 lines · Greg Kroah-Hartman
Quoted 78 lines · Peter Hurley

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.

Document the required behavior of the original implementation.

Fixes c7cef0a84912cab3c9df8 ("console: Add extensible console matching")

---

v3: Fixed automatic console to port line settings initialization;
open-coded serial8250_console_setup() so the baud can be probed; added sha reference in commit log

v2: Fixed regression which allowed "console=uart1337,..." to start a
console (but not an earlycon)
+ fixed earlycon= documentation related required behavior fixed by this patch

 Documentation/kernel-parameters.txt  | 18 ++++++++++++++---
 drivers/tty/serial/8250/8250_core.c  | 38 +++++++++++++++++++++++++++++++++---
 drivers/tty/serial/8250/8250_early.c | 19 ------------------
 3 files changed, 50 insertions(+), 25 deletions(-)
Documentation/kernel-parameters.txt +15 -3
index bfcb1a6..1facf0b 100644
@@ -713,10 +713,18 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 
 		uart[8250],io,<addr>[,options]
 		uart[8250],mmio,<addr>[,options]
+		uart[8250],mmio32,<addr>[,options]
+		uart[8250],0x<addr>[,options]
 			Start an early, polled-mode console on the 8250/16550
 			UART at the specified I/O port or MMIO address,
-			switching to the matching ttyS device later.  The
-			options are the same as for ttyS, above.
+			switching to the matching ttyS device later.
+			MMIO inter-register address stride is either 8-bit
+			(mmio) or 32-bit (mmio32).
+			If none of [io|mmio|mmio32], <addr> is assumed to be
+			equivalent to 'mmio'. 'options' are specified in the
+			same format described for ttyS above; if unspecified,
+			the h/w is not re-initialized.
+
 		hvc<n>	Use the hypervisor console device <n>. This is for
 			both Xen and PowerPC hypervisors.
 
@@ -944,11 +952,15 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 		uart[8250],io,<addr>[,options]
 		uart[8250],mmio,<addr>[,options]
 		uart[8250],mmio32,<addr>[,options]
+		uart[8250],0x<addr>[,options]
 			Start an early, polled-mode console on the 8250/16550
 			UART at the specified I/O port or MMIO address.
 			MMIO inter-register address stride is either 8-bit
 			(mmio) or 32-bit (mmio32).
-			The options are the same as for ttyS, above.
+			If none of [io|mmio|mmio32], <addr> is assumed to be
+			equivalent to 'mmio'. 'options' are specified in the
+			same format described for "console=ttyS<n>"; if
+			unspecified, the h/w is not initialized.
 
 		pl011,<addr>
 			Start an early, polled-mode console on a pl011 serial
drivers/tty/serial/8250/8250_core.c +0 -0
index e0fb5f0..f59c7a0 100644
@@ -3447,6 +3447,22 @@ static int univ8250_console_setup(struct console *co, char *options)
 	return serial8250_console_setup(up, options);
 }
 
Quoted 5 lines

drivers/tty/serial/8250/8250_core.c static int univ8250_console_setup(struct console *co, char *options) · line 3450

Quoted 1 line
drivers/tty/serial/8250/8250_core.c +1 -0
+/* FIXME: this is broken on most other 8250 h/w */

What do you mean by "most other"? What hardware does this work for? What is it broken for? What is someone supposed to think/do with this comment?

It's a direct copy of the existing behavior for 8250 earlycon, which is broken for h/w with non-standard divisor registers. That's basically _every_ new design, because that's what vendors need to extend to support modern bitrates.

Affected h/w that I know of includes: 8250_dw, exar xr17v35 cards, omap8250, omap15xx, intel byt, intel mid.

But it was already broken for these and so not a regression.

Regards,
Peter Hurley

#48 lore raw

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

Quoted 91 lines · Peter Hurley
Quoted 79 lines · Greg Kroah-Hartman
Quoted 78 lines · Peter Hurley

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.

Document the required behavior of the original implementation.

Fixes c7cef0a84912cab3c9df8 ("console: Add extensible console matching")

---

v3: Fixed automatic console to port line settings initialization;
open-coded serial8250_console_setup() so the baud can be probed; added sha reference in commit log

v2: Fixed regression which allowed "console=uart1337,..." to start a
console (but not an earlycon)
+ fixed earlycon= documentation related required behavior fixed by this patch

 Documentation/kernel-parameters.txt  | 18 ++++++++++++++---
 drivers/tty/serial/8250/8250_core.c  | 38 +++++++++++++++++++++++++++++++++---
 drivers/tty/serial/8250/8250_early.c | 19 ------------------
 3 files changed, 50 insertions(+), 25 deletions(-)
Documentation/kernel-parameters.txt +15 -3
index bfcb1a6..1facf0b 100644
@@ -713,10 +713,18 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 
 		uart[8250],io,<addr>[,options]
 		uart[8250],mmio,<addr>[,options]
+		uart[8250],mmio32,<addr>[,options]
+		uart[8250],0x<addr>[,options]
 			Start an early, polled-mode console on the 8250/16550
 			UART at the specified I/O port or MMIO address,
-			switching to the matching ttyS device later.  The
-			options are the same as for ttyS, above.
+			switching to the matching ttyS device later.
+			MMIO inter-register address stride is either 8-bit
+			(mmio) or 32-bit (mmio32).
+			If none of [io|mmio|mmio32], <addr> is assumed to be
+			equivalent to 'mmio'. 'options' are specified in the
+			same format described for ttyS above; if unspecified,
+			the h/w is not re-initialized.
+
 		hvc<n>	Use the hypervisor console device <n>. This is for
 			both Xen and PowerPC hypervisors.
 
@@ -944,11 +952,15 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 		uart[8250],io,<addr>[,options]
 		uart[8250],mmio,<addr>[,options]
 		uart[8250],mmio32,<addr>[,options]
+		uart[8250],0x<addr>[,options]
 			Start an early, polled-mode console on the 8250/16550
 			UART at the specified I/O port or MMIO address.
 			MMIO inter-register address stride is either 8-bit
 			(mmio) or 32-bit (mmio32).
-			The options are the same as for ttyS, above.
+			If none of [io|mmio|mmio32], <addr> is assumed to be
+			equivalent to 'mmio'. 'options' are specified in the
+			same format described for "console=ttyS<n>"; if
+			unspecified, the h/w is not initialized.
 
 		pl011,<addr>
 			Start an early, polled-mode console on a pl011 serial
drivers/tty/serial/8250/8250_core.c +0 -0
index e0fb5f0..f59c7a0 100644
@@ -3447,6 +3447,22 @@ static int univ8250_console_setup(struct console *co, char *options)
 	return serial8250_console_setup(up, options);
 }
 
Quoted 5 lines

drivers/tty/serial/8250/8250_core.c static int univ8250_console_setup(struct console *co, char *options) · line 3450

Quoted 1 line
drivers/tty/serial/8250/8250_core.c +1 -0
+/* FIXME: this is broken on most other 8250 h/w */

What do you mean by "most other"? What hardware does this work for? What is it broken for? What is someone supposed to think/do with this comment?

It's a direct copy of the existing behavior for 8250 earlycon, which is broken for h/w with non-standard divisor registers. That's basically _every_ new design, because that's what vendors need to extend to support modern bitrates.

Quoted 4 lines

Affected h/w that I know of includes: 8250_dw, exar xr17v35 cards, omap8250, omap15xx, intel byt, intel mid.

But it was already broken for these and so not a regression.

Sorry, I know the function is a copy, you haven't broken anything that wasn't already broken. I see this comment as a "rant", but we might as well turn that "rant" into something descriptive to let other people know what is really going on here.

Sound reasonable?

thanks,

greg k-h

#49 lore raw

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

Quoted 3 lines · Greg Kroah-Hartman
Quoted 2 lines · Peter Hurley
Quoted 1 line · Greg Kroah-Hartman

On Sat, Apr 04, 2015 at 10:27:30AM -0400, Peter Hurley wrote:

[...]

Quoted 14 lines
Quoted 14 lines
Quoted 5 lines
Quoted 1 line

+/* FIXME: this is broken on most other 8250 h/w */

What do you mean by "most other"? What hardware does this work for? What is it broken for? What is someone supposed to think/do with this comment?

It's a direct copy of the existing behavior for 8250 earlycon, which is broken for h/w with non-standard divisor registers. That's basically _every_ new design, because that's what vendors need to extend to support modern bitrates.

Affected h/w that I know of includes: 8250_dw, exar xr17v35 cards, omap8250, omap15xx, intel byt, intel mid.

Quoted 6 lines
Quoted 1 line

But it was already broken for these and so not a regression.

Sorry, I know the function is a copy, you haven't broken anything that wasn't already broken. I see this comment as a "rant", but we might as well turn that "rant" into something descriptive to let other people know what is really going on here.

It's not intended as rant. My concern is that it appears as "desirable" code because it's new, when that's not my intention.

When others go to implement earlycon-to-console handoff, my hope is that they don't follow this exemplar. Unfortunately, since this is the only driver that implements earlycon-to-console handoff (right now), some might just simply copy the behavior here. My intention is to discourage that.

Quoted 1 line

Sound reasonable?

Ok. How about "most new"?

Regards,
Peter Hurley

#50 lore raw

PATCH v4 1/1 earlycon: 8250: Fix command line regression

In reply to Peter Hurley

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.

Document the required behavior of the original implementation.

Fixes c7cef0a84912cab3c9df8 ("console: Add extensible console matching")

---
v4: Removed FIXME comment

v3: Fixed automatic console to port line settings initialization;
open-coded serial8250_console_setup() so the baud can be probed; added sha reference in commit log

v2: Fixed regression which allowed "console=uart1337,..." to start a
console (but not an earlycon)
+ fixed earlycon= documentation related required behavior fixed by this patch

 Documentation/kernel-parameters.txt  | 18 +++++++++++++++---
 drivers/tty/serial/8250/8250_core.c  | 37 +++++++++++++++++++++++++++++++++---
 drivers/tty/serial/8250/8250_early.c | 19 ------------------
 3 files changed, 49 insertions(+), 25 deletions(-)
Documentation/kernel-parameters.txt +15 -3
index bfcb1a6..1facf0b 100644
@@ -713,10 +713,18 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 
 		uart[8250],io,<addr>[,options]
 		uart[8250],mmio,<addr>[,options]
+		uart[8250],mmio32,<addr>[,options]
+		uart[8250],0x<addr>[,options]
 			Start an early, polled-mode console on the 8250/16550
 			UART at the specified I/O port or MMIO address,
-			switching to the matching ttyS device later.  The
-			options are the same as for ttyS, above.
+			switching to the matching ttyS device later.
+			MMIO inter-register address stride is either 8-bit
+			(mmio) or 32-bit (mmio32).
+			If none of [io|mmio|mmio32], <addr> is assumed to be
+			equivalent to 'mmio'. 'options' are specified in the
+			same format described for ttyS above; if unspecified,
+			the h/w is not re-initialized.
+
 		hvc<n>	Use the hypervisor console device <n>. This is for
 			both Xen and PowerPC hypervisors.
 
@@ -944,11 +952,15 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 		uart[8250],io,<addr>[,options]
 		uart[8250],mmio,<addr>[,options]
 		uart[8250],mmio32,<addr>[,options]
+		uart[8250],0x<addr>[,options]
 			Start an early, polled-mode console on the 8250/16550
 			UART at the specified I/O port or MMIO address.
 			MMIO inter-register address stride is either 8-bit
 			(mmio) or 32-bit (mmio32).
-			The options are the same as for ttyS, above.
+			If none of [io|mmio|mmio32], <addr> is assumed to be
+			equivalent to 'mmio'. 'options' are specified in the
+			same format described for "console=ttyS<n>"; if
+			unspecified, the h/w is not initialized.
 
 		pl011,<addr>
 			Start an early, polled-mode console on a pl011 serial
drivers/tty/serial/8250/8250_core.c +34 -3
index e0fb5f0..456606f 100644
@@ -3447,6 +3447,21 @@ static int univ8250_console_setup(struct console *co, char *options)
 	return serial8250_console_setup(up, 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;
+}
+
 /**
  *	univ8250_console_match - non-standard console matching
  *	@co:	  registering console
@@ -3455,13 +3470,18 @@ static int univ8250_console_setup(struct console *co, char *options)
  *	@options: 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>
- *	    console=uart<>,<addr>,options
+ *	    console=uart[8250],io|mmio|mmio32,<addr>[,<options>]
+ *	    console=uart[8250],0x<addr>[,<options>]
  *	This form is used to register an initial earlycon boot console and
  *	replace it with the serial8250_console at 8250 driver init.
  *
  *	Performs console setup for a match (as required by interface)
  *
+ *	** HACK ALERT **
+ *	If no <options> are specified, then assume the h/w is already setup.
+ *	This was the undocumented behavior of the original implementation so
+ *	it is cast in stone forever.
+ *
  *	Returns 0 if console matches; otherwise non-zero to use default matching
  */
 static int univ8250_console_match(struct console *co, char *name, int idx,
@@ -3475,12 +3495,16 @@ static int univ8250_console_match(struct console *co, char *name, int idx,
 	if (strncmp(name, match, 4) != 0)
 		return -ENODEV;
 
+	if (idx && idx != 8250)
+		return -ENODEV;
+
 	if (uart_parse_earlycon(options, &iotype, &addr, &options))
 		return -ENODEV;
 
 	/* try to match the port specified on the command line */
 	for (i = 0; i < nr_uarts; i++) {
 		struct uart_port *port = &serial8250_ports[i].port;
+		int baud, bits = 8, parity = 'n', flow = 'n';
 
 		if (port->iotype != iotype)
 			continue;
@@ -3490,8 +3514,15 @@ static int univ8250_console_match(struct console *co, char *name, int idx,
 		if (iotype == UPIO_PORT && port->iobase != addr)
 			continue;
 
+		/* link port to console */
 		co->index = i;
-		return univ8250_console_setup(co, options);
+		port->cons = co;
+
+		if (options && *options)
+			uart_parse_options(options, &baud, &parity, &bits, &flow);
+		else
+			baud = probe_baud(port);
+		return uart_set_options(port, port->cons, baud, parity, bits, flow);
 	}
 
 	return -ENODEV;
drivers/tty/serial/8250/8250_early.c +0 -19
index e95ebfe..8e11968 100644
@@ -105,21 +105,6 @@ static void __init early_serial8250_write(struct console *console,
 		serial8250_early_out(port, UART_IER, ier);
 }
 
-static unsigned int __init probe_baud(struct uart_port *port)
-{
-	unsigned char lcr, dll, dlm;
-	unsigned int quot;
-
-	lcr = serial8250_early_in(port, UART_LCR);
-	serial8250_early_out(port, UART_LCR, lcr | UART_LCR_DLAB);
-	dll = serial8250_early_in(port, UART_DLL);
-	dlm = serial8250_early_in(port, UART_DLM);
-	serial8250_early_out(port, UART_LCR, lcr);
-
-	quot = (dlm << 8) | dll;
-	return (port->uartclk / 16) / quot;
-}
-
 static void __init init_port(struct earlycon_device *device)
 {
 	struct uart_port *port = &device->port;
@@ -151,10 +136,6 @@ static int __init early_serial8250_setup(struct earlycon_device *device,
 		struct uart_port *port = &device->port;
 		unsigned int ier;
 
-		device->baud = probe_baud(&device->port);
-		snprintf(device->options, sizeof(device->options), "%u",
-			 device->baud);
-
 		/* assume the device was initialized, only mask interrupts */
 		ier = serial8250_early_in(port, UART_IER);
 		serial8250_early_out(port, UART_IER, ier & UART_IER_UUE);
Signature · 1 line
2.3.5
#51 lore raw

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

Quoted 8 lines · Peter Hurley

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.

Document the required behavior of the original implementation.

Greg,

Please wait for a Tested-by from Yinghai before pushing; I have no platform to test if this fixes his regression.

Regards,
Peter Hurley

#52 lore raw

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

Quoted 8 lines · Peter Hurley
Quoted 7 lines · Peter Hurley

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.

Quoted 6 lines
Quoted 1 line

Document the required behavior of the original implementation.

Greg,

Please wait for a Tested-by from Yinghai before pushing; I have no platform to test if this fixes his regression.

Ok, will do, thanks for redoing this and spinning up a fix so quickly.

greg k-h

#53 lore raw

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

In reply to Peter Hurley

On Sat, Apr 4, 2015 at 10:19 AM, Peter Hurley <[email protected]> wrote:
...

Quoted 10 lines
 Documentation/kernel-parameters.txt  | 18 +++++++++++++++---
 drivers/tty/serial/8250/8250_core.c  | 37 +++++++++++++++++++++++++++++++++---
 drivers/tty/serial/8250/8250_early.c | 19 ------------------
 3 files changed, 49 insertions(+), 25 deletions(-)
Documentation/kernel-parameters.txt +0 -0
index bfcb1a6..1facf0b 100644

Documentation/kernel-parameters.txt bytes respectively. Such letter suffixes can also be entirely omitted. · line 717

Quoted 5 lines
Documentation/kernel-parameters.txt +2 -0
@@ -713,10 +713,18 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 
                uart[8250],io,<addr>[,options]
                uart[8250],mmio,<addr>[,options]
+               uart[8250],mmio32,<addr>[,options]
+               uart[8250],0x<addr>[,options]

put this to other patch please.

Quoted 16 lines
Documentation/kernel-parameters.txt +8 -2
                        Start an early, polled-mode console on the 8250/16550
                        UART at the specified I/O port or MMIO address,
-                       switching to the matching ttyS device later.  The
-                       options are the same as for ttyS, above.
+                       switching to the matching ttyS device later.
+                       MMIO inter-register address stride is either 8-bit
+                       (mmio) or 32-bit (mmio32).
+                       If none of [io|mmio|mmio32], <addr> is assumed to be
+                       equivalent to 'mmio'. 'options' are specified in the
+                       same format described for ttyS above; if unspecified,
+                       the h/w is not re-initialized.
+
                hvc<n>  Use the hypervisor console device <n>. This is for
                        both Xen and PowerPC hypervisors.
 

Documentation/kernel-parameters.txt bytes respectively. Such letter suffixes can also be entirely omitted. · line 955

Quoted 4 lines
Documentation/kernel-parameters.txt +1 -0
@@ -944,11 +952,15 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
                uart[8250],io,<addr>[,options]
                uart[8250],mmio,<addr>[,options]
                uart[8250],mmio32,<addr>[,options]
+               uart[8250],0x<addr>[,options]

and this to another patch please.

Quoted 25 lines
Documentation/kernel-parameters.txt +4 -1
                        Start an early, polled-mode console on the 8250/16550
                        UART at the specified I/O port or MMIO address.
                        MMIO inter-register address stride is either 8-bit
                        (mmio) or 32-bit (mmio32).
-                       The options are the same as for ttyS, above.
+                       If none of [io|mmio|mmio32], <addr> is assumed to be
+                       equivalent to 'mmio'. 'options' are specified in the
+                       same format described for "console=ttyS<n>"; if
+                       unspecified, the h/w is not initialized.
 
                pl011,<addr>
                        Start an early, polled-mode console on a pl011 serial
drivers/tty/serial/8250/8250_core.c +5 -0
index e0fb5f0..456606f 100644
@@ -3447,6 +3447,21 @@ static int univ8250_console_setup(struct console *co, char *options)
        return serial8250_console_setup(up, options);
 }
 
+static unsigned int probe_baud(struct uart_port *port)
+{
+       unsigned char lcr, dll, dlm;
+       unsigned int quot;
+

drivers/tty/serial/8250/8250_core.c static int univ8250_console_setup(struct console *co, char *options) · line 3464

Quoted 10 lines
drivers/tty/serial/8250/8250_core.c +10 -0
+       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;
+}
+

You said some "newer" chips do not support probe baud. why do you move code to core ?

I was thinking some embedded guys could comment out 8280_early.c, now you get extra work for them to comment out code from 8250_core.c.

Quoted 7 lines
drivers/tty/serial/8250/8250_core.c +0 -0
 /**
  *     univ8250_console_match - non-standard console matching
  *     @co:      registering console
@@ -3455,13 +3470,18 @@ static int univ8250_console_setup(struct console *co, char *options)
  *     @options: ptr to option string from console command line
  *
  *     Only attempts to match console command lines of the form:

drivers/tty/serial/8250/8250_core.c static int univ8250_console_setup(struct console *co, char *options) · line 3480

Quoted 10 lines
drivers/tty/serial/8250/8250_core.c +3 -2
- *         console=uart<>,io|mmio|mmio32,<addr>,<options>
- *         console=uart<>,<addr>,options
+ *         console=uart[8250],io|mmio|mmio32,<addr>[,<options>]
+ *         console=uart[8250],0x<addr>[,<options>]
  *     This form is used to register an initial earlycon boot console and
  *     replace it with the serial8250_console at 8250 driver init.
  *
  *     Performs console setup for a match (as required by interface)
  *
+ *     ** HACK ALERT **

That is not HACK original.

but your fix make it to be hack.

Quoted 8 lines
drivers/tty/serial/8250/8250_core.c +4 -0
+ *     If no <options> are specified, then assume the h/w is already setup.
+ *     This was the undocumented behavior of the original implementation so
+ *     it is cast in stone forever.
+ *
  *     Returns 0 if console matches; otherwise non-zero to use default matching
  */
 static int univ8250_console_match(struct console *co, char *name, int idx,

drivers/tty/serial/8250/8250_core.c static int univ8250_console_match(struct console *co, char *name, int idx, · line 3500

Quoted 6 lines
drivers/tty/serial/8250/8250_core.c +3 -0
@@ -3475,12 +3495,16 @@ static int univ8250_console_match(struct console *co, char *name, int idx,
        if (strncmp(name, match, 4) != 0)
                return -ENODEV;
 
+       if (idx && idx != 8250)
+               return -ENODEV;
+

Your fix is getting ugly now.

Quoted 14 lines
drivers/tty/serial/8250/8250_core.c +1 -0
        if (uart_parse_earlycon(options, &iotype, &addr, &options))
                return -ENODEV;
 
        /* try to match the port specified on the command line */
        for (i = 0; i < nr_uarts; i++) {
                struct uart_port *port = &serial8250_ports[i].port;
+               int baud, bits = 8, parity = 'n', flow = 'n';
 
                if (port->iotype != iotype)
                        continue;
@@ -3490,8 +3514,15 @@ static int univ8250_console_match(struct console *co, char *name, int idx,
                if (iotype == UPIO_PORT && port->iobase != addr)
                        continue;
 

drivers/tty/serial/8250/8250_core.c static int univ8250_console_match(struct console *co, char *name, int idx, · line 3525

Quoted 10 lines
drivers/tty/serial/8250/8250_core.c +8 -1
+               /* link port to console */
                co->index = i;
-               return univ8250_console_setup(co, options);
+               port->cons = co;
+
+               if (options && *options)
+                       uart_parse_options(options, &baud, &parity, &bits, &flow);
+               else
+                       baud = probe_baud(port);
+               return uart_set_options(port, port->cons, baud, parity, bits, flow);

what a mess.

Now sure if it is safe to move down probe_baud, when serial port is still used.

Quoted 31 lines
drivers/tty/serial/8250/8250_core.c +0 -0
        }
 
        return -ENODEV;
drivers/tty/serial/8250/8250_early.c +0 -15
index e95ebfe..8e11968 100644
@@ -105,21 +105,6 @@ static void __init early_serial8250_write(struct console *console,
                serial8250_early_out(port, UART_IER, ier);
 }
 
-static unsigned int __init probe_baud(struct uart_port *port)
-{
-       unsigned char lcr, dll, dlm;
-       unsigned int quot;
-
-       lcr = serial8250_early_in(port, UART_LCR);
-       serial8250_early_out(port, UART_LCR, lcr | UART_LCR_DLAB);
-       dll = serial8250_early_in(port, UART_DLL);
-       dlm = serial8250_early_in(port, UART_DLM);
-       serial8250_early_out(port, UART_LCR, lcr);
-
-       quot = (dlm << 8) | dll;
-       return (port->uartclk / 16) / quot;
-}
-
 static void __init init_port(struct earlycon_device *device)
 {
        struct uart_port *port = &device->port;
@@ -151,10 +136,6 @@ static int __init early_serial8250_setup(struct earlycon_device *device,
                struct uart_port *port = &device->port;

drivers/tty/serial/8250/8250_early.c static int __init early_serial8250_setup(struct earlycon_device *device,

Quoted 10 lines
drivers/tty/serial/8250/8250_early.c +0 -5
                unsigned int ier;
 
-               device->baud = probe_baud(&device->port);
-               snprintf(device->options, sizeof(device->options), "%u",
-                        device->baud);
-
                /* assume the device was initialized, only mask interrupts */
                ier = serial8250_early_in(port, UART_IER);
                serial8250_early_out(port, UART_IER, ier & UART_IER_UUE);
--

Greg, Please consider apply my fix as attached, it is much cleaner.

Or just drop commit c7cef0a84912 ("console: Add extensible console matching") from the tty-next now.

Thanks

Yinghai

Subject: [PATCH -v3] 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.

With that we restore the original behavior.

Fixes commit c7cef0a84912 ("console: Add extensible console matching")

---
-v2: simplify serial8250_get_earlycon_options and don't update
console_cmdline.
-v3: add earlycon_match to restore original behavior.
---

---
 drivers/tty/serial/8250/8250_core.c  |    3 +++
 drivers/tty/serial/8250/8250_early.c |    7 +++++++
 drivers/tty/serial/earlycon.c        |   15 +++++++++++++++
 include/linux/serial_core.h          |    2 ++
 4 files changed, 27 insertions(+)
drivers/tty/serial/8250/8250_core.c +3 -0
Index: linux-2.6/drivers/tty/serial/8250/8250_core.c
===================================================================
@@ -3490,6 +3490,9 @@ static int univ8250_console_match(struct
 		if (iotype == UPIO_PORT && port->iobase != addr)
 			continue;
 
+		if (!earlycon_match(port, &options))
+			return -ENODEV;
+
 		co->index = i;
 		return univ8250_console_setup(co, options);
 	}
drivers/tty/serial/8250/8250_early.c +7 -0
Index: linux-2.6/drivers/tty/serial/8250/8250_early.c
===================================================================
@@ -105,6 +105,12 @@ static void __init early_serial8250_writ
 		serial8250_early_out(port, UART_IER, ier);
 }
 
+static int serial8250_earlycon_match(struct earlycon_device *device,
+				     struct uart_port *up)
+{
+	return uart_match_port(up, &device->port);
+}
+
 static unsigned int __init probe_baud(struct uart_port *port)
 {
 	unsigned char lcr, dll, dlm;
@@ -161,6 +167,7 @@ static int __init early_serial8250_setup
 	} else
 		init_port(device);
 
+	device->match = serial8250_earlycon_match;
 	device->con->write = early_serial8250_write;
 	return 0;
 }
drivers/tty/serial/earlycon.c +15 -0
Index: linux-2.6/drivers/tty/serial/earlycon.c
===================================================================
@@ -127,6 +127,21 @@ static int __init register_earlycon(char
 	return 0;
 }
 
+int earlycon_match(struct uart_port *up, char **options_p)
+{
+	struct earlycon_device *device = &early_console_dev;
+
+	if (!device->con || !(device->con->flags & CON_ENABLED))
+		return 0;
+
+	if (device->match && device->match(device, up)) {
+		*options_p = device->options;
+		return 1;
+	}
+
+	return 0;
+}
+
 /**
  *	setup_earlycon - match and register earlycon console
  *	@buf:	earlycon param string
include/linux/serial_core.h +2 -0
Index: linux-2.6/include/linux/serial_core.h
===================================================================
@@ -337,6 +337,7 @@ struct earlycon_device {
 	struct uart_port port;
 	char options[16];		/* e.g., 115200n8 */
 	unsigned int baud;
+	int (*match)(struct earlycon_device *, struct uart_port *);
 };
 
 struct earlycon_id {
@@ -344,6 +345,7 @@ struct earlycon_id {
 	int	(*setup)(struct earlycon_device *, const char *options);
 };
 
+extern int earlycon_match(struct uart_port *up, char **options_p);
 extern int setup_earlycon(char *buf);
 extern int of_setup_earlycon(unsigned long addr,
 			     int (*setup)(struct earlycon_device *, const char *));
#54 lore raw

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

Quoted 73 lines · Yinghai Lu

On Sat, Apr 4, 2015 at 10:19 AM, Peter Hurley <[email protected]> wrote:
...

Quoted 10 lines
 Documentation/kernel-parameters.txt  | 18 +++++++++++++++---
 drivers/tty/serial/8250/8250_core.c  | 37 +++++++++++++++++++++++++++++++++---
 drivers/tty/serial/8250/8250_early.c | 19 ------------------
 3 files changed, 49 insertions(+), 25 deletions(-)
Documentation/kernel-parameters.txt +0 -0
index bfcb1a6..1facf0b 100644

Documentation/kernel-parameters.txt bytes respectively. Such letter suffixes can also be entirely omitted. · line 717

Quoted 5 lines
Documentation/kernel-parameters.txt +2 -0
@@ -713,10 +713,18 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 
                uart[8250],io,<addr>[,options]
                uart[8250],mmio,<addr>[,options]
+               uart[8250],mmio32,<addr>[,options]
+               uart[8250],0x<addr>[,options]

put this to other patch please.

Quoted 16 lines
Documentation/kernel-parameters.txt +8 -2
                        Start an early, polled-mode console on the 8250/16550
                        UART at the specified I/O port or MMIO address,
-                       switching to the matching ttyS device later.  The
-                       options are the same as for ttyS, above.
+                       switching to the matching ttyS device later.
+                       MMIO inter-register address stride is either 8-bit
+                       (mmio) or 32-bit (mmio32).
+                       If none of [io|mmio|mmio32], <addr> is assumed to be
+                       equivalent to 'mmio'. 'options' are specified in the
+                       same format described for ttyS above; if unspecified,
+                       the h/w is not re-initialized.
+
                hvc<n>  Use the hypervisor console device <n>. This is for
                        both Xen and PowerPC hypervisors.
 

Documentation/kernel-parameters.txt bytes respectively. Such letter suffixes can also be entirely omitted. · line 955

Quoted 4 lines
Documentation/kernel-parameters.txt +1 -0
@@ -944,11 +952,15 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
                uart[8250],io,<addr>[,options]
                uart[8250],mmio,<addr>[,options]
                uart[8250],mmio32,<addr>[,options]
+               uart[8250],0x<addr>[,options]

and this to another patch please.

Quoted 30 lines
Documentation/kernel-parameters.txt +4 -1
                        Start an early, polled-mode console on the 8250/16550
                        UART at the specified I/O port or MMIO address.
                        MMIO inter-register address stride is either 8-bit
                        (mmio) or 32-bit (mmio32).
-                       The options are the same as for ttyS, above.
+                       If none of [io|mmio|mmio32], <addr> is assumed to be
+                       equivalent to 'mmio'. 'options' are specified in the
+                       same format described for "console=ttyS<n>"; if
+                       unspecified, the h/w is not initialized.
 
                pl011,<addr>
                        Start an early, polled-mode console on a pl011 serial
drivers/tty/serial/8250/8250_core.c +10 -0
index e0fb5f0..456606f 100644
@@ -3447,6 +3447,21 @@ static int univ8250_console_setup(struct console *co, char *options)
        return serial8250_console_setup(up, 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);
Quoted 8 lines

drivers/tty/serial/8250/8250_core.c static int univ8250_console_setup(struct console *co, char *options) · line 3464

Quoted 5 lines
drivers/tty/serial/8250/8250_core.c +5 -0
+
+       quot = (dlm << 8) | dll;
+       return (port->uartclk / 16) / quot;
+}
+

You said some "newer" chips do not support probe baud. why do you move code to core ?

There's no functional difference, but here it's at least possible to add support for exar, synopsys, ti omap, intel, etc. based on either port type or a function vector initialized by the sub-driver.

Quoted 2 lines

I was thinking some embedded guys could comment out 8280_early.c, now you get extra work for them to comment out code from 8250_core.c.

Huh? That's just ridiculous.

Quoted 33 lines
Quoted 7 lines
drivers/tty/serial/8250/8250_core.c +0 -0
 /**
  *     univ8250_console_match - non-standard console matching
  *     @co:      registering console
@@ -3455,13 +3470,18 @@ static int univ8250_console_setup(struct console *co, char *options)
  *     @options: ptr to option string from console command line
  *
  *     Only attempts to match console command lines of the form:

drivers/tty/serial/8250/8250_core.c static int univ8250_console_setup(struct console *co, char *options) · line 3480

Quoted 10 lines
drivers/tty/serial/8250/8250_core.c +3 -2
- *         console=uart<>,io|mmio|mmio32,<addr>,<options>
- *         console=uart<>,<addr>,options
+ *         console=uart[8250],io|mmio|mmio32,<addr>[,<options>]
+ *         console=uart[8250],0x<addr>[,<options>]
  *     This form is used to register an initial earlycon boot console and
  *     replace it with the serial8250_console at 8250 driver init.
  *
  *     Performs console setup for a match (as required by interface)
  *
+ *     ** HACK ALERT **

That is not HACK original.

but your fix make it to be hack.

Quoted 11 lines
drivers/tty/serial/8250/8250_core.c +4 -0
+ *     If no <options> are specified, then assume the h/w is already setup.
+ *     This was the undocumented behavior of the original implementation so
+ *     it is cast in stone forever.
+ *
  *     Returns 0 if console matches; otherwise non-zero to use default matching
  */
 static int univ8250_console_match(struct console *co, char *name, int idx,
@@ -3475,12 +3495,16 @@ static int univ8250_console_match(struct console *co, char *name, int idx,
        if (strncmp(name, match, 4) != 0)
                return -ENODEV;
 
Quoted 5 lines

drivers/tty/serial/8250/8250_core.c static int univ8250_console_match(struct · line 3495

Quoted 3 lines
drivers/tty/serial/8250/8250_core.c +3 -0
+       if (idx && idx != 8250)
+               return -ENODEV;
+

Your fix is getting ugly now.

This is required anyway. I'm not the one that decided it would be cute to have "uart" and "uart8250" mean the same thing.

Quoted 14 lines
Quoted 14 lines
drivers/tty/serial/8250/8250_core.c +1 -0
        if (uart_parse_earlycon(options, &iotype, &addr, &options))
                return -ENODEV;
 
        /* try to match the port specified on the command line */
        for (i = 0; i < nr_uarts; i++) {
                struct uart_port *port = &serial8250_ports[i].port;
+               int baud, bits = 8, parity = 'n', flow = 'n';
 
                if (port->iotype != iotype)
                        continue;
@@ -3490,8 +3514,15 @@ static int univ8250_console_match(struct console *co, char *name, int idx,
                if (iotype == UPIO_PORT && port->iobase != addr)
                        continue;
 
Quoted 12 lines

drivers/tty/serial/8250/8250_core.c static int univ8250_console_match(struct console *co, char *name, int idx, · line 3525

Quoted 10 lines
drivers/tty/serial/8250/8250_core.c +8 -1
+               /* link port to console */
                co->index = i;
-               return univ8250_console_setup(co, options);
+               port->cons = co;
+
+               if (options && *options)
+                       uart_parse_options(options, &baud, &parity, &bits, &flow);
+               else
+                       baud = probe_baud(port);
+               return uart_set_options(port, port->cons, baud, parity, bits, flow);

what a mess.

This was the mess:

Quoted 129 lines
drivers/tty/serial/8250/8250_core.c +0 -18
 
-static int serial8250_console_early_setup(void)
-{
-	return serial8250_find_port_for_earlycon();
-}
@@ -3347,7 +3392,7 @@ static struct console serial8250_console = {
 	.write		= serial8250_console_write,
 	.device		= uart_console_device,
 	.setup		= serial8250_console_setup,
-	.early_setup	= serial8250_console_early_setup,
 	.flags		= CON_PRINTBUFFER | CON_ANYTIME,
 	.index		= -1,
 	.data		= &serial8250_reg,
@@ -3361,19 +3406,6 @@ static int __init serial8250_console_init(void)
 
-int serial8250_find_port(struct uart_port *p)
-{
-	int line;
-	struct uart_port *port;
-
-	for (line = 0; line < nr_uarts; line++) {
-		port = &serial8250_ports[line].port;
-		if (uart_match_port(p, port))
-			return line;
-	}
-	return -ENODEV;
-}
-
 
drivers/tty/serial/8250/8250_early.c +0 -23
 
-
-int serial8250_find_port_for_earlycon(void)
-{
-	struct earlycon_device *device = early_device;
-	struct uart_port *port = device ? &device->port : NULL;
-	int line;
-	int ret;
-
-	if (!port || (!port->membase && !port->iobase))
-		return -ENODEV;
-
-	line = serial8250_find_port(port);
-	if (line < 0)
-		return -ENODEV;
-
-	ret = update_console_cmdline("uart", 8250,
-			     "ttyS", line, device->options);
-	if (ret < 0)
-		ret = update_console_cmdline("uart", 0,
-				     "ttyS", line, device->options);
-
-	return ret;
-}
include/linux/console.h +0 -1
 
-extern int update_console_cmdline(char *name, int idx, char *name_new, int idx_new, char *options);
include/linux/serial_8250.h +0 -2
 
-extern int serial8250_find_port(struct uart_port *p);
-extern int serial8250_find_port_for_earlycon(void);
kernel/printk/printk.c +0 -21
 
-int update_console_cmdline(char *name, int idx, char *name_new, int idx_new, char *options)
-{
-	struct console_cmdline *c;
-	int i;
-
-	for (i = 0, c = console_cmdline;
-	     i < MAX_CMDLINECONSOLES && c->name[0];
-	     i++, c++)
-		if (strcmp(c->name, name) == 0 && c->index == idx) {
-			strlcpy(c->name, name_new, sizeof(c->name));
-			c->options = options;
-			c->index = idx_new;
-			return i;
-		}
-	/* not found */
-	return -1;
-}
-
@@ -2436,9 +2418,6 @@ void register_console(struct console *newcon)
 
-	if (newcon->early_setup)
-		newcon->early_setup();
-
 
 

Now sure if it is safe to move down probe_baud, when serial port is still used.

Quoted 33 lines
drivers/tty/serial/8250/8250_core.c +0 -0
        }
 
        return -ENODEV;
drivers/tty/serial/8250/8250_early.c +0 -15
index e95ebfe..8e11968 100644
@@ -105,21 +105,6 @@ static void __init early_serial8250_write(struct console *console,
                serial8250_early_out(port, UART_IER, ier);
 }
 
-static unsigned int __init probe_baud(struct uart_port *port)
-{
-       unsigned char lcr, dll, dlm;
-       unsigned int quot;
-
-       lcr = serial8250_early_in(port, UART_LCR);
-       serial8250_early_out(port, UART_LCR, lcr | UART_LCR_DLAB);
-       dll = serial8250_early_in(port, UART_DLL);
-       dlm = serial8250_early_in(port, UART_DLM);
-       serial8250_early_out(port, UART_LCR, lcr);
-
-       quot = (dlm << 8) | dll;
-       return (port->uartclk / 16) / quot;
-}
-
 static void __init init_port(struct earlycon_device *device)
 {
        struct uart_port *port = &device->port;
@@ -151,10 +136,6 @@ static int __init early_serial8250_setup(struct earlycon_device *device,
                struct uart_port *port = &device->port;
                unsigned int ier;
 
Quoted 10 lines

drivers/tty/serial/8250/8250_early.c static int __init early_serial8250_setup(struct earlycon_device *device,

Quoted 8 lines
drivers/tty/serial/8250/8250_early.c +0 -5
-               device->baud = probe_baud(&device->port);
-               snprintf(device->options, sizeof(device->options), "%u",
-                        device->baud);
-
                /* assume the device was initialized, only mask interrupts */
                ier = serial8250_early_in(port, UART_IER);
                serial8250_early_out(port, UART_IER, ier & UART_IER_UUE);
--

Greg, Please consider apply my fix as attached, it is much cleaner.

On what planet is 27 loc across 4 source files cleaner than 6 loc that might be reducible to 2?

#55 lore raw

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

Quoted 4 lines · Peter Hurley

On 04/05/2015 03:09 AM, Yinghai Lu wrote:

On what planet is 27 loc across 4 source files cleaner than 6 loc that might be reducible to 2?

loc is not only thing to decide if it is cleaner.

Let's Greg and Andrew to check which one is clean.

Subject: [PATCH -v3] 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.

With that we restore the original behavior.

Fixes commit c7cef0a84912 ("console: Add extensible console matching")

---
-v2: simplify serial8250_get_earlycon_options and don't update
console_cmdline.
-v3: add earlycon_match to restore original behavior.
---

---
 drivers/tty/serial/8250/8250_core.c  |    3 +++
 drivers/tty/serial/8250/8250_early.c |    7 +++++++
 drivers/tty/serial/earlycon.c        |   15 +++++++++++++++
 include/linux/serial_core.h          |    2 ++
 4 files changed, 27 insertions(+)
drivers/tty/serial/8250/8250_core.c +3 -0
Index: linux-2.6/drivers/tty/serial/8250/8250_core.c
===================================================================
@@ -3490,6 +3490,9 @@ static int univ8250_console_match(struct
 		if (iotype == UPIO_PORT && port->iobase != addr)
 			continue;
 
+		if (!earlycon_match(port, &options))
+			return -ENODEV;
+
 		co->index = i;
 		return univ8250_console_setup(co, options);
 	}
drivers/tty/serial/8250/8250_early.c +7 -0
Index: linux-2.6/drivers/tty/serial/8250/8250_early.c
===================================================================
@@ -105,6 +105,12 @@ static void __init early_serial8250_writ
 		serial8250_early_out(port, UART_IER, ier);
 }
 
+static int serial8250_earlycon_match(struct earlycon_device *device,
+				     struct uart_port *up)
+{
+	return uart_match_port(up, &device->port);
+}
+
 static unsigned int __init probe_baud(struct uart_port *port)
 {
 	unsigned char lcr, dll, dlm;
@@ -161,6 +167,7 @@ static int __init early_serial8250_setup
 	} else
 		init_port(device);
 
+	device->match = serial8250_earlycon_match;
 	device->con->write = early_serial8250_write;
 	return 0;
 }
drivers/tty/serial/earlycon.c +15 -0
Index: linux-2.6/drivers/tty/serial/earlycon.c
===================================================================
@@ -127,6 +127,21 @@ static int __init register_earlycon(char
 	return 0;
 }
 
+int earlycon_match(struct uart_port *up, char **options_p)
+{
+	struct earlycon_device *device = &early_console_dev;
+
+	if (!device->con || !(device->con->flags & CON_ENABLED))
+		return 0;
+
+	if (device->match && device->match(device, up)) {
+		*options_p = device->options;
+		return 1;
+	}
+
+	return 0;
+}
+
 /**
  *	setup_earlycon - match and register earlycon console
  *	@buf:	earlycon param string
include/linux/serial_core.h +2 -0
Index: linux-2.6/include/linux/serial_core.h
===================================================================
@@ -337,6 +337,7 @@ struct earlycon_device {
 	struct uart_port port;
 	char options[16];		/* e.g., 115200n8 */
 	unsigned int baud;
+	int (*match)(struct earlycon_device *, struct uart_port *);
 };
 
 struct earlycon_id {
@@ -344,6 +345,7 @@ struct earlycon_id {
 	int	(*setup)(struct earlycon_device *, const char *options);
 };
 
+extern int earlycon_match(struct uart_port *up, char **options_p);
 extern int setup_earlycon(char *buf);
 extern int of_setup_earlycon(unsigned long addr,
 			     int (*setup)(struct earlycon_device *, const char *));
#56 lore raw

PATCH v5 1/1 earlycon: 8250: Fix command line regression

In reply to Peter Hurley

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.

Document the required behavior of the original implementation.

Fixes c7cef0a84912cab3c9df8 ("console: Add extensible console matching")

---
v5: Refactored serial8250_console_setup() & univ8250_console_setup()
to eliminate open-coding; net +1 LOC (excludes documentation)

v4: Removed FIXME comment

v3: Fixed automatic console to port line settings initialization;
open-coded serial8250_console_setup() so the baud can be probed; added sha reference in commit log

v2: Fixed regression which allowed "console=uart1337,..." to start a
console (but not an earlycon)
+ fixed earlycon= documentation related required behavior fixed by this patch

 Documentation/kernel-parameters.txt  | 18 ++++++++++++---
 drivers/tty/serial/8250/8250_core.c  | 45 ++++++++++++++++++++++++++++--------
 drivers/tty/serial/8250/8250_early.c | 19 ---------------
 3 files changed, 50 insertions(+), 32 deletions(-)
Documentation/kernel-parameters.txt +15 -3
index bfcb1a6..1facf0b 100644
@@ -713,10 +713,18 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 
 		uart[8250],io,<addr>[,options]
 		uart[8250],mmio,<addr>[,options]
+		uart[8250],mmio32,<addr>[,options]
+		uart[8250],0x<addr>[,options]
 			Start an early, polled-mode console on the 8250/16550
 			UART at the specified I/O port or MMIO address,
-			switching to the matching ttyS device later.  The
-			options are the same as for ttyS, above.
+			switching to the matching ttyS device later.
+			MMIO inter-register address stride is either 8-bit
+			(mmio) or 32-bit (mmio32).
+			If none of [io|mmio|mmio32], <addr> is assumed to be
+			equivalent to 'mmio'. 'options' are specified in the
+			same format described for ttyS above; if unspecified,
+			the h/w is not re-initialized.
+
 		hvc<n>	Use the hypervisor console device <n>. This is for
 			both Xen and PowerPC hypervisors.
 
@@ -944,11 +952,15 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 		uart[8250],io,<addr>[,options]
 		uart[8250],mmio,<addr>[,options]
 		uart[8250],mmio32,<addr>[,options]
+		uart[8250],0x<addr>[,options]
 			Start an early, polled-mode console on the 8250/16550
 			UART at the specified I/O port or MMIO address.
 			MMIO inter-register address stride is either 8-bit
 			(mmio) or 32-bit (mmio32).
-			The options are the same as for ttyS, above.
+			If none of [io|mmio|mmio32], <addr> is assumed to be
+			equivalent to 'mmio'. 'options' are specified in the
+			same format described for "console=ttyS<n>"; if
+			unspecified, the h/w is not initialized.
 
 		pl011,<addr>
 			Start an early, polled-mode console on a pl011 serial
drivers/tty/serial/8250/8250_core.c +35 -10

96 lines not on this page · raw message

drivers/tty/serial/8250/8250_early.c +0 -19
index e95ebfe..8e11968 100644
@@ -105,21 +105,6 @@ static void __init early_serial8250_write(struct console *console,
 		serial8250_early_out(port, UART_IER, ier);
 }
 
-static unsigned int __init probe_baud(struct uart_port *port)
-{
-	unsigned char lcr, dll, dlm;
-	unsigned int quot;
-
-	lcr = serial8250_early_in(port, UART_LCR);
-	serial8250_early_out(port, UART_LCR, lcr | UART_LCR_DLAB);
-	dll = serial8250_early_in(port, UART_DLL);
-	dlm = serial8250_early_in(port, UART_DLM);
-	serial8250_early_out(port, UART_LCR, lcr);
-
-	quot = (dlm << 8) | dll;
-	return (port->uartclk / 16) / quot;
-}
-
 static void __init init_port(struct earlycon_device *device)
 {
 	struct uart_port *port = &device->port;
@@ -151,10 +136,6 @@ static int __init early_serial8250_setup(struct earlycon_device *device,
 		struct uart_port *port = &device->port;
 		unsigned int ier;
 
-		device->baud = probe_baud(&device->port);
-		snprintf(device->options, sizeof(device->options), "%u",
-			 device->baud);
-
 		/* assume the device was initialized, only mask interrupts */
 		ier = serial8250_early_in(port, UART_IER);
 		serial8250_early_out(port, UART_IER, ier & UART_IER_UUE);
Signature · 1 line
2.3.5
#57 lore raw

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

Quoted 37 lines · Peter Hurley

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.

Document the required behavior of the original implementation.

Fixes c7cef0a84912cab3c9df8 ("console: Add extensible console matching")

---
v5: Refactored serial8250_console_setup() & univ8250_console_setup()
to eliminate open-coding; net +1 LOC (excludes documentation)

v4: Removed FIXME comment

v3: Fixed automatic console to port line settings initialization;
open-coded serial8250_console_setup() so the baud can be probed; added sha reference in commit log

v2: Fixed regression which allowed "console=uart1337,..." to start a
console (but not an earlycon)
+ fixed earlycon= documentation related required behavior fixed by this patch

 Documentation/kernel-parameters.txt  | 18 ++++++++++++---
 drivers/tty/serial/8250/8250_core.c  | 45 ++++++++++++++++++++++++++++--------
 drivers/tty/serial/8250/8250_early.c | 19 ---------------
 3 files changed, 50 insertions(+), 32 deletions(-)
Documentation/kernel-parameters.txt +0 -0
index bfcb1a6..1facf0b 100644

Documentation/kernel-parameters.txt bytes respectively. Such letter suffixes can also be entirely omitted. · line 717

Quoted 5 lines
Documentation/kernel-parameters.txt +2 -0
@@ -713,10 +713,18 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 
                uart[8250],io,<addr>[,options]
                uart[8250],mmio,<addr>[,options]
+               uart[8250],mmio32,<addr>[,options]
+               uart[8250],0x<addr>[,options]

You just don't listen.

I wasted too much time on this.

Greg,

Please just drop c7cef0a84912cab3c9df8 ("console: Add extensible console matching").

Thanks

Yinghai

#58 lore raw

PATCH v6 1/1 earlycon: 8250: Fix command line regression

In reply to Peter Hurley

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")

---
v6: Removed documentation
+ removed unnecessary checks; this fix does not attempt to replicate the _exact_ original behavior, but only the reported breakage.

v5: Refactored serial8250_console_setup() & univ8250_console_setup()
to eliminate open-coding; net +1 LOC (excludes documentation)

v4: Removed FIXME comment

v3: Fixed automatic console to port line settings initialization;
open-coded serial8250_console_setup() so the baud can be probed; added sha reference in commit log

v2: Fixed regression which allowed "console=uart1337,..." to start a
console (but not an earlycon)
+ fixed earlycon= documentation related required behavior fixed by this patch

 drivers/tty/serial/8250/8250_core.c  | 31 ++++++++++++++++++++++++-------
 drivers/tty/serial/8250/8250_early.c | 19 -------------------
 2 files changed, 24 insertions(+), 26 deletions(-)
drivers/tty/serial/8250/8250_core.c +24 -7
index e0fb5f0..18142ee 100644
@@ -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;
drivers/tty/serial/8250/8250_early.c +0 -19
index e95ebfe..8e11968 100644
@@ -105,21 +105,6 @@ static void __init early_serial8250_write(struct console *console,
 		serial8250_early_out(port, UART_IER, ier);
 }
 
-static unsigned int __init probe_baud(struct uart_port *port)
-{
-	unsigned char lcr, dll, dlm;
-	unsigned int quot;
-
-	lcr = serial8250_early_in(port, UART_LCR);
-	serial8250_early_out(port, UART_LCR, lcr | UART_LCR_DLAB);
-	dll = serial8250_early_in(port, UART_DLL);
-	dlm = serial8250_early_in(port, UART_DLM);
-	serial8250_early_out(port, UART_LCR, lcr);
-
-	quot = (dlm << 8) | dll;
-	return (port->uartclk / 16) / quot;
-}
-
 static void __init init_port(struct earlycon_device *device)
 {
 	struct uart_port *port = &device->port;
@@ -151,10 +136,6 @@ static int __init early_serial8250_setup(struct earlycon_device *device,
 		struct uart_port *port = &device->port;
 		unsigned int ier;
 
-		device->baud = probe_baud(&device->port);
-		snprintf(device->options, sizeof(device->options), "%u",
-			 device->baud);
-
 		/* assume the device was initialized, only mask interrupts */
 		ier = serial8250_early_in(port, UART_IER);
 		serial8250_early_out(port, UART_IER, ier & UART_IER_UUE);
Signature · 1 line
2.3.5
#59 lore raw

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

In reply to Peter Hurley
Quoted 8 lines · Peter Hurley
Quoted 6 lines · Yinghai Lu
Quoted 3 lines · Peter Hurley

On 04/03/2015 12:57 PM, Yinghai Lu wrote:

Wait -- you have earlycon in a product??

What do you mean?

Quoted 7 lines

I mean, what will happen if I put in a big debug banner like Steven did for ftrace?

Kernel developers need earlycon for debugging arch code; often the earlycon is just hacked together especially when it requires fixmap support.

Putting it in a product and _relying on undocumented behavior_ is a bad idea.

let me repeat again:
when you have "console=uart8250,io,0x3f8", you will have earlycon and then console.

That is just for kernel developer for debugging.

When you have x86 with bunch of dimms and cpus, user will have to wait couple of minutes to output from console=ttyS0....and if it hang early, no one would know what happen.

Also it is only boot time only....

#60 lore raw

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

Quoted 21 lines · Yinghai Lu
Quoted 8 lines · Peter Hurley
Quoted 6 lines · Yinghai Lu
Quoted 3 lines · Peter Hurley

On 04/03/2015 12:57 PM, Yinghai Lu wrote:

Wait -- you have earlycon in a product??

What do you mean?

Quoted 7 lines

I mean, what will happen if I put in a big debug banner like Steven did for ftrace?

Kernel developers need earlycon for debugging arch code; often the earlycon is just hacked together especially when it requires fixmap support.

Putting it in a product and _relying on undocumented behavior_ is a bad idea.

let me repeat again:
when you have "console=uart8250,io,0x3f8", you will have earlycon and then console.

Quoted 7 lines

That is just for kernel developer for debugging.

When you have x86 with bunch of dimms and cpus, user will have to wait couple of minutes to output from console=ttyS0....and if it hang early, no one would know what happen.

Also it is only boot time only....

The fix is sitting in your inbox. Pointless to discuss it now.

#61 lore raw

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

In reply to Peter Hurley
Quoted 4 lines · Peter Hurley

On 04/03/2015 01:44 PM, Yinghai Lu wrote:

which means you have to have CONFIG_SERIAL_EARLYCON to get a serial console at all.

what do you mean? Now in drivers/tty/serial/8250/Kconfig we have

config SERIAL_8250_CONSOLE
bool "Console on 8250/16550 and compatible serial port" depends on SERIAL_8250=y
select SERIAL_CORE_CONSOLE
select SERIAL_EARLYCON

do you mean, we should not have that "select SERIAL_EARLYCON" ?

#62 lore raw
In reply to Peter Hurley
Quoted 57 lines · Peter Hurley

Changes from v2:
* remainder of unapplied series
* Changed the title and commit log for
"serial: earlycon: Allow earlycon params with name only" to "serial: earlycon: Skip parse_options() for empty string" per Rob's comment.

Changes from v1:
* rebased on and requires "console: Fix console name size mismatch"

Hi Greg & Andrew,

This patch series implements:
1. console-definable (aka extensible) matching
2. generic earlycon-to-console handoff via extensible matching
3. arch/prom support for direct earlycon

Extensible console matching

Extensible console matching enables the console itself to define the conditions for a "command line" match. This mimics the design of device matching in the driver model. Two important use-cases which this feature enables are generic earlycon-to-console handoff and support for driver migration.

Earlycon-to-console handoff was implemented in 2007. Console command lines of the form:

   console=uart,io,0x3f8,115200n8

start an earlycon and later allow the 8250 driver console to takeover. Unfortunately this implementation requires direct coupling between the earlycon and the console and is facilitated by ugly hacks like editing the console command line in-place.

Extensible console matching allows the 8250 driver to directly match that console command line instead, and enables other serial drivers to trivially support console handoff themselves.

In addition, extensible console matching allows a new driver to provide support for a different driver's console. This requirement stems from needing to minimize breakage when migrating serial drivers. Since many devices are based on the original 8250/16550 designs but sometimes have features incompatible with the existing 8250 driver support, the initial driver is often standalone. When/if the standalone driver is migrated to the 8250 driver, the problem of console names in the command line remains. Extensible console matching enables a simple migration path.

Direct earlycon

This feature enables arches and proms to start an earlycon directly, rather than requiring an "earlycon=" command line parameter. Devicetree can already do this via the 'linux,stdout-path' property, but arch and prom code requires direct coupling to the serial driver.

Quoted 8 lines

This support is implemented by judicious refactoring and the same construct that devicetree and early_param use: a link table containing the necessary information (name and setup() function) to find and bind the appropriate earlycon "driver".

NB: I combined these two features in this series because their implementations heavily overlap in the same source files.

All now queued up, thanks.

greg k-h