Skip to content

Commit 5621faf

Browse files
benhartcheathamdjbw
authored andcommitted
EINJ: Migrate to a platform driver
Change the EINJ module to install a platform device/driver on module init and move the module init() and exit() functions to driver probe and remove. This change allows the EINJ module to load regardless of whether setting up EINJ succeeds, which allows dependent modules to still load (i.e. the CXL core). Since EINJ may no longer be initialized when the module loads, any functions that are called from dependent/external modules should safegaurd against the case EINJ didn't load. Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> Reviewed-by: Dan Williams <dan.j.williams@intel.com> Signed-off-by: Ben Cheatham <Benjamin.Cheatham@amd.com> Link: https://lore.kernel.org/r/20240311142508.31717-2-Benjamin.Cheatham@amd.com Signed-off-by: Dan Williams <dan.j.williams@intel.com>
1 parent d206a76 commit 5621faf

File tree

1 file changed

+44
-4
lines changed

1 file changed

+44
-4
lines changed

drivers/acpi/apei/einj.c

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <linux/nmi.h>
2222
#include <linux/delay.h>
2323
#include <linux/mm.h>
24+
#include <linux/platform_device.h>
2425
#include <asm/unaligned.h>
2526

2627
#include "apei-internal.h"
@@ -137,6 +138,11 @@ static struct apei_exec_ins_type einj_ins_type[] = {
137138
*/
138139
static DEFINE_MUTEX(einj_mutex);
139140

141+
/*
142+
* Exported APIs use this flag to exit early if einj_probe() failed.
143+
*/
144+
static bool einj_initialized __ro_after_init;
145+
140146
static void *einj_param;
141147

142148
static void einj_exec_ctx_init(struct apei_exec_context *ctx)
@@ -703,21 +709,21 @@ static int einj_check_table(struct acpi_table_einj *einj_tab)
703709
return 0;
704710
}
705711

706-
static int __init einj_init(void)
712+
static int __init einj_probe(struct platform_device *pdev)
707713
{
708714
int rc;
709715
acpi_status status;
710716
struct apei_exec_context ctx;
711717

712718
if (acpi_disabled) {
713-
pr_info("ACPI disabled.\n");
719+
pr_debug("ACPI disabled.\n");
714720
return -ENODEV;
715721
}
716722

717723
status = acpi_get_table(ACPI_SIG_EINJ, 0,
718724
(struct acpi_table_header **)&einj_tab);
719725
if (status == AE_NOT_FOUND) {
720-
pr_warn("EINJ table not found.\n");
726+
pr_debug("EINJ table not found.\n");
721727
return -ENODEV;
722728
} else if (ACPI_FAILURE(status)) {
723729
pr_err("Failed to get EINJ table: %s\n",
@@ -805,7 +811,7 @@ static int __init einj_init(void)
805811
return rc;
806812
}
807813

808-
static void __exit einj_exit(void)
814+
static void __exit einj_remove(struct platform_device *pdev)
809815
{
810816
struct apei_exec_context ctx;
811817

@@ -826,6 +832,40 @@ static void __exit einj_exit(void)
826832
acpi_put_table((struct acpi_table_header *)einj_tab);
827833
}
828834

835+
static struct platform_device *einj_dev;
836+
static struct platform_driver einj_driver = {
837+
.remove_new = einj_remove,
838+
.driver = {
839+
.name = "acpi-einj",
840+
},
841+
};
842+
843+
static int __init einj_init(void)
844+
{
845+
struct platform_device_info einj_dev_info = {
846+
.name = "acpi-einj",
847+
.id = -1,
848+
};
849+
int rc;
850+
851+
einj_dev = platform_device_register_full(&einj_dev_info);
852+
if (IS_ERR(einj_dev))
853+
return PTR_ERR(einj_dev);
854+
855+
rc = platform_driver_probe(&einj_driver, einj_probe);
856+
einj_initialized = rc == 0;
857+
858+
return 0;
859+
}
860+
861+
static void __exit einj_exit(void)
862+
{
863+
if (einj_initialized)
864+
platform_driver_unregister(&einj_driver);
865+
866+
platform_device_del(einj_dev);
867+
}
868+
829869
module_init(einj_init);
830870
module_exit(einj_exit);
831871

0 commit comments

Comments
 (0)