From babc92da5928f81af951663fc436997352e02d3a Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Fri, 14 Jan 2022 13:24:49 +0200 Subject: [PATCH 01/13] ACPI: properties: Consistently return -ENOENT if there are no more references __acpi_node_get_property_reference() is documented to return -ENOENT if the caller requests a property reference at an index that does not exist, not -EINVAL which it actually does. Fix this by returning -ENOENT consistenly, independently of whether the property value is a plain reference or a package. Fixes: c343bc2ce2c6 ("ACPI: properties: Align return codes of __acpi_node_get_property_reference()") Cc: 4.14+ # 4.14+ Signed-off-by: Sakari Ailus Signed-off-by: Rafael J. Wysocki --- drivers/acpi/property.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c index d0986bda2964..3fceb4681ec9 100644 --- a/drivers/acpi/property.c +++ b/drivers/acpi/property.c @@ -685,7 +685,7 @@ int __acpi_node_get_property_reference(const struct fwnode_handle *fwnode, */ if (obj->type == ACPI_TYPE_LOCAL_REFERENCE) { if (index) - return -EINVAL; + return -ENOENT; device = acpi_fetch_acpi_dev(obj->reference.handle); if (!device) From 631e3893c35e116d16b81b41bea6ba2143db4fa4 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 1 Feb 2022 20:18:10 +0100 Subject: [PATCH 02/13] ACPI: PM: Print additional debug message in acpi_s2idle_wake() Make acpi_s2idle_wake() print an additional debug message when the SCI is going to be rearmed for system wakeup to help diagnose wakeup-related issues. Signed-off-by: Rafael J. Wysocki --- drivers/acpi/sleep.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index d4fbea91ab6b..d068ff42fce4 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -758,6 +758,8 @@ bool acpi_s2idle_wake(void) return true; } + pm_pr_dbg("Rearming ACPI SCI for wakeup\n"); + pm_wakeup_clear(acpi_sci_irq); rearm_wake_irq(acpi_sci_irq); } From 977dc3082285206e7b1fcbc4496671194cfb7980 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 1 Feb 2022 20:18:56 +0100 Subject: [PATCH 03/13] ACPI: EC / PM: Print additional debug message in acpi_ec_dispatch_gpe() Make acpi_ec_dispatch_gpe() print an additional debug message after seeing the EC GPE status bit set to help diagnose wakeup-related issues. Signed-off-by: Rafael J. Wysocki --- drivers/acpi/ec.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 46710380a402..f039565d59ad 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -2081,8 +2081,11 @@ bool acpi_ec_dispatch_gpe(void) */ spin_lock_irq(&first_ec->lock); - if (acpi_ec_gpe_status_set(first_ec)) + if (acpi_ec_gpe_status_set(first_ec)) { + pm_pr_dbg("ACPI EC GPE status set\n"); + work_in_progress = advance_transaction(first_ec, false); + } spin_unlock_irq(&first_ec->lock); From 9978f446d406a7dae080ca4a682bac927c9b8773 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 9 Feb 2022 16:53:18 +0200 Subject: [PATCH 04/13] ACPI: property: Get rid of redundant 'else' In the snippets like the following if (...) return / goto / break / continue ...; else ... the 'else' is redundant. Get rid of it. While at it, replace conditional '<= 0' for unsigned type by '== 0' in acpi_data_prop_read(); update comment in the __acpi_node_get_property_reference() on how we parse the reference. Signed-off-by: Andy Shevchenko Signed-off-by: Rafael J. Wysocki --- drivers/acpi/property.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c index 3fceb4681ec9..12bbfe833609 100644 --- a/drivers/acpi/property.c +++ b/drivers/acpi/property.c @@ -541,7 +541,8 @@ acpi_device_data_of_node(const struct fwnode_handle *fwnode) if (is_acpi_device_node(fwnode)) { const struct acpi_device *adev = to_acpi_device_node(fwnode); return &adev->data; - } else if (is_acpi_data_node(fwnode)) { + } + if (is_acpi_data_node(fwnode)) { const struct acpi_data_node *dn = to_acpi_data_node(fwnode); return &dn->data; } @@ -739,14 +740,19 @@ int __acpi_node_get_property_reference(const struct fwnode_handle *fwnode, return -EINVAL; } - /* assume following integer elements are all args */ + /* + * Assume the following integer elements are all args. + * Stop counting on the first reference or end of the + * package arguments. In case of neither reference, + * nor integer, return an error, we can't parse it. + */ for (i = 0; element + i < end && i < num_args; i++) { int type = element[i].type; + if (type == ACPI_TYPE_LOCAL_REFERENCE) + break; if (type == ACPI_TYPE_INTEGER) nargs++; - else if (type == ACPI_TYPE_LOCAL_REFERENCE) - break; else return -EINVAL; } @@ -950,7 +956,7 @@ static int acpi_data_prop_read(const struct acpi_device_data *data, if (proptype != DEV_PROP_STRING && nval > obj->package.count) return -EOVERFLOW; - else if (nval <= 0) + if (nval == 0) return -EINVAL; items = obj->package.elements; @@ -1012,14 +1018,10 @@ struct fwnode_handle *acpi_get_next_subnode(const struct fwnode_handle *fwnode, const struct list_head *head; struct list_head *next; - if (!child || is_acpi_device_node(child)) { + if ((!child || is_acpi_device_node(child)) && adev) { struct acpi_device *child_adev; - if (adev) - head = &adev->children; - else - goto nondev; - + head = &adev->children; if (list_empty(head)) goto nondev; @@ -1089,7 +1091,8 @@ acpi_node_get_parent(const struct fwnode_handle *fwnode) if (is_acpi_data_node(fwnode)) { /* All data nodes have parent pointer so just return that */ return to_acpi_data_node(fwnode)->parent; - } else if (is_acpi_device_node(fwnode)) { + } + if (is_acpi_device_node(fwnode)) { struct device *dev = to_acpi_device_node(fwnode)->dev.parent; if (dev) From a8ab8ef437d48173e166f1f44f202097e91bf81c Mon Sep 17 00:00:00 2001 From: Tom Rix Date: Sun, 6 Feb 2022 06:58:03 -0800 Subject: [PATCH 05/13] ACPI: clean up double words in two comments Remove the second 'on' and 'those'. Signed-off-by: Tom Rix [ rjw: Subject adjustments ] Signed-off-by: Rafael J. Wysocki --- drivers/acpi/Kconfig | 2 +- drivers/acpi/pci_link.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 273741dedfd2..1e34f846508f 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -302,7 +302,7 @@ config ACPI_IPMI help This driver enables the ACPI to access the BMC controller. And it uses the IPMI request/response message to communicate with BMC - controller, which can be found on on the server. + controller, which can be found on the server. To compile this driver as a module, choose M here: the module will be called as acpi_ipmi. diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c index d54fb8e54671..58647051c948 100644 --- a/drivers/acpi/pci_link.c +++ b/drivers/acpi/pci_link.c @@ -185,7 +185,7 @@ static acpi_status acpi_pci_link_check_current(struct acpi_resource *resource, if (!p || !p->interrupt_count) { /* * IRQ descriptors may have no IRQ# bits set, - * particularly those those w/ _STA disabled + * particularly those w/ _STA disabled */ pr_debug("Blank _CRS IRQ resource\n"); return AE_OK; From f38312c9b569322edf4baae467568206fe46d57b Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Wed, 23 Feb 2022 14:50:31 +0100 Subject: [PATCH 06/13] ACPI / x86: Add skip i2c clients quirk for Nextbook Ares 8 The Nextbook Ares 8 is a x86 ACPI tablet which ships with Android x86 as factory OS. Its DSDT contains a bunch of I2C devices which are not actually there, causing various resource conflicts (the Android x86 kernel fork ignores I2C devices described in the DSDT). Add a ACPI_QUIRK_SKIP_I2C_CLIENTS for the Nextbook Ares 8 to the acpi_quirk_skip_dmi_ids table to woraround this. Signed-off-by: Hans de Goede Signed-off-by: Rafael J. Wysocki --- drivers/acpi/x86/utils.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/acpi/x86/utils.c b/drivers/acpi/x86/utils.c index ffdeed5334d6..9b991294f1e5 100644 --- a/drivers/acpi/x86/utils.c +++ b/drivers/acpi/x86/utils.c @@ -284,6 +284,15 @@ static const struct dmi_system_id acpi_quirk_skip_dmi_ids[] = { .driver_data = (void *)(ACPI_QUIRK_SKIP_I2C_CLIENTS | ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY), }, + { + /* Nextbook Ares 8 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Insyde"), + DMI_MATCH(DMI_PRODUCT_NAME, "M890BAP"), + }, + .driver_data = (void *)(ACPI_QUIRK_SKIP_I2C_CLIENTS | + ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY), + }, { /* Whitelabel (sold as various brands) TM800A550L */ .matches = { From 4fecb1e93e4914fc0bc1fb467ca79741f9f94abb Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Wed, 23 Feb 2022 14:50:32 +0100 Subject: [PATCH 07/13] ACPI / x86: Add skip i2c clients quirk for Lenovo Yoga Tablet 1050F/L The Yoga Tablet 1050F/L is a x86 ACPI tablet which ships with Android x86 as factory OS. Its DSDT contains a bunch of I2C devices which are not actually there, causing various resource conflicts (the Android x86 kernel fork ignores I2C devices described in the DSDT). Add a ACPI_QUIRK_SKIP_I2C_CLIENTS for the Nextbook Ares 8 to the acpi_quirk_skip_dmi_ids table to woraround this. Signed-off-by: Hans de Goede Signed-off-by: Rafael J. Wysocki --- drivers/acpi/x86/utils.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/acpi/x86/utils.c b/drivers/acpi/x86/utils.c index 9b991294f1e5..664070fc8349 100644 --- a/drivers/acpi/x86/utils.c +++ b/drivers/acpi/x86/utils.c @@ -284,6 +284,18 @@ static const struct dmi_system_id acpi_quirk_skip_dmi_ids[] = { .driver_data = (void *)(ACPI_QUIRK_SKIP_I2C_CLIENTS | ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY), }, + { + /* Lenovo Yoga Tablet 1050F/L */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Intel Corp."), + DMI_MATCH(DMI_PRODUCT_NAME, "VALLEYVIEW C0 PLATFORM"), + DMI_MATCH(DMI_BOARD_NAME, "BYT-T FFD8"), + /* Partial match on beginning of BIOS version */ + DMI_MATCH(DMI_BIOS_VERSION, "BLADE_21"), + }, + .driver_data = (void *)(ACPI_QUIRK_SKIP_I2C_CLIENTS | + ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY), + }, { /* Nextbook Ares 8 */ .matches = { From fd8af343a299df264c41b1219358f502c7b5b18a Mon Sep 17 00:00:00 2001 From: Huang Rui Date: Mon, 14 Feb 2022 18:14:47 +0800 Subject: [PATCH 08/13] x86/ACPI: CPPC: Rename cppc_msr.c to cppc.c Rename the cppc_msr.c to cppc.c in x86 ACPI, that expects to use this file to cover more function implementation for ACPI CPPC beside MSR helpers. Naming as "cppc" is more straightforward as one of the functionalities under ACPI subsystem. Signed-off-by: Huang Rui [ rjw: Subject ] Signed-off-by: Rafael J. Wysocki --- arch/x86/kernel/acpi/Makefile | 2 +- arch/x86/kernel/acpi/{cppc_msr.c => cppc.c} | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename arch/x86/kernel/acpi/{cppc_msr.c => cppc.c} (96%) diff --git a/arch/x86/kernel/acpi/Makefile b/arch/x86/kernel/acpi/Makefile index cf340d85946a..fc17b3f136fe 100644 --- a/arch/x86/kernel/acpi/Makefile +++ b/arch/x86/kernel/acpi/Makefile @@ -3,7 +3,7 @@ obj-$(CONFIG_ACPI) += boot.o obj-$(CONFIG_ACPI_SLEEP) += sleep.o wakeup_$(BITS).o obj-$(CONFIG_ACPI_APEI) += apei.o -obj-$(CONFIG_ACPI_CPPC_LIB) += cppc_msr.o +obj-$(CONFIG_ACPI_CPPC_LIB) += cppc.o ifneq ($(CONFIG_ACPI_PROCESSOR),) obj-y += cstate.o diff --git a/arch/x86/kernel/acpi/cppc_msr.c b/arch/x86/kernel/acpi/cppc.c similarity index 96% rename from arch/x86/kernel/acpi/cppc_msr.c rename to arch/x86/kernel/acpi/cppc.c index b961de569e7e..08d823d72586 100644 --- a/arch/x86/kernel/acpi/cppc_msr.c +++ b/arch/x86/kernel/acpi/cppc.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * cppc_msr.c: MSR Interface for CPPC + * cppc.c: CPPC Interface for x86 * Copyright (c) 2016, Intel Corporation. */ From 82d89369141b8fab56deff540121b8d09d289bfd Mon Sep 17 00:00:00 2001 From: Huang Rui Date: Mon, 14 Feb 2022 18:14:48 +0800 Subject: [PATCH 09/13] x86/ACPI: CPPC: Move AMD maximum frequency ratio setting function into x86 CPPC The AMD maximum frequency ratio setting function depends on CPPC, so the x86 CPPC implementation file is better space for this function. Signed-off-by: Huang Rui [ rjw: Subject adjustment ] Signed-off-by: Rafael J. Wysocki --- arch/x86/include/asm/topology.h | 9 +++++++ arch/x86/kernel/acpi/cppc.c | 40 ++++++++++++++++++++++++++++++ arch/x86/kernel/smpboot.c | 44 +-------------------------------- 3 files changed, 50 insertions(+), 43 deletions(-) diff --git a/arch/x86/include/asm/topology.h b/arch/x86/include/asm/topology.h index 2f0b6be8eaab..168ade7d4007 100644 --- a/arch/x86/include/asm/topology.h +++ b/arch/x86/include/asm/topology.h @@ -226,4 +226,13 @@ void init_freq_invariance_cppc(void); #define init_freq_invariance_cppc init_freq_invariance_cppc #endif +#ifdef CONFIG_ACPI_CPPC_LIB +bool amd_set_max_freq_ratio(u64 *ratio); +#else +static inline bool amd_set_max_freq_ratio(u64 *ratio) +{ + return false; +} +#endif + #endif /* _ASM_X86_TOPOLOGY_H */ diff --git a/arch/x86/kernel/acpi/cppc.c b/arch/x86/kernel/acpi/cppc.c index 08d823d72586..f0be5058e3e3 100644 --- a/arch/x86/kernel/acpi/cppc.c +++ b/arch/x86/kernel/acpi/cppc.c @@ -6,6 +6,8 @@ #include #include +#include +#include /* Refer to drivers/acpi/cppc_acpi.c for the description of functions */ @@ -47,3 +49,41 @@ int cpc_write_ffh(int cpunum, struct cpc_reg *reg, u64 val) } return err; } + +bool amd_set_max_freq_ratio(u64 *ratio) +{ + struct cppc_perf_caps perf_caps; + u64 highest_perf, nominal_perf; + u64 perf_ratio; + int rc; + + if (!ratio) + return false; + + rc = cppc_get_perf_caps(0, &perf_caps); + if (rc) { + pr_debug("Could not retrieve perf counters (%d)\n", rc); + return false; + } + + highest_perf = amd_get_highest_perf(); + nominal_perf = perf_caps.nominal_perf; + + if (!highest_perf || !nominal_perf) { + pr_debug("Could not retrieve highest or nominal performance\n"); + return false; + } + + perf_ratio = div_u64(highest_perf * SCHED_CAPACITY_SCALE, nominal_perf); + /* midpoint between max_boost and max_P */ + perf_ratio = (perf_ratio + SCHED_CAPACITY_SCALE) >> 1; + if (!perf_ratio) { + pr_debug("Non-zero highest/nominal perf values led to a 0 ratio\n"); + return false; + } + + *ratio = perf_ratio; + arch_set_max_freq_ratio(false); + + return true; +} diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index 617012f4619f..0718cc7649a4 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c @@ -2097,48 +2097,6 @@ out: return true; } -#ifdef CONFIG_ACPI_CPPC_LIB -static bool amd_set_max_freq_ratio(void) -{ - struct cppc_perf_caps perf_caps; - u64 highest_perf, nominal_perf; - u64 perf_ratio; - int rc; - - rc = cppc_get_perf_caps(0, &perf_caps); - if (rc) { - pr_debug("Could not retrieve perf counters (%d)\n", rc); - return false; - } - - highest_perf = amd_get_highest_perf(); - nominal_perf = perf_caps.nominal_perf; - - if (!highest_perf || !nominal_perf) { - pr_debug("Could not retrieve highest or nominal performance\n"); - return false; - } - - perf_ratio = div_u64(highest_perf * SCHED_CAPACITY_SCALE, nominal_perf); - /* midpoint between max_boost and max_P */ - perf_ratio = (perf_ratio + SCHED_CAPACITY_SCALE) >> 1; - if (!perf_ratio) { - pr_debug("Non-zero highest/nominal perf values led to a 0 ratio\n"); - return false; - } - - arch_turbo_freq_ratio = perf_ratio; - arch_set_max_freq_ratio(false); - - return true; -} -#else -static bool amd_set_max_freq_ratio(void) -{ - return false; -} -#endif - static void init_counter_refs(void) { u64 aperf, mperf; @@ -2187,7 +2145,7 @@ static void init_freq_invariance(bool secondary, bool cppc_ready) if (!cppc_ready) { return; } - ret = amd_set_max_freq_ratio(); + ret = amd_set_max_freq_ratio(&arch_turbo_freq_ratio); } if (ret) { From 666f6ecf35bc3a14ab01fa761a7e17afac04dcd5 Mon Sep 17 00:00:00 2001 From: Huang Rui Date: Mon, 14 Feb 2022 18:14:49 +0800 Subject: [PATCH 10/13] x86: Expose init_freq_invariance() to topology header The function init_freq_invariance will be used on x86 CPPC, so expose it in the topology header. Signed-off-by: Huang Rui [ rjw: Subject adjustment ] Signed-off-by: Rafael J. Wysocki --- arch/x86/include/asm/topology.h | 4 ++++ arch/x86/kernel/smpboot.c | 8 +------- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/arch/x86/include/asm/topology.h b/arch/x86/include/asm/topology.h index 168ade7d4007..c35005a03768 100644 --- a/arch/x86/include/asm/topology.h +++ b/arch/x86/include/asm/topology.h @@ -215,10 +215,14 @@ extern void arch_scale_freq_tick(void); #define arch_scale_freq_tick arch_scale_freq_tick extern void arch_set_max_freq_ratio(bool turbo_disabled); +void init_freq_invariance(bool secondary, bool cppc_ready); #else static inline void arch_set_max_freq_ratio(bool turbo_disabled) { } +static inline void init_freq_invariance(bool secondary, bool cppc_ready) +{ +} #endif #if defined(CONFIG_ACPI_CPPC_LIB) && defined(CONFIG_SMP) diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index 0718cc7649a4..8f2ff9be0fcc 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c @@ -155,8 +155,6 @@ static inline void smpboot_restore_warm_reset_vector(void) *((volatile u32 *)phys_to_virt(TRAMPOLINE_PHYS_LOW)) = 0; } -static void init_freq_invariance(bool secondary, bool cppc_ready); - /* * Report back to the Boot Processor during boot time or to the caller processor * during CPU online. @@ -2125,7 +2123,7 @@ static void register_freq_invariance_syscore_ops(void) static inline void register_freq_invariance_syscore_ops(void) {} #endif -static void init_freq_invariance(bool secondary, bool cppc_ready) +void init_freq_invariance(bool secondary, bool cppc_ready) { bool ret = false; @@ -2222,8 +2220,4 @@ error: pr_warn("Scheduler frequency invariance went wobbly, disabling!\n"); schedule_work(&disable_freq_invariance_work); } -#else -static inline void init_freq_invariance(bool secondary, bool cppc_ready) -{ -} #endif /* CONFIG_X86_64 */ From eb5616d4adeebf958a42822ee440d79e9f803bf7 Mon Sep 17 00:00:00 2001 From: Huang Rui Date: Mon, 14 Feb 2022 18:14:50 +0800 Subject: [PATCH 11/13] x86/ACPI: CPPC: Move init_freq_invariance_cppc() into x86 CPPC The init_freq_invariance_cppc code actually doesn't need the SMP functionality. So setting the CONFIG_SMP as the check condition for init_freq_invariance_cppc may cause the confusion to misunderstand the CPPC. And the x86 CPPC file is better space to store the CPPC related functions, while the init_freq_invariance_cppc is out of smpboot, that means, the CONFIG_SMP won't be mandatory condition any more. And It's more clear than before. Signed-off-by: Huang Rui [ rjw: Subject adjustment ] Signed-off-by: Rafael J. Wysocki --- arch/x86/include/asm/topology.h | 4 +--- arch/x86/kernel/acpi/cppc.c | 14 ++++++++++++++ arch/x86/kernel/smpboot.c | 20 -------------------- 3 files changed, 15 insertions(+), 23 deletions(-) diff --git a/arch/x86/include/asm/topology.h b/arch/x86/include/asm/topology.h index c35005a03768..9c73d62f7276 100644 --- a/arch/x86/include/asm/topology.h +++ b/arch/x86/include/asm/topology.h @@ -225,12 +225,10 @@ static inline void init_freq_invariance(bool secondary, bool cppc_ready) } #endif -#if defined(CONFIG_ACPI_CPPC_LIB) && defined(CONFIG_SMP) +#ifdef CONFIG_ACPI_CPPC_LIB void init_freq_invariance_cppc(void); #define init_freq_invariance_cppc init_freq_invariance_cppc -#endif -#ifdef CONFIG_ACPI_CPPC_LIB bool amd_set_max_freq_ratio(u64 *ratio); #else static inline bool amd_set_max_freq_ratio(u64 *ratio) diff --git a/arch/x86/kernel/acpi/cppc.c b/arch/x86/kernel/acpi/cppc.c index f0be5058e3e3..df1644d9b3b6 100644 --- a/arch/x86/kernel/acpi/cppc.c +++ b/arch/x86/kernel/acpi/cppc.c @@ -87,3 +87,17 @@ bool amd_set_max_freq_ratio(u64 *ratio) return true; } + +static DEFINE_MUTEX(freq_invariance_lock); + +void init_freq_invariance_cppc(void) +{ + static bool secondary; + + mutex_lock(&freq_invariance_lock); + + init_freq_invariance(secondary, true); + secondary = true; + + mutex_unlock(&freq_invariance_lock); +} diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index 8f2ff9be0fcc..2ef14772dc04 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c @@ -83,10 +83,6 @@ #include #include -#ifdef CONFIG_ACPI_CPPC_LIB -#include -#endif - /* representing HT siblings of each logical CPU */ DEFINE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_sibling_map); EXPORT_PER_CPU_SYMBOL(cpu_sibling_map); @@ -2156,22 +2152,6 @@ void init_freq_invariance(bool secondary, bool cppc_ready) } } -#ifdef CONFIG_ACPI_CPPC_LIB -static DEFINE_MUTEX(freq_invariance_lock); - -void init_freq_invariance_cppc(void) -{ - static bool secondary; - - mutex_lock(&freq_invariance_lock); - - init_freq_invariance(secondary, true); - secondary = true; - - mutex_unlock(&freq_invariance_lock); -} -#endif - static void disable_freq_invariance_workfn(struct work_struct *work) { static_branch_disable(&arch_scale_freq_key); From e702196bf85778f2c5527ca47f33ef2e2fca8297 Mon Sep 17 00:00:00 2001 From: Mark Cilissen Date: Mon, 7 Mar 2022 04:16:58 +0100 Subject: [PATCH 12/13] ACPI / x86: Work around broken XSDT on Advantech DAC-BJ01 board On this board the ACPI RSDP structure points to both a RSDT and an XSDT, but the XSDT points to a truncated FADT. This causes all sorts of trouble and usually a complete failure to boot after the following error occurs: ACPI Error: Unsupported address space: 0x20 (*/hwregs-*) ACPI Error: AE_SUPPORT, Unable to initialize fixed events (*/evevent-*) ACPI: Unable to start ACPI Interpreter This leaves the ACPI implementation in such a broken state that subsequent kernel subsystem initialisations go wrong, resulting in among others mismapped PCI memory, SATA and USB enumeration failures, and freezes. As this is an older embedded platform that will likely never see any BIOS updates to address this issue and its default shipping OS only complies to ACPI 1.0, work around this by forcing `acpi=rsdt`. This patch, applied on top of Linux 5.10.102, was confirmed on real hardware to fix the issue. Signed-off-by: Mark Cilissen Cc: All applicable Reviewed-by: Hans de Goede Signed-off-by: Rafael J. Wysocki --- arch/x86/kernel/acpi/boot.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index 5b6d1a95776f..0d01e7f5078c 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c @@ -1328,6 +1328,17 @@ static int __init disable_acpi_pci(const struct dmi_system_id *d) return 0; } +static int __init disable_acpi_xsdt(const struct dmi_system_id *d) +{ + if (!acpi_force) { + pr_notice("%s detected: force use of acpi=rsdt\n", d->ident); + acpi_gbl_do_not_use_xsdt = TRUE; + } else { + pr_notice("Warning: DMI blacklist says broken, but acpi XSDT forced\n"); + } + return 0; +} + static int __init dmi_disable_acpi(const struct dmi_system_id *d) { if (!acpi_force) { @@ -1451,6 +1462,19 @@ static const struct dmi_system_id acpi_dmi_table[] __initconst = { DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"), }, }, + /* + * Boxes that need ACPI XSDT use disabled due to corrupted tables + */ + { + .callback = disable_acpi_xsdt, + .ident = "Advantech DAC-BJ01", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "NEC"), + DMI_MATCH(DMI_PRODUCT_NAME, "Bearlake CRB Board"), + DMI_MATCH(DMI_BIOS_VERSION, "V1.12"), + DMI_MATCH(DMI_BIOS_DATE, "02/01/2011"), + }, + }, {} }; From 6a861abceecb68497dd82a324fee45a5332dcece Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Thu, 17 Mar 2022 08:39:39 -0700 Subject: [PATCH 13/13] clocksource: acpi_pm: fix return value of __setup handler __setup() handlers should return 1 to obsolete_checksetup() in init/main.c to indicate that the boot option has been handled. A return of 0 causes the boot option/value to be listed as an Unknown kernel parameter and added to init's (limited) environment strings. The __setup() handler interface isn't meant to handle negative return values -- they are non-zero, so they mean "handled" (like a return value of 1 does), but that's just a quirk. So return 1 from parse_pmtmr(). Also print a warning message if kstrtouint() returns an error. Fixes: 6b148507d3d0 ("pmtmr: allow command line override of ioport") Signed-off-by: Randy Dunlap Reported-by: Igor Zhbanov Link: lore.kernel.org/r/64644a2f-4a20-bab3-1e15-3b2cdd0defe3@omprussia.ru Signed-off-by: Rafael J. Wysocki --- drivers/clocksource/acpi_pm.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/clocksource/acpi_pm.c b/drivers/clocksource/acpi_pm.c index eb596ff9e7bb..279ddff81ab4 100644 --- a/drivers/clocksource/acpi_pm.c +++ b/drivers/clocksource/acpi_pm.c @@ -229,8 +229,10 @@ static int __init parse_pmtmr(char *arg) int ret; ret = kstrtouint(arg, 16, &base); - if (ret) - return ret; + if (ret) { + pr_warn("PMTMR: invalid 'pmtmr=' value: '%s'\n", arg); + return 1; + } pr_info("PMTMR IOPort override: 0x%04x -> 0x%04x\n", pmtmr_ioport, base);