]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commitdiff
ACPI: SPCR: Make SPCR available to x86
authorPrarit Bhargava <prarit@redhat.com>
Thu, 18 Jan 2018 15:09:51 +0000 (10:09 -0500)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Wed, 7 Feb 2018 10:39:58 +0000 (11:39 +0100)
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>
Documentation/admin-guide/kernel-parameters.txt
arch/arm64/kernel/acpi.c
arch/x86/kernel/acpi/boot.c
drivers/acpi/Kconfig
drivers/acpi/spcr.c
drivers/tty/serial/earlycon.c
include/linux/acpi.h
include/linux/serial_core.h

index 1bdcf572c2ac7065102a4b8a8e8f7cd95d6433ed..aecb1c8ef675231a995c4a277aa404de90a6e508 100644 (file)
 
        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
index b3162715ed78daefb5b47e0ae9b0035b02217af6..2aa5609def27a876200a7825c296dfd0c8a6f149 100644 (file)
@@ -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);
        }
index ec3a286163c37aac183489be3a1cbf3312425d59..2aa92094b59d4fb6f3fffa8c0a920eb8023f6d45 100644 (file)
@@ -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;
 }
 
index 46505396869e615e17809d06ecac974798c39e51..ddcb5f40e8ee8fe59aabaed024804196ce0ba9c8 100644 (file)
@@ -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
index 324b35bfe781d42ad83e70d2f95d4ed56ab0854c..89e97d21a89ce26c7b8a0f5b53802618c871a927 100644 (file)
@@ -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);
 
-       err = add_preferred_console(uart, 0, opts + strlen(uart) + 1);
-
+       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;
index 4c8b80f1c688ca85b576bded14be885528af660f..870e84fb6e39ebb8fbfbc31f1a3608caddf6072d 100644 (file)
@@ -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();
index b8f4c3c776e5db8c41516c52e725fb0d5f442fdb..e6b98a32495f318d6a104437e7084d0e2a0d8f97 100644 (file)
@@ -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)
index 37b044e78333ab28b01c6460e5f00484658cc20e..aefd0e5115dae30703fdf6b61858c438a76665bf 100644 (file)
@@ -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