linux/debian/patches/bugfix/arm64/arm64-acpi-Add-fixup-for-HP...

93 lines
2.8 KiB
Diff

From: Geoff Levand <geoff@infradead.org>
Date: Wed, 13 Jun 2018 10:56:08 -0700
Subject: arm64/acpi: Add fixup for HPE m400 quirks
Forwarded: https://patchwork.codeaurora.org/patch/547277/
Adds a new ACPI init routine acpi_fixup_m400_quirks that adds
a work-around for HPE ProLiant m400 APEI firmware problems.
The work-around disables APEI when CONFIG_ACPI_APEI is set and
m400 firmware is detected. Without this fixup m400 systems
experience errors like these on startup:
[Hardware Error]: Hardware error from APEI Generic Hardware Error Source: 2
[Hardware Error]: event severity: fatal
[Hardware Error]: Error 0, type: fatal
[Hardware Error]: section_type: memory error
[Hardware Error]: error_status: 0x0000000000001300
[Hardware Error]: error_type: 10, invalid address
Kernel panic - not syncing: Fatal hardware error!
Signed-off-by: Geoff Levand <geoff@infradead.org>
[bwh: Adjust context to apply to Linux 4.19]
---
arch/arm64/kernel/acpi.c | 40 ++++++++++++++++++++++++++++++++++++----
1 file changed, 36 insertions(+), 4 deletions(-)
Index: linux/arch/arm64/kernel/acpi.c
===================================================================
--- linux.orig/arch/arm64/kernel/acpi.c
+++ linux/arch/arm64/kernel/acpi.c
@@ -33,6 +33,8 @@
#include <asm/pgtable.h>
#include <asm/smp_plat.h>
+#include <acpi/apei.h>
+
int acpi_noirq = 1; /* skip ACPI IRQ initialization */
int acpi_disabled = 1;
EXPORT_SYMBOL(acpi_disabled);
@@ -179,6 +181,33 @@ out:
}
/*
+ * acpi_fixup_m400_quirks - Work-around for HPE ProLiant m400 APEI firmware
+ * problems.
+ */
+static void __init acpi_fixup_m400_quirks(void)
+{
+ acpi_status status;
+ struct acpi_table_header *header;
+#if !defined(CONFIG_ACPI_APEI)
+ int hest_disable = HEST_DISABLED;
+#endif
+
+ if (!IS_ENABLED(CONFIG_ACPI_APEI) || hest_disable != HEST_ENABLED)
+ return;
+
+ status = acpi_get_table(ACPI_SIG_HEST, 0, &header);
+
+ if (ACPI_SUCCESS(status) && !strncmp(header->oem_id, "HPE ", 6) &&
+ !strncmp(header->oem_table_id, "ProLiant", 8) &&
+ MIDR_IMPLEMENTOR(read_cpuid_id()) == ARM_CPU_IMP_APM) {
+ hest_disable = HEST_DISABLED;
+ pr_info("Disabled APEI for m400.\n");
+ }
+
+ acpi_put_table(header);
+}
+
+/*
* acpi_boot_table_init() called from setup_arch(), always.
* 1. find RSDP and get its address, and then find XSDT
* 2. extract all tables and checksums them all
@@ -233,11 +262,14 @@ done:
if (acpi_disabled) {
if (earlycon_acpi_spcr_enable)
early_init_dt_scan_chosen_stdout();
- } else {
- acpi_parse_spcr(earlycon_acpi_spcr_enable, true);
- if (IS_ENABLED(CONFIG_ACPI_BGRT))
- acpi_table_parse(ACPI_SIG_BGRT, acpi_parse_bgrt);
+ return;
}
+
+ acpi_parse_spcr(earlycon_acpi_spcr_enable, true);
+ if (IS_ENABLED(CONFIG_ACPI_BGRT))
+ acpi_table_parse(ACPI_SIG_BGRT, acpi_parse_bgrt);
+
+ acpi_fixup_m400_quirks();
}
pgprot_t __acpi_get_mem_attribute(phys_addr_t addr)