ACPI: introduce sysfs I/F for dynamic tables
SSDT tables may be loaded at runtime. create sysfs I/F for these dynamic tables in /sys/firmware/acpi/tables/dynamic/. Signed-off-by: Zhang Rui <rui.zhang@intel.com> Signed-off-by: Len Brown <len.brown@intel.com>
This commit is contained in:
@@ -62,6 +62,7 @@ module_param_call(acpica_version, NULL, param_get_acpica_version, NULL, 0444);
|
|||||||
-------------------------------------------------------------------------- */
|
-------------------------------------------------------------------------- */
|
||||||
static LIST_HEAD(acpi_table_attr_list);
|
static LIST_HEAD(acpi_table_attr_list);
|
||||||
static struct kobject *tables_kobj;
|
static struct kobject *tables_kobj;
|
||||||
|
static struct kobject *dynamic_tables_kobj;
|
||||||
|
|
||||||
struct acpi_table_attr {
|
struct acpi_table_attr {
|
||||||
struct bin_attribute attr;
|
struct bin_attribute attr;
|
||||||
@@ -128,6 +129,40 @@ static void acpi_table_attr_init(struct acpi_table_attr *table_attr,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static acpi_status
|
||||||
|
acpi_sysfs_table_handler(u32 event, void *table, void *context)
|
||||||
|
{
|
||||||
|
struct acpi_table_attr *table_attr;
|
||||||
|
|
||||||
|
switch (event) {
|
||||||
|
case ACPI_TABLE_EVENT_LOAD:
|
||||||
|
table_attr =
|
||||||
|
kzalloc(sizeof(struct acpi_table_attr), GFP_KERNEL);
|
||||||
|
if (!table_attr)
|
||||||
|
return AE_NO_MEMORY;
|
||||||
|
|
||||||
|
acpi_table_attr_init(table_attr, table);
|
||||||
|
if (sysfs_create_bin_file(dynamic_tables_kobj,
|
||||||
|
&table_attr->attr)) {
|
||||||
|
kfree(table_attr);
|
||||||
|
return AE_ERROR;
|
||||||
|
} else
|
||||||
|
list_add_tail(&table_attr->node,
|
||||||
|
&acpi_table_attr_list);
|
||||||
|
break;
|
||||||
|
case ACPI_TABLE_EVENT_UNLOAD:
|
||||||
|
/*
|
||||||
|
* we do not need to do anything right now
|
||||||
|
* because the table is not deleted from the
|
||||||
|
* global table list when unloading it.
|
||||||
|
*/
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return AE_BAD_PARAMETER;
|
||||||
|
}
|
||||||
|
return AE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
static int acpi_system_sysfs_init(void)
|
static int acpi_system_sysfs_init(void)
|
||||||
{
|
{
|
||||||
struct acpi_table_attr *table_attr;
|
struct acpi_table_attr *table_attr;
|
||||||
@@ -137,7 +172,11 @@ static int acpi_system_sysfs_init(void)
|
|||||||
|
|
||||||
tables_kobj = kobject_create_and_add("tables", acpi_kobj);
|
tables_kobj = kobject_create_and_add("tables", acpi_kobj);
|
||||||
if (!tables_kobj)
|
if (!tables_kobj)
|
||||||
return -ENOMEM;
|
goto err;
|
||||||
|
|
||||||
|
dynamic_tables_kobj = kobject_create_and_add("dynamic", tables_kobj);
|
||||||
|
if (!dynamic_tables_kobj)
|
||||||
|
goto err_dynamic_tables;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
result = acpi_get_table_by_index(table_index, &table_header);
|
result = acpi_get_table_by_index(table_index, &table_header);
|
||||||
@@ -162,8 +201,14 @@ static int acpi_system_sysfs_init(void)
|
|||||||
}
|
}
|
||||||
} while (!result);
|
} while (!result);
|
||||||
kobject_uevent(tables_kobj, KOBJ_ADD);
|
kobject_uevent(tables_kobj, KOBJ_ADD);
|
||||||
|
kobject_uevent(dynamic_tables_kobj, KOBJ_ADD);
|
||||||
|
result = acpi_install_table_handler(acpi_sysfs_table_handler, NULL);
|
||||||
|
|
||||||
return 0;
|
return result == AE_OK ? 0 : -EINVAL;
|
||||||
|
err_dynamic_tables:
|
||||||
|
kobject_put(tables_kobj);
|
||||||
|
err:
|
||||||
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Reference in New Issue
Block a user