ACPI for Arm Components 1.1 Platform Design Document v1.1 [0] specifices Arm Generic Diagnostic Device Interface (AGDI). It allows an admin to issue diagnostic dump and reset via an SDEI event or an interrupt. This patch implements SDEI path. [0] https://developer.arm.com/documentation/den0093/latest/ Signed-off-by: Ilkka Koskinen <ilkka@xxxxxxxxxxxxxxxxxxxxxx> --- drivers/acpi/arm64/Kconfig | 10 +++++++ drivers/acpi/arm64/Makefile | 1 + drivers/acpi/arm64/agdi.c | 52 +++++++++++++++++++++++++++++++++++++ drivers/acpi/bus.c | 2 ++ include/linux/acpi_agdi.h | 13 ++++++++++ 5 files changed, 78 insertions(+) create mode 100644 drivers/acpi/arm64/agdi.c create mode 100644 include/linux/acpi_agdi.h diff --git a/drivers/acpi/arm64/Kconfig b/drivers/acpi/arm64/Kconfig index 6dba187f4f2e..d4a72835f328 100644 --- a/drivers/acpi/arm64/Kconfig +++ b/drivers/acpi/arm64/Kconfig @@ -8,3 +8,13 @@ config ACPI_IORT config ACPI_GTDT bool + +config ACPI_AGDI + bool "Arm Generic Diagnostic Dump and Reset Device Interface" + depends on ARM_SDE_INTERFACE + help + Arm Generic Diagnostic Dump and Reset Device Interface (AGDI) is + a standard that enables issuing a non-maskable diagnostic dump and + reset command. + + If set, the kernel parses AGDI table and listens for the command. diff --git a/drivers/acpi/arm64/Makefile b/drivers/acpi/arm64/Makefile index 66acbe77f46e..7b9e4045659d 100644 --- a/drivers/acpi/arm64/Makefile +++ b/drivers/acpi/arm64/Makefile @@ -1,4 +1,5 @@ # SPDX-License-Identifier: GPL-2.0-only +obj-$(CONFIG_ACPI_AGDI) += agdi.o obj-$(CONFIG_ACPI_IORT) += iort.o obj-$(CONFIG_ACPI_GTDT) += gtdt.o obj-y += dma.o diff --git a/drivers/acpi/arm64/agdi.c b/drivers/acpi/arm64/agdi.c new file mode 100644 index 000000000000..28916650d834 --- /dev/null +++ b/drivers/acpi/arm64/agdi.c @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * This file implements handling of + * Arm Generic Diagnostic Dump and Reset Interface table (AGDI) + * + * Copyright (c) 2022, Ampere Computing LLC + */ + +#define pr_fmt(fmt) "ACPI: AGDI: " fmt + +#include <linux/acpi.h> +#include <linux/arm_sdei.h> +#include <linux/io.h> +#include <linux/kernel.h> + +static int agdi_sdei_handler(u32 sdei_event, struct pt_regs *regs, void *arg) +{ + nmi_panic(regs, "Arm Generic Diagnostic Dump and Reset SDEI event issued"); + return 0; +} + +void __init acpi_agdi_init(void) +{ + struct acpi_table_agdi *agdi_table; + acpi_status status; + int sdei_event; + + status = acpi_get_table(ACPI_SIG_AGDI, 0, + (struct acpi_table_header **) &agdi_table); + if (ACPI_FAILURE(status)) + return; + + if (agdi_table->flags & ACPI_AGDI_SIGNALING_MODE) { + pr_warn("Interrupt signaling is not supported"); + acpi_put_table((struct acpi_table_header *)agdi_table); + return; + } + + sdei_event = agdi_table->sdei_event; + acpi_put_table((struct acpi_table_header *)agdi_table); + + if (sdei_event_register(sdei_event, agdi_sdei_handler, NULL)) { + pr_err("Failed to register for SDEI event %d", sdei_event); + return; + } + + if (sdei_event_enable(sdei_event)) { + pr_err("Failed to enable SDEI event %d\n", sdei_event); + sdei_event_unregister(sdei_event); + return; + } +} diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index eaa511fc9c66..87b93f4df0cf 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -26,6 +26,7 @@ #include <asm/mpspec.h> #include <linux/dmi.h> #endif +#include <linux/acpi_agdi.h> #include <linux/acpi_iort.h> #include <linux/acpi_viot.h> #include <linux/pci.h> @@ -1386,6 +1387,7 @@ static int __init acpi_init(void) acpi_debugger_init(); acpi_setup_sb_notify_handler(); acpi_viot_init(); + acpi_agdi_init(); return 0; } diff --git a/include/linux/acpi_agdi.h b/include/linux/acpi_agdi.h new file mode 100644 index 000000000000..f477f0b452fa --- /dev/null +++ b/include/linux/acpi_agdi.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef __ACPI_AGDI_H__ +#define __ACPI_AGDI_H__ + +#include <linux/acpi.h> + +#ifdef CONFIG_ACPI_AGDI +void __init acpi_agdi_init(void); +#else +static inline void acpi_agdi_init(void) {} +#endif +#endif /* __ACPI_AGDI_H__ */ -- 2.17.1