diff options
Diffstat (limited to 'drivers/acpi')
-rw-r--r-- | drivers/acpi/executer/exconfig.c | 29 | ||||
-rw-r--r-- | drivers/acpi/tables/tbxface.c | 89 | ||||
-rw-r--r-- | drivers/acpi/utilities/utglobal.c | 3 |
3 files changed, 119 insertions, 2 deletions
diff --git a/drivers/acpi/executer/exconfig.c b/drivers/acpi/executer/exconfig.c index 25802f302ff..009aef5fcbf 100644 --- a/drivers/acpi/executer/exconfig.c +++ b/drivers/acpi/executer/exconfig.c @@ -234,6 +234,13 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state, table->oem_table_id)); } + /* Invoke table handler if present */ + + if (acpi_gbl_table_handler) { + (void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_LOAD, table, + acpi_gbl_table_handler_context); + } + *return_desc = ddb_handle; return_ACPI_STATUS(status); } @@ -352,6 +359,14 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, return_ACPI_STATUS(status); } + /* Invoke table handler if present */ + + if (acpi_gbl_table_handler) { + (void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_LOAD, + table_desc.pointer, + acpi_gbl_table_handler_context); + } + cleanup: if (ACPI_FAILURE(status)) { acpi_tb_delete_table(&table_desc); @@ -376,6 +391,7 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle) acpi_status status = AE_OK; union acpi_operand_object *table_desc = ddb_handle; acpi_native_uint table_index; + struct acpi_table_header *table; ACPI_FUNCTION_TRACE(ex_unload_table); @@ -395,6 +411,17 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle) table_index = (acpi_native_uint) table_desc->reference.object; + /* Invoke table handler if present */ + + if (acpi_gbl_table_handler) { + status = acpi_get_table_by_index(table_index, &table); + if (ACPI_SUCCESS(status)) { + (void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_UNLOAD, + table, + acpi_gbl_table_handler_context); + } + } + /* * Delete the entire namespace under this table Node * (Offset contains the table_id) @@ -407,5 +434,5 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle) /* Delete the table descriptor (ddb_handle) */ acpi_ut_remove_reference(table_desc); - return_ACPI_STATUS(status); + return_ACPI_STATUS(AE_OK); } diff --git a/drivers/acpi/tables/tbxface.c b/drivers/acpi/tables/tbxface.c index a9e3331fee5..5f2271542a9 100644 --- a/drivers/acpi/tables/tbxface.c +++ b/drivers/acpi/tables/tbxface.c @@ -635,6 +635,95 @@ acpi_status acpi_load_tables(void) ACPI_EXPORT_SYMBOL(acpi_load_tables) +/******************************************************************************* + * + * FUNCTION: acpi_install_table_handler + * + * PARAMETERS: Handler - Table event handler + * Context - Value passed to the handler on each event + * + * RETURN: Status + * + * DESCRIPTION: Install table event handler + * + ******************************************************************************/ +acpi_status +acpi_install_table_handler(acpi_tbl_handler handler, void *context) +{ + acpi_status status; + + ACPI_FUNCTION_TRACE(acpi_install_table_handler); + + if (!handler) { + return_ACPI_STATUS(AE_BAD_PARAMETER); + } + + status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + + /* Don't allow more than one handler */ + + if (acpi_gbl_table_handler) { + status = AE_ALREADY_EXISTS; + goto cleanup; + } + + /* Install the handler */ + + acpi_gbl_table_handler = handler; + acpi_gbl_table_handler_context = context; + + cleanup: + (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); + return_ACPI_STATUS(status); +} + +ACPI_EXPORT_SYMBOL(acpi_install_table_handler) + +/******************************************************************************* + * + * FUNCTION: acpi_remove_table_handler + * + * PARAMETERS: Handler - Table event handler that was installed + * previously. + * + * RETURN: Status + * + * DESCRIPTION: Remove table event handler + * + ******************************************************************************/ +acpi_status acpi_remove_table_handler(acpi_tbl_handler handler) +{ + acpi_status status; + + ACPI_FUNCTION_TRACE(acpi_remove_table_handler); + + status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + + /* Make sure that the installed handler is the same */ + + if (!handler || handler != acpi_gbl_table_handler) { + status = AE_BAD_PARAMETER; + goto cleanup; + } + + /* Remove the handler */ + + acpi_gbl_table_handler = NULL; + + cleanup: + (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); + return_ACPI_STATUS(status); +} + +ACPI_EXPORT_SYMBOL(acpi_remove_table_handler) + + static int __init acpi_no_auto_ssdt_setup(char *s) { printk(KERN_NOTICE "ACPI: SSDT auto-load disabled\n"); diff --git a/drivers/acpi/utilities/utglobal.c b/drivers/acpi/utilities/utglobal.c index 630c9a2c5b7..44425433075 100644 --- a/drivers/acpi/utilities/utglobal.c +++ b/drivers/acpi/utilities/utglobal.c @@ -675,12 +675,13 @@ void acpi_ut_init_globals(void) acpi_gbl_gpe_fadt_blocks[0] = NULL; acpi_gbl_gpe_fadt_blocks[1] = NULL; - /* Global notify handlers */ + /* Global handlers */ acpi_gbl_system_notify.handler = NULL; acpi_gbl_device_notify.handler = NULL; acpi_gbl_exception_handler = NULL; acpi_gbl_init_handler = NULL; + acpi_gbl_table_handler = NULL; /* Global Lock support */ |