Skip to content

Commit

Permalink
ACPI: Add a context argument for table parsing handlers
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Dan Williams committed Nov 15, 2021
1 parent ad2f639 commit 2d03e46
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 7 deletions.
51 changes: 44 additions & 7 deletions drivers/acpi/tables.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
*
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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)
{
Expand Down
11 changes: 11 additions & 0 deletions include/linux/acpi.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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;
};

Expand All @@ -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
Expand All @@ -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);

Expand Down

0 comments on commit 2d03e46

Please sign in to comment.