diff options
| author | Zhang Rui <rui.zhang@intel.com> | 2009-02-26 11:27:23 +0800 | 
|---|---|---|
| committer | Len Brown <len.brown@intel.com> | 2009-02-26 01:03:15 -0500 | 
| commit | 4658e4ef9d252c26630268b20ceab78b3952db41 (patch) | |
| tree | 7dc5bc5f546de3e311eb7752d0e7917e0c88076c /drivers/acpi/system.c | |
| parent | c15d8a6499d04e5d2cac07f8120f207bb275f60f (diff) | |
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>
Diffstat (limited to 'drivers/acpi/system.c')
| -rw-r--r-- | drivers/acpi/system.c | 51 | 
1 files changed, 48 insertions, 3 deletions
diff --git a/drivers/acpi/system.c b/drivers/acpi/system.c index 391d0358a592..c8859047acfe 100644 --- a/drivers/acpi/system.c +++ b/drivers/acpi/system.c @@ -62,6 +62,7 @@ module_param_call(acpica_version, NULL, param_get_acpica_version, NULL, 0444);     -------------------------------------------------------------------------- */  static LIST_HEAD(acpi_table_attr_list);  static struct kobject *tables_kobj; +static struct kobject *dynamic_tables_kobj;  struct acpi_table_attr {  	struct bin_attribute attr; @@ -128,6 +129,40 @@ static void acpi_table_attr_init(struct acpi_table_attr *table_attr,  	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)  {  	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);  	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 {  		result = acpi_get_table_by_index(table_index, &table_header); @@ -162,8 +201,14 @@ static int acpi_system_sysfs_init(void)  		}  	} while (!result);  	kobject_uevent(tables_kobj, KOBJ_ADD); - -	return 0; +	kobject_uevent(dynamic_tables_kobj, KOBJ_ADD); +	result = acpi_install_table_handler(acpi_sysfs_table_handler, NULL); + +	return result == AE_OK ? 0 : -EINVAL; +err_dynamic_tables: +	kobject_put(tables_kobj); +err: +	return -ENOMEM;  }  /*  | 
