diff options
author | Dan Williams <dan.j.williams@intel.com> | 2021-10-29 12:51:42 -0700 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2021-11-15 11:02:59 -0800 |
commit | 2d03e46a4bad20191d07b83ec1242d5f002577be (patch) | |
tree | b94e5a3cf03ea39aad703d73cdb400d2380c90e9 /drivers/acpi/tables.c | |
parent | ad2f63971e9655e3987db32dac85aa50658790eb (diff) |
ACPI: Add a context argument for table parsing handlers
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>
Diffstat (limited to 'drivers/acpi/tables.c')
-rw-r--r-- | drivers/acpi/tables.c | 51 |
1 files changed, 44 insertions, 7 deletions
diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c index 8d052b65f6bc..e9bdbb6fbc36 100644 --- a/drivers/acpi/tables.c +++ b/drivers/acpi/tables.c @@ -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) { |