aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPrarit Bhargava <prarit@redhat.com>2018-01-18 10:09:51 -0500
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2018-02-07 05:39:58 -0500
commit0231d00082f61cfe03f2b7c27e5356f8cdf0312c (patch)
tree24f036cb972640ccdeed395a55d1c37571fcb3db
parent890674343bb2d546825f713542b1e199f0728732 (diff)
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>
-rw-r--r--Documentation/admin-guide/kernel-parameters.txt9
-rw-r--r--arch/arm64/kernel/acpi.c4
-rw-r--r--arch/x86/kernel/acpi/boot.c3
-rw-r--r--drivers/acpi/Kconfig7
-rw-r--r--drivers/acpi/spcr.c29
-rw-r--r--drivers/tty/serial/earlycon.c15
-rw-r--r--include/linux/acpi.h7
-rw-r--r--include/linux/serial_core.h4
8 files changed, 44 insertions, 34 deletions
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 1bdcf572c2ac..aecb1c8ef675 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -917,9 +917,12 @@
917 917
918 earlycon= [KNL] Output early console device and options. 918 earlycon= [KNL] Output early console device and options.
919 919
920 When used with no options, the early console is 920 [ARM64] The early console is determined by the
921 determined by the stdout-path property in device 921 stdout-path property in device tree's chosen node,
922 tree's chosen node. 922 or determined by the ACPI SPCR table.
923
924 [X86] When used with no options the early console is
925 determined by the ACPI SPCR table.
923 926
924 cdns,<addr>[,options] 927 cdns,<addr>[,options]
925 Start an early, polled-mode console on a Cadence 928 Start an early, polled-mode console on a Cadence
diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
index b3162715ed78..2aa5609def27 100644
--- a/arch/arm64/kernel/acpi.c
+++ b/arch/arm64/kernel/acpi.c
@@ -230,10 +230,10 @@ void __init acpi_boot_table_init(void)
230 230
231done: 231done:
232 if (acpi_disabled) { 232 if (acpi_disabled) {
233 if (earlycon_init_is_deferred) 233 if (earlycon_acpi_spcr_enable)
234 early_init_dt_scan_chosen_stdout(); 234 early_init_dt_scan_chosen_stdout();
235 } else { 235 } else {
236 parse_spcr(earlycon_init_is_deferred); 236 acpi_parse_spcr(earlycon_acpi_spcr_enable, true);
237 if (IS_ENABLED(CONFIG_ACPI_BGRT)) 237 if (IS_ENABLED(CONFIG_ACPI_BGRT))
238 acpi_table_parse(ACPI_SIG_BGRT, acpi_parse_bgrt); 238 acpi_table_parse(ACPI_SIG_BGRT, acpi_parse_bgrt);
239 } 239 }
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index ec3a286163c3..2aa92094b59d 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -36,6 +36,7 @@
36#include <linux/ioport.h> 36#include <linux/ioport.h>
37#include <linux/pci.h> 37#include <linux/pci.h>
38#include <linux/efi-bgrt.h> 38#include <linux/efi-bgrt.h>
39#include <linux/serial_core.h>
39 40
40#include <asm/e820/api.h> 41#include <asm/e820/api.h>
41#include <asm/irqdomain.h> 42#include <asm/irqdomain.h>
@@ -1625,6 +1626,8 @@ int __init acpi_boot_init(void)
1625 if (!acpi_noirq) 1626 if (!acpi_noirq)
1626 x86_init.pci.init = pci_acpi_init; 1627 x86_init.pci.init = pci_acpi_init;
1627 1628
1629 /* Do not enable ACPI SPCR console by default */
1630 acpi_parse_spcr(earlycon_acpi_spcr_enable, false);
1628 return 0; 1631 return 0;
1629} 1632}
1630 1633
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 46505396869e..ddcb5f40e8ee 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -79,7 +79,12 @@ config ACPI_DEBUGGER_USER
79endif 79endif
80 80
81config ACPI_SPCR_TABLE 81config ACPI_SPCR_TABLE
82 bool 82 bool "ACPI Serial Port Console Redirection Support"
83 default y if X86
84 help
85 Enable support for Serial Port Console Redirection (SPCR) Table.
86 This table provides information about the configuration of the
87 earlycon console.
83 88
84config ACPI_LPIT 89config ACPI_LPIT
85 bool 90 bool
diff --git a/drivers/acpi/spcr.c b/drivers/acpi/spcr.c
index 324b35bfe781..89e97d21a89c 100644
--- a/drivers/acpi/spcr.c
+++ b/drivers/acpi/spcr.c
@@ -21,7 +21,7 @@
21 * occasionally getting stuck as 1. To avoid the potential for a hang, check 21 * occasionally getting stuck as 1. To avoid the potential for a hang, check
22 * TXFE == 0 instead of BUSY == 1. This may not be suitable for all UART 22 * TXFE == 0 instead of BUSY == 1. This may not be suitable for all UART
23 * implementations, so only do so if an affected platform is detected in 23 * implementations, so only do so if an affected platform is detected in
24 * parse_spcr(). 24 * acpi_parse_spcr().
25 */ 25 */
26bool qdf2400_e44_present; 26bool qdf2400_e44_present;
27EXPORT_SYMBOL(qdf2400_e44_present); 27EXPORT_SYMBOL(qdf2400_e44_present);
@@ -74,19 +74,21 @@ static bool xgene_8250_erratum_present(struct acpi_table_spcr *tb)
74} 74}
75 75
76/** 76/**
77 * parse_spcr() - parse ACPI SPCR table and add preferred console 77 * acpi_parse_spcr() - parse ACPI SPCR table and add preferred console
78 * 78 *
79 * @earlycon: set up earlycon for the console specified by the table 79 * @enable_earlycon: set up earlycon for the console specified by the table
80 * @enable_console: setup the console specified by the table.
80 * 81 *
81 * For the architectures with support for ACPI, CONFIG_ACPI_SPCR_TABLE may be 82 * For the architectures with support for ACPI, CONFIG_ACPI_SPCR_TABLE may be
82 * defined to parse ACPI SPCR table. As a result of the parsing preferred 83 * defined to parse ACPI SPCR table. As a result of the parsing preferred
83 * console is registered and if @earlycon is true, earlycon is set up. 84 * console is registered and if @enable_earlycon is true, earlycon is set up.
85 * If @enable_console is true the system console is also configured.
84 * 86 *
85 * When CONFIG_ACPI_SPCR_TABLE is defined, this function should be called 87 * When CONFIG_ACPI_SPCR_TABLE is defined, this function should be called
86 * from arch initialization code as soon as the DT/ACPI decision is made. 88 * from arch initialization code as soon as the DT/ACPI decision is made.
87 * 89 *
88 */ 90 */
89int __init parse_spcr(bool earlycon) 91int __init acpi_parse_spcr(bool enable_earlycon, bool enable_console)
90{ 92{
91 static char opts[64]; 93 static char opts[64];
92 struct acpi_table_spcr *table; 94 struct acpi_table_spcr *table;
@@ -105,11 +107,8 @@ int __init parse_spcr(bool earlycon)
105 if (ACPI_FAILURE(status)) 107 if (ACPI_FAILURE(status))
106 return -ENOENT; 108 return -ENOENT;
107 109
108 if (table->header.revision < 2) { 110 if (table->header.revision < 2)
109 err = -ENOENT; 111 pr_info("SPCR table version %d\n", table->header.revision);
110 pr_err("wrong table version\n");
111 goto done;
112 }
113 112
114 if (table->serial_port.space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { 113 if (table->serial_port.space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
115 switch (ACPI_ACCESS_BIT_WIDTH(( 114 switch (ACPI_ACCESS_BIT_WIDTH((
@@ -185,7 +184,7 @@ int __init parse_spcr(bool earlycon)
185 */ 184 */
186 if (qdf2400_erratum_44_present(&table->header)) { 185 if (qdf2400_erratum_44_present(&table->header)) {
187 qdf2400_e44_present = true; 186 qdf2400_e44_present = true;
188 if (earlycon) 187 if (enable_earlycon)
189 uart = "qdf2400_e44"; 188 uart = "qdf2400_e44";
190 } 189 }
191 190
@@ -205,11 +204,13 @@ int __init parse_spcr(bool earlycon)
205 204
206 pr_info("console: %s\n", opts); 205 pr_info("console: %s\n", opts);
207 206
208 if (earlycon) 207 if (enable_earlycon)
209 setup_earlycon(opts); 208 setup_earlycon(opts);
210 209
211 err = add_preferred_console(uart, 0, opts + strlen(uart) + 1); 210 if (enable_console)
212 211 err = add_preferred_console(uart, 0, opts + strlen(uart) + 1);
212 else
213 err = 0;
213done: 214done:
214 acpi_put_table((struct acpi_table_header *)table); 215 acpi_put_table((struct acpi_table_header *)table);
215 return err; 216 return err;
diff --git a/drivers/tty/serial/earlycon.c b/drivers/tty/serial/earlycon.c
index 4c8b80f1c688..870e84fb6e39 100644
--- a/drivers/tty/serial/earlycon.c
+++ b/drivers/tty/serial/earlycon.c
@@ -197,25 +197,20 @@ int __init setup_earlycon(char *buf)
197} 197}
198 198
199/* 199/*
200 * When CONFIG_ACPI_SPCR_TABLE is defined, "earlycon" without parameters in 200 * This defers the initialization of the early console until after ACPI has
201 * command line does not start DT earlycon immediately, instead it defers 201 * been initialized.
202 * starting it until DT/ACPI decision is made. At that time if ACPI is enabled
203 * call parse_spcr(), else call early_init_dt_scan_chosen_stdout()
204 */ 202 */
205bool earlycon_init_is_deferred __initdata; 203bool earlycon_acpi_spcr_enable __initdata;
206 204
207/* early_param wrapper for setup_earlycon() */ 205/* early_param wrapper for setup_earlycon() */
208static int __init param_setup_earlycon(char *buf) 206static int __init param_setup_earlycon(char *buf)
209{ 207{
210 int err; 208 int err;
211 209
212 /* 210 /* Just 'earlycon' is a valid param for devicetree and ACPI SPCR. */
213 * Just 'earlycon' is a valid param for devicetree earlycons;
214 * don't generate a warning from parse_early_params() in that case
215 */
216 if (!buf || !buf[0]) { 211 if (!buf || !buf[0]) {
217 if (IS_ENABLED(CONFIG_ACPI_SPCR_TABLE)) { 212 if (IS_ENABLED(CONFIG_ACPI_SPCR_TABLE)) {
218 earlycon_init_is_deferred = true; 213 earlycon_acpi_spcr_enable = true;
219 return 0; 214 return 0;
220 } else if (!buf) { 215 } else if (!buf) {
221 return early_init_dt_scan_chosen_stdout(); 216 return early_init_dt_scan_chosen_stdout();
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index b8f4c3c776e5..e6b98a32495f 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -1249,9 +1249,12 @@ static inline bool acpi_has_watchdog(void) { return false; }
1249 1249
1250#ifdef CONFIG_ACPI_SPCR_TABLE 1250#ifdef CONFIG_ACPI_SPCR_TABLE
1251extern bool qdf2400_e44_present; 1251extern bool qdf2400_e44_present;
1252int parse_spcr(bool earlycon); 1252int acpi_parse_spcr(bool enable_earlycon, bool enable_console);
1253#else 1253#else
1254static inline int parse_spcr(bool earlycon) { return 0; } 1254static inline int acpi_parse_spcr(bool enable_earlycon, bool enable_console)
1255{
1256 return 0;
1257}
1255#endif 1258#endif
1256 1259
1257#if IS_ENABLED(CONFIG_ACPI_GENERIC_GSI) 1260#if IS_ENABLED(CONFIG_ACPI_GENERIC_GSI)
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index 37b044e78333..aefd0e5115da 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -376,10 +376,10 @@ extern int of_setup_earlycon(const struct earlycon_id *match,
376 const char *options); 376 const char *options);
377 377
378#ifdef CONFIG_SERIAL_EARLYCON 378#ifdef CONFIG_SERIAL_EARLYCON
379extern bool earlycon_init_is_deferred __initdata; 379extern bool earlycon_acpi_spcr_enable __initdata;
380int setup_earlycon(char *buf); 380int setup_earlycon(char *buf);
381#else 381#else
382static const bool earlycon_init_is_deferred; 382static const bool earlycon_acpi_spcr_enable;
383static inline int setup_earlycon(char *buf) { return 0; } 383static inline int setup_earlycon(char *buf) { return 0; }
384#endif 384#endif
385 385