linux-serial.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v5 1/2] serial_core: add pci uart early console support
@ 2015-05-29 18:38 Bin Gao
  2015-06-08 18:17 ` [PATCH v6 " Bin Gao
  0 siblings, 1 reply; 5+ messages in thread
From: Bin Gao @ 2015-05-29 18:38 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: One Thousand Gnomes, Peter Hurley, Jiri Slaby, Paul Bolle,
	bin.gao, linux-serial, linux-kernel

On some Intel Atom SoCs, the legacy IO port UART(0x3F8) is not available.
Instead, a 8250 compatible PCI uart can be used as early console.
This patch adds pci support to the 8250 early console driver uart8250.
For example, to enable pci uart(00:21.3) as early console on these
platforms, append the following line to the kernel command line
(assume baud rate is 115200):
earlyprintk=uart8250,pci32,0:24.2,115200n8

Signed-off-by: Bin Gao <bin.gao@intel.com>
---
Changes in v5:
 - updated Documentation/kernel-parameters.txt.
 - moved earlyprintk= to patch 2/2 (requires x86 people's review).
 - rolled back to simple_strto* APIs.
 - seperate pci/pci32 format description.
 - minor error and debug message changes.
 - if/else statements in uart_parse_earlycon() were refactored to avoid
   logic steering locals.
Changes in v4:
 - moved PCI_EARLY definition from arch/x86/Kconfig to drivers/pci/Kconfig
 - made earlycon= for all archs but earlyprintk= only for x86 by changing
   "#ifdef #else #endif" to "#if #endif".
Changes in v3:
 - introduced CONFIG_EARLY_PCI to protect pci codes in serial_core.c.
 - added earlyprintk= as alia to earlycon= to keep x86 compatibility.
changes in v2:
 - added the second patch (2/2) to remove existed pci early console support
   from arch/x86/kernel/early_printk.c.
 Documentation/kernel-parameters.txt |  15 +++++
 arch/x86/Kconfig                    |   1 +
 drivers/pci/Kconfig                 |  11 ++++
 drivers/tty/serial/serial_core.c    | 106 +++++++++++++++++++++++++++++++++++-
 4 files changed, 132 insertions(+), 1 deletion(-)

diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 61ab162..598606e 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -969,6 +969,16 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 			same format described for "console=ttyS<n>"; if
 			unspecified, the h/w is not initialized.
 
+		uart8250,pci,<bus:dev.func>[,options]
+		uart8250,pci32,<bus:dev.func>[,options]
+			Start an early, polled-mode console on the 8250/16550
+			UART at the specified PCI device (bus:dev.func).
+			The io or memory mmaped register width is either 8-bit
+			(pci) or 32-bit (pci32).
+			'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
 			port at the specified address. The pl011 serial port
@@ -1009,6 +1019,8 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 			earlyprintk=serial[,0x...[,baudrate]]
 			earlyprintk=ttySn[,baudrate]
 			earlyprintk=dbgp[debugController#]
+			earlyprintk=uart8250,pci,<bus:dev.fun>[,options]
+			earlyprintk=uart8250,pci32,<bus:dev.func>[,options]
 
 			earlyprintk is useful when the kernel crashes before
 			the normal console is initialized. It is not enabled by
@@ -1037,6 +1049,9 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 
 			The xen output can only be used by Xen PV guests.
 
+			The uart8250,pci and uart8250,pci32 output share the
+			same definition that is in earlycon= section.
+
 	edac_report=	[HW,EDAC] Control how to report EDAC event
 			Format: {"on" | "off" | "force"}
 			on: enable EDAC to report H/W event. May be overridden
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 226d569..bdedd61 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -143,6 +143,7 @@ config X86
 	select ACPI_LEGACY_TABLES_LOOKUP if ACPI
 	select X86_FEATURE_NAMES if PROC_FS
 	select SRCU
+	select PCI_EARLY if PCI
 
 config INSTRUCTION_DECODER
 	def_bool y
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
index 7a8f1c5..4f0f055 100644
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -114,4 +114,15 @@ config PCI_LABEL
 	def_bool y if (DMI || ACPI)
 	select NLS
 
+config PCI_EARLY
+	bool "Early PCI access"
+	depends on PCI
+	default n
+	help
+	  This option indicates that a group of APIs are available (in
+	  asm/pci-direct.h) so the kernel can access pci config registers
+	  before the PCI subsystem is initialized. Any arch that supports
+	  early pci APIs should enable this option which is required  by
+	  arch independent codes, e.g. uart8250 pci early console driver.
+
 source "drivers/pci/host/Kconfig"
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
index 0b7bb12..5b21999 100644
--- a/drivers/tty/serial/serial_core.c
+++ b/drivers/tty/serial/serial_core.c
@@ -34,10 +34,15 @@
 #include <linux/serial_core.h>
 #include <linux/delay.h>
 #include <linux/mutex.h>
+#include <linux/pci_regs.h>
 
 #include <asm/irq.h>
 #include <asm/uaccess.h>
 
+#ifdef CONFIG_PCI_EARLY
+#include <asm/pci-direct.h>
+#endif
+
 /*
  * This is used to lock changes in serial line configuration.
  */
@@ -1808,6 +1813,85 @@ uart_get_console(struct uart_port *ports, int nr, struct console *co)
 	return ports + idx;
 }
 
+#ifdef CONFIG_PCI_EARLY
+/*
+ * The whole pci option from the command line is: pci[32],B:D.F[,options]
+ * Examples:
+ *     pci,0:21.3,115200n8
+ *     pci32,0:21.3
+ * Here pci32 means 8250 UART registers are 32-bit width(regshift = 2).
+ * pci means 8250 UART registers are 8-bit width(regshift = 0).
+ * B,D and F are bus, device and function, in decimal(not hex).
+ * The additional options(115200n8) would be parsed by the earlycon framework.
+ *
+ * @options: the pci options
+ * @phys: the pointer to return pci mem or io address
+ * return: <0: error
+ *          0: pci mem
+ *          1: pci io
+ */
+static int parse_pci_options(char *options, unsigned long *phys)
+{
+	u8 bus, dev, func;
+	u64 bar0;
+	u16 cmd;
+	int pci_io = 0;
+
+	if (!early_pci_allowed()) {
+		pr_err("earlycon: early pci not allowed.\n");
+		return -EINVAL;
+	}
+
+	/* We come here with options=B:D.F[,options] */
+	if (*options == 0)
+		goto failed;
+
+	bus = (u8)simple_strtoul(options, &options, 10);
+	if (*options != ':')
+		goto failed;
+
+	dev = (u8)simple_strtoul(options + 1, &options, 10);
+	if (*options != '.')
+		goto failed;
+
+	func = (u8)simple_strtoul(options + 1, NULL, 10);
+
+	bar0 = read_pci_config(bus, dev, func, PCI_BASE_ADDRESS_0);
+
+	/* The BAR is IO or Memory? */
+	if ((bar0 & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO)
+		pci_io = 1;
+
+	if ((bar0 & PCI_BASE_ADDRESS_MEM_TYPE_MASK) ==
+			PCI_BASE_ADDRESS_MEM_TYPE_64)
+		bar0 |= (u64)read_pci_config(bus, dev, func,
+				PCI_BASE_ADDRESS_0 + 4) << 32;
+
+	*phys = bar0 & (pci_io ? PCI_BASE_ADDRESS_IO_MASK :
+				 PCI_BASE_ADDRESS_MEM_MASK);
+
+	/* Enable address decoding */
+	cmd = read_pci_config_16(bus, dev, func, PCI_COMMAND);
+	write_pci_config_16(bus, dev, func, PCI_COMMAND,
+		cmd | (pci_io ? PCI_COMMAND_IO : PCI_COMMAND_MEMORY));
+
+	pr_debug("Use 8250 uart at PCI 0000:%02u:%02u.%01u as early console\n",
+							bus, dev, func);
+	return pci_io;
+
+failed:
+	pr_err("Invalid earlycon pci parameters\n");
+	return -EINVAL;
+}
+
+#else
+static int parse_pci_options(char *options, unsigned long *phys)
+{
+	pr_err("earlycon: pci not supported (requires CONFIG_PCI_EARLY=y)\n");
+	return -EINVAL;
+}
+#endif
+
 /**
  *	uart_parse_earlycon - Parse earlycon options
  *	@p:	  ptr to 2nd field (ie., just beyond '<name>,')
@@ -1817,7 +1901,9 @@ uart_get_console(struct uart_port *ports, int nr, struct console *co)
  *
  *	Decodes earlycon kernel command line parameters of the form
  *	   earlycon=<name>,io|mmio|mmio32,<addr>,<options>
+ *	   earlycon=<name>,pci|pci32,<bus:dev.func>,<options>
  *	   console=<name>,io|mmio|mmio32,<addr>,<options>
+ *	For pci|pci32, bus, dev and func are in decimal.
  *
  *	The optional form
  *	   earlycon=<name>,0x<addr>,<options>
@@ -1829,22 +1915,40 @@ uart_get_console(struct uart_port *ports, int nr, struct console *co)
 int uart_parse_earlycon(char *p, unsigned char *iotype, unsigned long *addr,
 			char **options)
 {
+	int ret;
+	unsigned long phys;
+
 	if (strncmp(p, "mmio,", 5) == 0) {
 		*iotype = UPIO_MEM;
 		p += 5;
+		*addr = simple_strtoul(p, NULL, 0);
 	} else if (strncmp(p, "mmio32,", 7) == 0) {
 		*iotype = UPIO_MEM32;
 		p += 7;
+		*addr = simple_strtoul(p, NULL, 0);
+	} else if (strncmp(p, "pci,", 4) == 0) {
+		p += 4;
+		ret = parse_pci_options(p, &phys);
+		if (ret < 0)
+			return ret;
+		*iotype = (ret > 0) ? UPIO_PORT : UPIO_MEM;
+	} else if (strncmp(p, "pci32,", 6) == 0) {
+		p += 6;
+		ret = parse_pci_options(p, &phys);
+		if (ret < 0)
+			return ret;
+		*iotype = (ret > 0) ? UPIO_PORT : UPIO_MEM32;
 	} else if (strncmp(p, "io,", 3) == 0) {
 		*iotype = UPIO_PORT;
 		p += 3;
+		*addr = simple_strtoul(p, NULL, 0);
 	} else if (strncmp(p, "0x", 2) == 0) {
 		*iotype = UPIO_MEM;
+		*addr = simple_strtoul(p, NULL, 0);
 	} else {
 		return -EINVAL;
 	}
 
-	*addr = simple_strtoul(p, NULL, 0);
 	p = strchr(p, ',');
 	if (p)
 		p++;
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v6 1/2] serial_core: add pci uart early console support
  2015-05-29 18:38 [PATCH v5 1/2] serial_core: add pci uart early console support Bin Gao
@ 2015-06-08 18:17 ` Bin Gao
  2015-06-28 20:44   ` Peter Hurley
  2015-07-23 22:21   ` Greg Kroah-Hartman
  0 siblings, 2 replies; 5+ messages in thread
