Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ACPI: APEI: explicit init of HEST and GHES in apci_init()

From commit e147133a42cb ("ACPI / APEI: Make hest.c manage the estatus
memory pool") was merged, ghes_init() relies on acpi_hest_init() to manage
the estatus memory pool. On the other hand, ghes_init() relies on
sdei_init() to detect the SDEI version and (un)register events. The
dependencies are as follows:

ghes_init() => acpi_hest_init() => acpi_bus_init() => acpi_init()
ghes_init() => sdei_init()

HEST is not PCI-specific and initcall ordering is implicit and not
well-defined within a level.

Based on above, remove acpi_hest_init() from acpi_pci_root_init() and
convert ghes_init() and sdei_init() from initcalls to explicit calls in the
following order:

acpi_hest_init()
ghes_init()
sdei_init()

Signed-off-by: Shuai Xue <xueshuai@linux.alibaba.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

authored by

Shuai Xue and committed by
Rafael J. Wysocki
dc4e8c07 7e57714c

+18 -26
+8 -11
drivers/acpi/apei/ghes.c
··· 1457 1457 .remove = ghes_remove, 1458 1458 }; 1459 1459 1460 - static int __init ghes_init(void) 1460 + void __init ghes_init(void) 1461 1461 { 1462 1462 int rc; 1463 1463 1464 + sdei_init(); 1465 + 1464 1466 if (acpi_disabled) 1465 - return -ENODEV; 1467 + return; 1466 1468 1467 1469 switch (hest_disable) { 1468 1470 case HEST_NOT_FOUND: 1469 - return -ENODEV; 1471 + return; 1470 1472 case HEST_DISABLED: 1471 1473 pr_info(GHES_PFX "HEST is not enabled!\n"); 1472 - return -EINVAL; 1474 + return; 1473 1475 default: 1474 1476 break; 1475 1477 } 1476 1478 1477 1479 if (ghes_disable) { 1478 1480 pr_info(GHES_PFX "GHES is not enabled!\n"); 1479 - return -EINVAL; 1481 + return; 1480 1482 } 1481 1483 1482 1484 ghes_nmi_init_cxt(); 1483 1485 1484 1486 rc = platform_driver_register(&ghes_platform_driver); 1485 1487 if (rc) 1486 - goto err; 1488 + return; 1487 1489 1488 1490 rc = apei_osc_setup(); 1489 1491 if (rc == 0 && osc_sb_apei_support_acked) ··· 1496 1494 pr_info(GHES_PFX "APEI firmware first mode is enabled by APEI bit.\n"); 1497 1495 else 1498 1496 pr_info(GHES_PFX "Failed to enable APEI firmware first mode.\n"); 1499 - 1500 - return 0; 1501 - err: 1502 - return rc; 1503 1497 } 1504 - device_initcall(ghes_init);
+2
drivers/acpi/bus.c
··· 1331 1331 1332 1332 pci_mmcfg_late_init(); 1333 1333 acpi_iort_init(); 1334 + acpi_hest_init(); 1335 + ghes_init(); 1334 1336 acpi_scan_init(); 1335 1337 acpi_ec_init(); 1336 1338 acpi_debugfs_init();
-3
drivers/acpi/pci_root.c
··· 22 22 #include <linux/slab.h> 23 23 #include <linux/dmi.h> 24 24 #include <linux/platform_data/x86/apple.h> 25 - #include <acpi/apei.h> /* for acpi_hest_init() */ 26 - 27 25 #include "internal.h" 28 26 29 27 #define ACPI_PCI_ROOT_CLASS "pci_bridge" ··· 941 943 942 944 void __init acpi_pci_root_init(void) 943 945 { 944 - acpi_hest_init(); 945 946 if (acpi_pci_disabled) 946 947 return; 947 948
+1
drivers/firmware/Kconfig
··· 40 40 config ARM_SDE_INTERFACE 41 41 bool "ARM Software Delegated Exception Interface (SDEI)" 42 42 depends on ARM64 43 + depends on ACPI_APEI_GHES 43 44 help 44 45 The Software Delegated Exception Interface (SDEI) is an ARM 45 46 standard for registering callbacks from the platform firmware
+2 -11
drivers/firmware/arm_sdei.c
··· 1059 1059 return true; 1060 1060 } 1061 1061 1062 - static int __init sdei_init(void) 1062 + void __init sdei_init(void) 1063 1063 { 1064 1064 struct platform_device *pdev; 1065 1065 int ret; 1066 1066 1067 1067 ret = platform_driver_register(&sdei_driver); 1068 1068 if (ret || !sdei_present_acpi()) 1069 - return ret; 1069 + return; 1070 1070 1071 1071 pdev = platform_device_register_simple(sdei_driver.driver.name, 1072 1072 0, NULL, 0); ··· 1076 1076 pr_info("Failed to register ACPI:SDEI platform device %d\n", 1077 1077 ret); 1078 1078 } 1079 - 1080 - return ret; 1081 1079 } 1082 - 1083 - /* 1084 - * On an ACPI system SDEI needs to be ready before HEST:GHES tries to register 1085 - * its events. ACPI is initialised from a subsys_initcall(), GHES is initialised 1086 - * by device_initcall(). We want to be called in the middle. 1087 - */ 1088 - subsys_initcall_sync(sdei_init); 1089 1080 1090 1081 int sdei_event_handler(struct pt_regs *regs, 1091 1082 struct sdei_registered_event *arg)
+3 -1
include/acpi/apei.h
··· 27 27 extern int erst_disable; 28 28 #ifdef CONFIG_ACPI_APEI_GHES 29 29 extern bool ghes_disable; 30 + void __init ghes_init(void); 30 31 #else 31 32 #define ghes_disable 1 33 + static inline void ghes_init(void) { } 32 34 #endif 33 35 34 36 #ifdef CONFIG_ACPI_APEI 35 37 void __init acpi_hest_init(void); 36 38 #else 37 - static inline void acpi_hest_init(void) { return; } 39 + static inline void acpi_hest_init(void) { } 38 40 #endif 39 41 40 42 int erst_write(const struct cper_record_header *record);
+2
include/linux/arm_sdei.h
··· 46 46 /* For use by arch code when CPU hotplug notifiers are not appropriate. */ 47 47 int sdei_mask_local_cpu(void); 48 48 int sdei_unmask_local_cpu(void); 49 + void __init sdei_init(void); 49 50 #else 50 51 static inline int sdei_mask_local_cpu(void) { return 0; } 51 52 static inline int sdei_unmask_local_cpu(void) { return 0; } 53 + static inline void sdei_init(void) { } 52 54 #endif /* CONFIG_ARM_SDE_INTERFACE */ 53 55 54 56