ACPI: SPCR: Make SPCR available to x86
SPCR is currently only enabled or ARM64 and x86 can use SPCR to setup an early console. General fixes include updating Documentation & Kconfig (for x86), updating comments, and changing parse_spcr() to acpi_parse_spcr(), and earlycon_init_is_deferred to earlycon_acpi_spcr_enable to be more descriptive. On x86, many systems have a valid SPCR table but the table version is not 2 so the table version check must be a warning. On ARM64 when the kernel parameter earlycon is used both the early console and console are enabled. On x86, only the earlycon should be enabled by by default. Modify acpi_parse_spcr() to allow options for initializing the early console and console separately. Signed-off-by: Prarit Bhargava <prarit@redhat.com> Acked-by: Ingo Molnar <mingo@kernel.org> Reviewed-by: Mark Salter <msalter@redhat.com> Tested-by: Mark Salter <msalter@redhat.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
This commit is contained in:
parent
890674343b
commit
0231d00082
|
@ -917,9 +917,12 @@
|
|||
|
||||
earlycon= [KNL] Output early console device and options.
|
||||
|
||||
When used with no options, the early console is
|
||||
determined by the stdout-path property in device
|
||||
tree's chosen node.
|
||||
[ARM64] The early console is determined by the
|
||||
stdout-path property in device tree's chosen node,
|
||||
or determined by the ACPI SPCR table.
|
||||
|
||||
[X86] When used with no options the early console is
|
||||
determined by the ACPI SPCR table.
|
||||
|
||||
cdns,<addr>[,options]
|
||||
Start an early, polled-mode console on a Cadence
|
||||
|
|
|
@ -230,10 +230,10 @@ void __init acpi_boot_table_init(void)
|
|||
|
||||
done:
|
||||
if (acpi_disabled) {
|
||||
if (earlycon_init_is_deferred)
|
||||
if (earlycon_acpi_spcr_enable)
|
||||
early_init_dt_scan_chosen_stdout();
|
||||
} else {
|
||||
parse_spcr(earlycon_init_is_deferred);
|
||||
acpi_parse_spcr(earlycon_acpi_spcr_enable, true);
|
||||
if (IS_ENABLED(CONFIG_ACPI_BGRT))
|
||||
acpi_table_parse(ACPI_SIG_BGRT, acpi_parse_bgrt);
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include <linux/ioport.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/efi-bgrt.h>
|
||||
#include <linux/serial_core.h>
|
||||
|
||||
#include <asm/e820/api.h>
|
||||
#include <asm/irqdomain.h>
|
||||
|
@ -1625,6 +1626,8 @@ int __init acpi_boot_init(void)
|
|||
if (!acpi_noirq)
|
||||
x86_init.pci.init = pci_acpi_init;
|
||||
|
||||
/* Do not enable ACPI SPCR console by default */
|
||||
acpi_parse_spcr(earlycon_acpi_spcr_enable, false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -79,7 +79,12 @@ config ACPI_DEBUGGER_USER
|
|||
endif
|
||||
|
||||
config ACPI_SPCR_TABLE
|
||||
bool
|
||||
bool "ACPI Serial Port Console Redirection Support"
|
||||
default y if X86
|
||||
help
|
||||
Enable support for Serial Port Console Redirection (SPCR) Table.
|
||||
This table provides information about the configuration of the
|
||||
earlycon console.
|
||||
|
||||
config ACPI_LPIT
|
||||
bool
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
* occasionally getting stuck as 1. To avoid the potential for a hang, check
|
||||
* TXFE == 0 instead of BUSY == 1. This may not be suitable for all UART
|
||||
* implementations, so only do so if an affected platform is detected in
|
||||
* parse_spcr().
|
||||
* acpi_parse_spcr().
|
||||
*/
|
||||
bool qdf2400_e44_present;
|
||||
EXPORT_SYMBOL(qdf2400_e44_present);
|
||||
|
@ -74,19 +74,21 @@ static bool xgene_8250_erratum_present(struct acpi_table_spcr *tb)
|
|||
}
|
||||
|
||||
/**
|
||||
* parse_spcr() - parse ACPI SPCR table and add preferred console
|
||||
* acpi_parse_spcr() - parse ACPI SPCR table and add preferred console
|
||||
*
|
||||
* @earlycon: set up earlycon for the console specified by the table
|
||||
* @enable_earlycon: set up earlycon for the console specified by the table
|
||||
* @enable_console: setup the console specified by the table.
|
||||
*
|
||||
* For the architectures with support for ACPI, CONFIG_ACPI_SPCR_TABLE may be
|
||||
* defined to parse ACPI SPCR table. As a result of the parsing preferred
|
||||
* console is registered and if @earlycon is true, earlycon is set up.
|
||||
* console is registered and if @enable_earlycon is true, earlycon is set up.
|
||||
* If @enable_console is true the system console is also configured.
|
||||
*
|
||||
* When CONFIG_ACPI_SPCR_TABLE is defined, this function should be called
|
||||
* from arch initialization code as soon as the DT/ACPI decision is made.
|
||||
*
|
||||
*/
|
||||
int __init parse_spcr(bool earlycon)
|
||||
int __init acpi_parse_spcr(bool enable_earlycon, bool enable_console)
|
||||
{
|
||||
static char opts[64];
|
||||
struct acpi_table_spcr *table;
|
||||
|
@ -105,11 +107,8 @@ int __init parse_spcr(bool earlycon)
|
|||
if (ACPI_FAILURE(status))
|
||||
return -ENOENT;
|
||||
|
||||
if (table->header.revision < 2) {
|
||||
err = -ENOENT;
|
||||
pr_err("wrong table version\n");
|
||||
goto done;
|
||||
}
|
||||
if (table->header.revision < 2)
|
||||
pr_info("SPCR table version %d\n", table->header.revision);
|
||||
|
||||
if (table->serial_port.space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
|
||||
switch (ACPI_ACCESS_BIT_WIDTH((
|
||||
|
@ -185,7 +184,7 @@ int __init parse_spcr(bool earlycon)
|
|||
*/
|
||||
if (qdf2400_erratum_44_present(&table->header)) {
|
||||
qdf2400_e44_present = true;
|
||||
if (earlycon)
|
||||
if (enable_earlycon)
|
||||
uart = "qdf2400_e44";
|
||||
}
|
||||
|
||||
|
@ -205,11 +204,13 @@ int __init parse_spcr(bool earlycon)
|
|||
|
||||
pr_info("console: %s\n", opts);
|
||||
|
||||
if (earlycon)
|
||||
if (enable_earlycon)
|
||||
setup_earlycon(opts);
|
||||
|
||||
if (enable_console)
|
||||
err = add_preferred_console(uart, 0, opts + strlen(uart) + 1);
|
||||
|
||||
else
|
||||
err = 0;
|
||||
done:
|
||||
acpi_put_table((struct acpi_table_header *)table);
|
||||
return err;
|
||||
|
|
|
@ -197,25 +197,20 @@ int __init setup_earlycon(char *buf)
|
|||
}
|
||||
|
||||
/*
|
||||
* When CONFIG_ACPI_SPCR_TABLE is defined, "earlycon" without parameters in
|
||||
* command line does not start DT earlycon immediately, instead it defers
|
||||
* starting it until DT/ACPI decision is made. At that time if ACPI is enabled
|
||||
* call parse_spcr(), else call early_init_dt_scan_chosen_stdout()
|
||||
* This defers the initialization of the early console until after ACPI has
|
||||
* been initialized.
|
||||
*/
|
||||
bool earlycon_init_is_deferred __initdata;
|
||||
bool earlycon_acpi_spcr_enable __initdata;
|
||||
|
||||
/* early_param wrapper for setup_earlycon() */
|
||||
static int __init param_setup_earlycon(char *buf)
|
||||
{
|
||||
int err;
|
||||
|
||||
/*
|
||||
* Just 'earlycon' is a valid param for devicetree earlycons;
|
||||
* don't generate a warning from parse_early_params() in that case
|
||||
*/
|
||||
/* Just 'earlycon' is a valid param for devicetree and ACPI SPCR. */
|
||||
if (!buf || !buf[0]) {
|
||||
if (IS_ENABLED(CONFIG_ACPI_SPCR_TABLE)) {
|
||||
earlycon_init_is_deferred = true;
|
||||
earlycon_acpi_spcr_enable = true;
|
||||
return 0;
|
||||
} else if (!buf) {
|
||||
return early_init_dt_scan_chosen_stdout();
|
||||
|
|
|
@ -1249,9 +1249,12 @@ static inline bool acpi_has_watchdog(void) { return false; }
|
|||
|
||||
#ifdef CONFIG_ACPI_SPCR_TABLE
|
||||
extern bool qdf2400_e44_present;
|
||||
int parse_spcr(bool earlycon);
|
||||
int acpi_parse_spcr(bool enable_earlycon, bool enable_console);
|
||||
#else
|
||||
static inline int parse_spcr(bool earlycon) { return 0; }
|
||||
static inline int acpi_parse_spcr(bool enable_earlycon, bool enable_console)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if IS_ENABLED(CONFIG_ACPI_GENERIC_GSI)
|
||||
|
|
|
@ -376,10 +376,10 @@ extern int of_setup_earlycon(const struct earlycon_id *match,
|
|||
const char *options);
|
||||
|
||||
#ifdef CONFIG_SERIAL_EARLYCON
|
||||
extern bool earlycon_init_is_deferred __initdata;
|
||||
extern bool earlycon_acpi_spcr_enable __initdata;
|
||||
int setup_earlycon(char *buf);
|
||||
#else
|
||||
static const bool earlycon_init_is_deferred;
|
||||
static const bool earlycon_acpi_spcr_enable;
|
||||
static inline int setup_earlycon(char *buf) { return 0; }
|
||||
#endif
|
||||
|
||||
|
|
Loading…
Reference in a new issue