The old_serial_port global array in 8250_core is supposed to hold an entry for each serial port on the system that cannot be discovered via a standard enumeration mechanism (aka ACPI/PCI/DTS). The array is populated at compile-time from the value specified in the SERIAL_PORT_DFNS macro. This macro is defined in arch/serial.h.
For x86, this macro is currently unconditionally initialized to supply four ioport UARTs (0x3F8, 0x2F8, 0x3E8, 0x2E8). However, not all x86 CPUs have these four ioport UARTs. For example, the UARTs on AMD Carrizo and later are separate memory mapped Designware IP blocks. Fairly early in boot the console_initcall univ8250_console_init iterates over this array and installs these old UARTs into the global array serial8250_ports. Further, it attemptes to register them for use as the console. In other words, if, for example, the kernel commandline has console=ttyS0, the console will be switched over to one of these non-existent UARTs. Only later, when the real UART drivers are probed and their devices are instantiated will the console switch back over to the proper UART. This is most noticeable when using earlycon, since part of the serial console log will appear to disappear (when the bogus old takes over) and then re-appear (when the real UART finally gets registered for the console). Add a Kconfig option to allow overriding this default hard coded value for arch/x86 devices that do not have such serial ports. Signed-off-by: Daniel Kurtz <djku...@chromium.org> --- arch/x86/Kconfig | 11 +++++++++++ arch/x86/include/asm/serial.h | 4 ++++ 2 files changed, 15 insertions(+) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 0a258bb30159..7501cd776cfc 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -463,6 +463,17 @@ config X86_SERIAL_BASE_BAUD default, but may need to be changed to get earlycon to work on some hardware, such as those that use AMD Carrizo or later SoCs. +config X86_SERIAL_DEFINE_OLD_SERIAL_PORTS + bool "Define un-enumerable serial ports" + default y + help + Say Y here if you want the kernel to assume the precense of built-in + serial ports that do not have a standard enumeration mechanism. + Platforms that can find all serial ports via mechanisms like ACPI or + PCI can set this to N. + + If unsure, say Y. + if X86_32 config X86_BIGSMP bool "Support for big SMP systems with more than 8 CPUs" diff --git a/arch/x86/include/asm/serial.h b/arch/x86/include/asm/serial.h index c28151090b51..e86304c2bfae 100644 --- a/arch/x86/include/asm/serial.h +++ b/arch/x86/include/asm/serial.h @@ -24,11 +24,15 @@ # define STD_COM4_FLAGS (UPF_BOOT_AUTOCONF | 0 | 0 ) #endif +#ifdef CONFIG_X86_SERIAL_DEFINE_OLD_SERIAL_PORTS #define SERIAL_PORT_DFNS \ /* UART CLK PORT IRQ FLAGS */ \ { .uart = 0, BASE_BAUD, 0x3F8, 4, STD_COMX_FLAGS }, /* ttyS0 */ \ { .uart = 0, BASE_BAUD, 0x2F8, 3, STD_COMX_FLAGS }, /* ttyS1 */ \ { .uart = 0, BASE_BAUD, 0x3E8, 4, STD_COMX_FLAGS }, /* ttyS2 */ \ { .uart = 0, BASE_BAUD, 0x2E8, 3, STD_COM4_FLAGS }, /* ttyS3 */ +#else +#define SERIAL_PORT_DFNS +#endif #endif /* _ASM_X86_SERIAL_H */ -- 2.16.2.395.g2e18187dfd-goog