From: Bin Gao @ 2015-06-08 18:17 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: One Thousand Gnomes, Peter Hurley, Jiri Slaby, Paul Bolle,
	linux-serial, linux-kernel, bin.gao

On some Intel Atom SoCs, the legacy IO port UART(0x3F8) is not available.
Instead, a 8250 compatible PCI uart can be used as early console.
This patch adds pci support to the 8250 early console driver uart8250.
For example, to enable pci uart(00:21.3) as early console on these
platforms, append the following line to the kernel command line
(assume baud rate is 115200):
earlyprintk=uart8250,pci32,0:24.2,115200n8

Signed-off-by: Bin Gao <bin.gao@intel.com>
---
Changes in v6: None
Changes in v5:
 - updated Documentation/kernel-parameters.txt.
 - moved earlyprintk= to patch 2/2 (requires x86 people's review).
 - rolled back to simple_strto* APIs.
 - seperate pci/pci32 format description.
 - minor error and debug message changes.
 - if/else statements in uart_parse_earlycon() were refactored to avoid
   logic steering locals.
Changes in v4:
 - moved PCI_EARLY definition from arch/x86/Kconfig to drivers/pci/Kconfig
 - made earlycon= for all archs but earlyprintk= only for x86 by changing
   "#ifdef #else #endif" to "#if #endif".
Changes in v3:
 - introduced CONFIG_EARLY_PCI to protect pci codes in serial_core.c.
 - added earlyprintk= as alia to earlycon= to keep x86 compatibility.
changes in v2:
 - added the second patch (2/2) to remove existed pci early console support
   from arch/x86/kernel/early_printk.c.
 Documentation/kernel-parameters.txt |  15 +++++
 arch/x86/Kconfig                    |   1 +
 drivers/pci/Kconfig                 |  11 ++++
 drivers/tty/serial/serial_core.c    | 106 +++++++++++++++++++++++++++++++++++-
 4 files changed, 132 insertions(+), 1 deletion(-)

diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 61ab162..598606e 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -969,6 +969,16 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 			same format described for "console=ttyS<n>"; if
 			unspecified, the h/w is not initialized.
 
+		uart8250,pci,<bus:dev.func>[,options]
+		uart8250,pci32,<bus:dev.func>[,options]
+			Start an early, polled-mode console on the 8250/16550
+			UART at the specified PCI device (bus:dev.func).
+			The io or memory mmaped register width is either 8-bit
+			(pci) or 32-bit (pci32).
+			'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
 			port at the specified address. The pl011 serial port
@@ -1009,6 +1019,8 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 			earlyprintk=serial[,0x...[,baudrate]]
 			earlyprintk=ttySn[,baudrate]
 			earlyprintk=dbgp[debugController#]
+			earlyprintk=uart8250,pci,<bus:dev.fun>[,options]
+			earlyprintk=uart8250,pci32,<bus:dev.func>[,options]
 
 			earlyprintk is useful when the kernel crashes before
 			the normal console is initialized. It is not enabled by
@@ -1037,6 +1049,9 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 
 			The xen output can only be used by Xen PV guests.
 
+			The uart8250,pci and uart8250,pci32 output share the
+			same definition that is in earlycon= section.
+
 	edac_report=	[HW,EDAC] Control how to report EDAC event
 			Format: {"on" | "off" | "force"}
 			on: enable EDAC to report H/W event. May be overridden
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 226d569..bdedd61 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -143,6 +143,7 @@ config X86
 	select ACPI_LEGACY_TABLES_LOOKUP if ACPI
 	select X86_FEATURE_NAMES if PROC_FS
 	select SRCU
+	select PCI_EARLY if PCI
 
 config INSTRUCTION_DECODER
 	def_bool y
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
index 7a8f1c5..4f0f055 100644
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -114,4 +114,15 @@ config PCI_LABEL
 	def_bool y if (DMI || ACPI)
 	select NLS
 
+config PCI_EARLY
+	bool "Early PCI access"
+	depends on PCI
+	default n
+	help
+	  This option indicates that a group of APIs are available (in
+	  asm/pci-direct.h) so the kernel can access pci config registers
+	  before the PCI subsystem is initialized. Any arch that supports
+	  early pci APIs should enable this option which is required  by
+	  arch independent codes, e.g. uart8250 pci early console driver.
+
 source "drivers/pci/host/Kconfig"
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
index 0b7bb12..5b21999 100644
--- a/drivers/tty/serial/serial_core.c
+++ b/drivers/tty/serial/serial_core.c
@@ -34,10 +34,15 @@
 #include <linux/serial_core.h>
 #include <linux/delay.h>
 #include <linux/mutex.h>
+#include <linux/pci_regs.h>
 
 #include <asm/irq.h>
 #include <asm/uaccess.h>
 
+#ifdef CONFIG_PCI_EARLY
+#include <asm/pci-direct.h>
+#endif
+
 /*
  * This is used to lock changes in serial line configuration.
  */
@@ -1808,6 +1813,85 @@ uart_get_console(struct uart_port *ports, int nr, struct console *co)
 	return ports + idx;
 }
 
+#ifdef CONFIG_PCI_EARLY
+/*
+ * The whole pci option from the command line is: pci[32],B:D.F[,options]
+ * Examples:
+ *     pci,0:21.3,115200n8
+ *     pci32,0:21.3
+ * Here pci32 means 8250 UART registers are 32-bit width(regshift = 2).
+ * pci means 8250 UART registers are 8-bit width(regshift = 0).
+ * B,D and F are bus, device and function, in decimal(not hex).
+ * The additional options(115200n8) would be parsed by the earlycon framework.
+ *
+ * @options: the pci options
+ * @phys: the pointer to return pci mem or io address
+ * return: <0: error
+ *          0: pci mem
+ *          1: pci io
+ */
+static int parse_pci_options(char *options, unsigned long *phys)
+{
+	u8 bus, dev, func;
+	u64 bar0;
+	u16 cmd;
+	int pci_io = 0;
+
+	if (!early_pci_allowed()) {
+		pr_err("earlycon: early pci not allowed.\n");
+		return -EINVAL;
+	}
+
+	/* We come here with options=B:D.F[,options] */
+	if (*options == 0)
+		goto failed;
+
+	bus = (u8)simple_strtoul(options, &options, 10);
+	if (*options != ':')
+		goto failed;
+
+	dev = (u8)simple_strtoul(options + 1, &options, 10);
+	if (*options != '.')
+		goto failed;
+
+	func = (u8)simple_strtoul(options + 1, NULL, 10);
+
+	bar0 = read_pci_config(bus, dev, func, PCI_BASE_ADDRESS_0);
+
+	/* The BAR is IO or Memory? */
+	if ((bar0 & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO)
+		pci_io = 1;
+
+	if ((bar0 & PCI_BASE_ADDRESS_MEM_TYPE_MASK) ==
+			PCI_BASE_ADDRESS_MEM_TYPE_64)
+		bar0 |= (u64)read_pci_config(bus, dev, func,
+				PCI_BASE_ADDRESS_0 + 4) << 32;
+
+	*phys = bar0 & (pci_io ? PCI_BASE_ADDRESS_IO_MASK :
+				 PCI_BASE_ADDRESS_MEM_MASK);
+
+	/* Enable address decoding */
+	cmd = read_pci_config_16(bus, dev, func, PCI_COMMAND);
+	write_pci_config_16(bus, dev, func, PCI_COMMAND,
+		cmd | (pci_io ? PCI_COMMAND_IO : PCI_COMMAND_MEMORY));
+
+	pr_debug("Use 8250 uart at PCI 0000:%02u:%02u.%01u as early console\n",
+							bus, dev, func);
+	return pci_io;
+
+failed:
+	pr_err("Invalid earlycon pci parameters\n");
+	return -EINVAL;
+}
+
+#else
+static int parse_pci_options(char *options, unsigned long *phys)
+{
+	pr_err("earlycon: pci not supported (requires CONFIG_PCI_EARLY=y)\n");
+	return -EINVAL;
+}
+#endif
+
 /**
  *	uart_parse_earlycon - Parse earlycon options
  *	@p:	  ptr to 2nd field (ie., just beyond '<name>,')
@@ -1817,7 +1901,9 @@ uart_get_console(struct uart_port *ports, int nr, struct console *co)
  *
  *	Decodes earlycon kernel command line parameters of the form
  *	   earlycon=<name>,io|mmio|mmio32,<addr>,<options>
+ *	   earlycon=<name>,pci|pci32,<bus:dev.func>,<options>
  *	   console=<name>,io|mmio|mmio32,<addr>,<options>
+ *	For pci|pci32, bus, dev and func are in decimal.
  *
  *	The optional form
  *	   earlycon=<name>,0x<addr>,<options>
@@ -1829,22 +1915,40 @@ uart_get_console(struct uart_port *ports, int nr, struct console *co)
 int uart_parse_earlycon(char *p, unsigned char *iotype, unsigned long *addr,
 			char **options)
 {
+	int ret;
+	unsigned long phys;
+
 	if (strncmp(p, "mmio,", 5) == 0) {
 		*iotype = UPIO_MEM;
 		p += 5;
+		*addr = simple_strtoul(p, NULL, 0);
 	} else if (strncmp(p, "mmio32,", 7) == 0) {
 		*iotype = UPIO_MEM32;
 		p += 7;
+		*addr = simple_strtoul(p, NULL, 0);
+	} else if (strncmp(p, "pci,", 4) == 0) {
+		p += 4;
+		ret = parse_pci_options(p, &phys);
+		if (ret < 0)
+			return ret;
+		*iotype = (ret > 0) ? UPIO_PORT : UPIO_MEM;
+	} else if (strncmp(p, "pci32,", 6) == 0) {
+		p += 6;
+		ret = parse_pci_options(p, &phys);
+		if (ret < 0)
+			return ret;
+		*iotype = (ret > 0) ? UPIO_PORT : UPIO_MEM32;
 	} else if (strncmp(p, "io,", 3) == 0) {
 		*iotype = UPIO_PORT;
 		p += 3;
+		*addr = simple_strtoul(p, NULL, 0);
 	} else if (strncmp(p, "0x", 2) == 0) {
 		*iotype = UPIO_MEM;
+		*addr = simple_strtoul(p, NULL, 0);
 	} else {
 		return -EINVAL;
 	}
 
-	*addr = simple_strtoul(p, NULL, 0);
 	p = strchr(p, ',');
 	if (p)
 		p++;
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH v6 1/2] serial_core: add pci uart early console support
  2015-06-08 18:17 ` [PATCH v6 " Bin Gao
@ 2015-06-28 20:44   ` Peter Hurley
  2015-07-23 22:21   ` Greg Kroah-Hartman
  1 sibling, 0 replies; 5+ messages in thread
From: Peter Hurley @ 2015-06-28 20:44 UTC (permalink / raw)
  To: Bin Gao
  Cc: Greg Kroah-Hartman, One Thousand Gnomes, Jiri Slaby, Paul Bolle,
	linux-serial, linux-kernel

On 06/08/2015 02:17 PM, Bin Gao wrote:
> On some Intel Atom SoCs, the legacy IO port UART(0x3F8) is not available.
> Instead, a 8250 compatible PCI uart can be used as early console.
> This patch adds pci support to the 8250 early console driver uart8250.
> For example, to enable pci uart(00:21.3) as early console on these
> platforms, append the following line to the kernel command line
> (assume baud rate is 115200):
> earlyprintk=uart8250,pci32,0:24.2,115200n8

Reviewed-by: Peter Hurley <peter@hurleysoftware.com>

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH v6 1/2] serial_core: add pci uart early console support
  2015-06-08 18:17 ` [PATCH v6 " Bin Gao
  2015-06-28 20:44   ` Peter Hurley
@ 2015-07-23 22:21   ` Greg Kroah-Hartman
  2015-07-27 23:33     ` Bin Gao
  1 sibling, 1 reply; 5+ messages in thread
From: Greg Kroah-Hartman @ 2015-07-23 22:21 UTC (permalink / raw)
  To: Bin Gao
  Cc: One Thousand Gnomes, Peter Hurley, Jiri Slaby, Paul Bolle,
	linux-serial, linux-kernel

On Mon, Jun 08, 2015 at 11:17:11AM -0700, Bin Gao wrote:
> On some Intel Atom SoCs, the legacy IO port UART(0x3F8) is not available.
> Instead, a 8250 compatible PCI uart can be used as early console.
> This patch adds pci support to the 8250 early console driver uart8250.
> For example, to enable pci uart(00:21.3) as early console on these
> platforms, append the following line to the kernel command line
> (assume baud rate is 115200):
> earlyprintk=uart8250,pci32,0:24.2,115200n8
> 
> Signed-off-by: Bin Gao <bin.gao@intel.com>
> ---
> Changes in v6: None
> Changes in v5:
>  - updated Documentation/kernel-parameters.txt.
>  - moved earlyprintk= to patch 2/2 (requires x86 people's review).
>  - rolled back to simple_strto* APIs.
>  - seperate pci/pci32 format description.
>  - minor error and debug message changes.
>  - if/else statements in uart_parse_earlycon() were refactored to avoid
>    logic steering locals.
> Changes in v4:
>  - moved PCI_EARLY definition from arch/x86/Kconfig to drivers/pci/Kconfig
>  - made earlycon= for all archs but earlyprintk= only for x86 by changing
>    "#ifdef #else #endif" to "#if #endif".
> Changes in v3:
>  - introduced CONFIG_EARLY_PCI to protect pci codes in serial_core.c.
>  - added earlyprintk= as alia to earlycon= to keep x86 compatibility.
> changes in v2:
>  - added the second patch (2/2) to remove existed pci early console support
>    from arch/x86/kernel/early_printk.c.
>  Documentation/kernel-parameters.txt |  15 +++++
>  arch/x86/Kconfig                    |   1 +
>  drivers/pci/Kconfig                 |  11 ++++
>  drivers/tty/serial/serial_core.c    | 106 +++++++++++++++++++++++++++++++++++-
>  4 files changed, 132 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
> index 61ab162..598606e 100644
> --- a/Documentation/kernel-parameters.txt
> +++ b/Documentation/kernel-parameters.txt
> @@ -969,6 +969,16 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
>  			same format described for "console=ttyS<n>"; if
>  			unspecified, the h/w is not initialized.
>  
> +		uart8250,pci,<bus:dev.func>[,options]
> +		uart8250,pci32,<bus:dev.func>[,options]
> +			Start an early, polled-mode console on the 8250/16550
> +			UART at the specified PCI device (bus:dev.func).
> +			The io or memory mmaped register width is either 8-bit
> +			(pci) or 32-bit (pci32).
> +			'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
>  			port at the specified address. The pl011 serial port
> @@ -1009,6 +1019,8 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
>  			earlyprintk=serial[,0x...[,baudrate]]
>  			earlyprintk=ttySn[,baudrate]
>  			earlyprintk=dbgp[debugController#]
> +			earlyprintk=uart8250,pci,<bus:dev.fun>[,options]
> +			earlyprintk=uart8250,pci32,<bus:dev.func>[,options]
>  
>  			earlyprintk is useful when the kernel crashes before
>  			the normal console is initialized. It is not enabled by
> @@ -1037,6 +1049,9 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
>  
>  			The xen output can only be used by Xen PV guests.
>  
> +			The uart8250,pci and uart8250,pci32 output share the
> +			same definition that is in earlycon= section.
> +
>  	edac_report=	[HW,EDAC] Control how to report EDAC event
>  			Format: {"on" | "off" | "force"}
>  			on: enable EDAC to report H/W event. May be overridden
> diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
> index 226d569..bdedd61 100644
> --- a/arch/x86/Kconfig
> +++ b/arch/x86/Kconfig
> @@ -143,6 +143,7 @@ config X86
>  	select ACPI_LEGACY_TABLES_LOOKUP if ACPI
>  	select X86_FEATURE_NAMES if PROC_FS
>  	select SRCU
> +	select PCI_EARLY if PCI
>  
>  config INSTRUCTION_DECODER
>  	def_bool y
> diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
> index 7a8f1c5..4f0f055 100644
> --- a/drivers/pci/Kconfig
> +++ b/drivers/pci/Kconfig
> @@ -114,4 +114,15 @@ config PCI_LABEL
>  	def_bool y if (DMI || ACPI)
>  	select NLS
>  
> +config PCI_EARLY
> +	bool "Early PCI access"
> +	depends on PCI
> +	default n

Default is always 'n' so this isn't needed here.


> +	help
> +	  This option indicates that a group of APIs are available (in
> +	  asm/pci-direct.h) so the kernel can access pci config registers
> +	  before the PCI subsystem is initialized. Any arch that supports
> +	  early pci APIs should enable this option which is required  by
> +	  arch independent codes, e.g. uart8250 pci early console driver.
> +
>  source "drivers/pci/host/Kconfig"
> diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
> index 0b7bb12..5b21999 100644
> --- a/drivers/tty/serial/serial_core.c
> +++ b/drivers/tty/serial/serial_core.c
> @@ -34,10 +34,15 @@
>  #include <linux/serial_core.h>
>  #include <linux/delay.h>
>  #include <linux/mutex.h>
> +#include <linux/pci_regs.h>
>  
>  #include <asm/irq.h>
>  #include <asm/uaccess.h>
>  
> +#ifdef CONFIG_PCI_EARLY
> +#include <asm/pci-direct.h>
> +#endif

You shouldn't need an #ifdef here, the .h file should handle it.  Why
doesn't pci.h always include this if it is present?

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH v6 1/2] serial_core: add pci uart early console support
  2015-07-23 22:21   ` Greg Kroah-Hartman
@ 2015-07-27 23:33     ` Bin Gao
  0 siblings, 0 replies; 5+ messages in thread
From: Bin Gao @ 2015-07-27 23:33 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: One Thousand Gnomes, Peter Hurley, Jiri Slaby, Paul Bolle,
	linux-serial, linux-kernel

On Thu, Jul 23, 2015 at 03:21:27PM -0700, Greg Kroah-Hartman wrote:
> > +config PCI_EARLY
> > +	bool "Early PCI access"
> > +	depends on PCI
> > +	default n
> 
> Default is always 'n' so this isn't needed here.

Will fix this.

> > diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
> > index 0b7bb12..5b21999 100644
> > --- a/drivers/tty/serial/serial_core.c
> > +++ b/drivers/tty/serial/serial_core.c
> > @@ -34,10 +34,15 @@
> >  #include <linux/serial_core.h>
> >  #include <linux/delay.h>
> >  #include <linux/mutex.h>
> > +#include <linux/pci_regs.h>
> >  
> >  #include <asm/irq.h>
> >  #include <asm/uaccess.h>
> >  
> > +#ifdef CONFIG_PCI_EARLY
> > +#include <asm/pci-direct.h>
> > +#endif
> 
> You shouldn't need an #ifdef here, the .h file should handle it.  Why
> doesn't pci.h always include this if it is present?

Only x86 has asm/pci-direct.h. Compiling on any other archs will fail
if we don't put CONFIG_PCI_EARLY here. That's way I added a new config
option CONFIG_PCI_EARLY to drivers/pci/Kconfig and let an arch to select
it. Do you want me to move "#include <asm/pci-direct.h>" to linux/pci.h?

> 
> thanks,
> 
> greg k-h

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2015-07-27 23:33 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-05-29 18:38 [PATCH v5 1/2] serial_core: add pci uart early console support Bin Gao
2015-06-08 18:17 ` [PATCH v6 " Bin Gao
2015-06-28 20:44   ` Peter Hurley
2015-07-23 22:21   ` Greg Kroah-Hartman
2015-07-27 23:33     ` Bin Gao

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).