ACPI: Add a context argument for table parsing handlers
authorDan Williams <dan.j.williams@intel.com>
Fri, 29 Oct 2021 19:51:42 +0000 (12:51 -0700)
committerDan Williams <dan.j.williams@intel.com>
Mon, 15 Nov 2021 19:02:59 +0000 (11:02 -0800)
In preparation for drivers reusing the core table parsing
infrastructure, arrange for handlers to take a context argument. This
allows driver table parsing to wrap ACPI table entries in
driver-specific data.

The first consumer of this infrastructure is the CEDT parsing that
happens in the cxl_acpi driver, add a conditional
(CONFIG_ACPI_TABLE_LIB=y) export of a acpi_table_parse_cedt() helper for
this case.

Cc: "Rafael J. Wysocki" <rafael@kernel.org>
Cc: Len Brown <lenb@kernel.org>
Tested-by: Alison Schofield <alison.schofield@intel.com>
Reviewed-by: Alison Schofield <alison.schofield@intel.com>
Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Link: https://lore.kernel.org/r/163553710257.2509508.14310494417463866020.stgit@dwillia2-desk3.amr.corp.intel.com
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
drivers/acpi/tables.c
include/linux/acpi.h

index 8d052b65f6bc1cdf6e0e0e6f07e4454a9b60d5eb..e9bdbb6fbc36bc9702f012928953b7e2b7d37923 100644 (file)
@@ -277,6 +277,22 @@ acpi_get_subtable_type(char *id)
        return ACPI_SUBTABLE_COMMON;
 }
 
+static __init_or_acpilib bool has_handler(struct acpi_subtable_proc *proc)
+{
+       return proc->handler || proc->handler_arg;
+}
+
+static __init_or_acpilib int call_handler(struct acpi_subtable_proc *proc,
+                                         union acpi_subtable_headers *hdr,
+                                         unsigned long end)
+{
+       if (proc->handler)
+               return proc->handler(hdr, end);
+       if (proc->handler_arg)
+               return proc->handler_arg(hdr, proc->arg, end);
+       return -EINVAL;
+}
+
 /**
  * acpi_parse_entries_array - for each proc_num find a suitable subtable
  *
@@ -327,8 +343,9 @@ static int __init_or_acpilib acpi_parse_entries_array(
                for (i = 0; i < proc_num; i++) {
                        if (acpi_get_entry_type(&entry) != proc[i].id)
                                continue;
-                       if (!proc[i].handler ||
-                            (!errs && proc[i].handler(entry.hdr, table_end))) {
+                       if (!has_handler(&proc[i]) ||
+                           (!errs &&
+                            call_handler(&proc[i], entry.hdr, table_end))) {
                                errs++;
                                continue;
                        }
@@ -394,21 +411,41 @@ int __init_or_acpilib acpi_table_parse_entries_array(
        return count;
 }
 
-int __init acpi_table_parse_entries(char *id,
-                       unsigned long table_size,
-                       int entry_id,
-                       acpi_tbl_entry_handler handler,
-                       unsigned int max_entries)
+static int __init_or_acpilib __acpi_table_parse_entries(
+       char *id, unsigned long table_size, int entry_id,
+       acpi_tbl_entry_handler handler, acpi_tbl_entry_handler_arg handler_arg,
+       void *arg, unsigned int max_entries)
 {
        struct acpi_subtable_proc proc = {
                .id             = entry_id,
                .handler        = handler,
+               .handler_arg    = handler_arg,
+               .arg            = arg,
        };
 
        return acpi_table_parse_entries_array(id, table_size, &proc, 1,
                                                max_entries);
 }
 
+int __init_or_acpilib
+acpi_table_parse_cedt(enum acpi_cedt_type id,
+                     acpi_tbl_entry_handler_arg handler_arg, void *arg)
+{
+       return __acpi_table_parse_entries(ACPI_SIG_CEDT,
+                                         sizeof(struct acpi_table_cedt), id,
+                                         NULL, handler_arg, arg, 0);
+}
+EXPORT_SYMBOL_ACPI_LIB(acpi_table_parse_cedt);
+
+int __init acpi_table_parse_entries(char *id, unsigned long table_size,
+                                   int entry_id,
+                                   acpi_tbl_entry_handler handler,
+                                   unsigned int max_entries)
+{
+       return __acpi_table_parse_entries(id, table_size, entry_id, handler,
+                                         NULL, NULL, max_entries);
+}
+
 int __init acpi_table_parse_madt(enum acpi_madt_type id,
                      acpi_tbl_entry_handler handler, unsigned int max_entries)
 {
index 6b7f181d51e235ef8c9666fc84e0f110b91d1392..95f88108f664ef079aa5c295cc4bdf8d9a182eb6 100644 (file)
@@ -141,6 +141,9 @@ typedef int (*acpi_tbl_table_handler)(struct acpi_table_header *table);
 typedef int (*acpi_tbl_entry_handler)(union acpi_subtable_headers *header,
                                      const unsigned long end);
 
+typedef int (*acpi_tbl_entry_handler_arg)(union acpi_subtable_headers *header,
+                                         void *arg, const unsigned long end);
+
 /* Debugger support */
 
 struct acpi_debugger_ops {
@@ -217,6 +220,8 @@ static inline int acpi_debugger_notify_command_complete(void)
 struct acpi_subtable_proc {
        int id;
        acpi_tbl_entry_handler handler;
+       acpi_tbl_entry_handler_arg handler_arg;
+       void *arg;
        int count;
 };
 
@@ -235,9 +240,11 @@ void acpi_table_init_complete (void);
 int acpi_table_init (void);
 
 #ifdef CONFIG_ACPI_TABLE_LIB
+#define EXPORT_SYMBOL_ACPI_LIB(x) EXPORT_SYMBOL_NS_GPL(x, ACPI)
 #define __init_or_acpilib
 #define __initdata_or_acpilib
 #else
+#define EXPORT_SYMBOL_ACPI_LIB(x)
 #define __init_or_acpilib __init
 #define __initdata_or_acpilib __initdata
 #endif
@@ -252,6 +259,10 @@ int __init_or_acpilib acpi_table_parse_entries_array(char *id,
 int acpi_table_parse_madt(enum acpi_madt_type id,
                          acpi_tbl_entry_handler handler,
                          unsigned int max_entries);
+int __init_or_acpilib
+acpi_table_parse_cedt(enum acpi_cedt_type id,
+                     acpi_tbl_entry_handler_arg handler_arg, void *arg);
+
 int acpi_parse_mcfg (struct acpi_table_header *header);
 void acpi_table_print_madt_entry (struct acpi_subtable_header *madt);