diff options
author | Lin Ming <ming.m.lin@intel.com> | 2010-08-06 05:35:51 +0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2010-10-01 09:47:43 +0400 |
commit | b0ed7a915abac309fcb5a51bccd3782e3daa7417 (patch) | |
tree | 0bffdd098549d61180e6959217c84a05dadb99fa /drivers/acpi/acpica/utxface.c | |
parent | 09387b43153953006471dbb06ece6bf779d10937 (diff) | |
download | linux-b0ed7a915abac309fcb5a51bccd3782e3daa7417.tar.xz |
ACPICA/ACPI: Add new host interfaces for _OSI support
Adds install/remove interfaces so that the host can dynamically
alter the global _OSI table. Also adds support for _OSI handlers.
Additional support: new debugger command (osi), and test support in
the acpiexec utility. Adds new file, utilities/utosi.c.
ACPICA bugzilla 836.
The Linux OSL _OSI code is also changed.
acpi_osi_setup can't call acpi_install/remove_interface because ACPICA
is not initialized yet at this early time.
So we just save the osi string in acpi_osi_setup and will handle it
later in a new function acpi_osi_setup_late.
http://www.acpica.org/bugzilla/show_bug.cgi?id=836
Signed-off-by: Lin Ming <ming.m.lin@intel.com>
Signed-off-by: Bob Moore <robert.moore@intel.com
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/acpica/utxface.c')
-rw-r--r-- | drivers/acpi/acpica/utxface.c | 125 |
1 files changed, 124 insertions, 1 deletions
diff --git a/drivers/acpi/acpica/utxface.c b/drivers/acpi/acpica/utxface.c index 7f8cefcb2b32..c2da90f5fbe9 100644 --- a/drivers/acpi/acpica/utxface.c +++ b/drivers/acpi/acpica/utxface.c @@ -110,6 +110,15 @@ acpi_status __init acpi_initialize_subsystem(void) return_ACPI_STATUS(status); } + /* Initialize the global OSI interfaces list with the static names */ + + status = acpi_ut_initialize_interfaces(); + if (ACPI_FAILURE(status)) { + ACPI_EXCEPTION((AE_INFO, status, + "During OSI interfaces initialization")); + return_ACPI_STATUS(status); + } + /* If configured, initialize the AML debugger */ ACPI_DEBUGGER_EXEC(status = acpi_db_initialize()); @@ -506,6 +515,7 @@ acpi_install_initialization_handler(acpi_init_handler handler, u32 function) ACPI_EXPORT_SYMBOL(acpi_install_initialization_handler) #endif /* ACPI_FUTURE_USAGE */ + /***************************************************************************** * * FUNCTION: acpi_purge_cached_objects @@ -529,4 +539,117 @@ acpi_status acpi_purge_cached_objects(void) } ACPI_EXPORT_SYMBOL(acpi_purge_cached_objects) -#endif + +/***************************************************************************** + * + * FUNCTION: acpi_install_interface + * + * PARAMETERS: interface_name - The interface to install + * + * RETURN: Status + * + * DESCRIPTION: Install an _OSI interface to the global list + * + ****************************************************************************/ +acpi_status acpi_install_interface(acpi_string interface_name) +{ + acpi_status status; + struct acpi_interface_info *interface_info; + + /* Parameter validation */ + + if (!interface_name || (ACPI_STRLEN(interface_name) == 0)) { + return (AE_BAD_PARAMETER); + } + + (void)acpi_os_acquire_mutex(acpi_gbl_osi_mutex, ACPI_WAIT_FOREVER); + + /* Check if the interface name is already in the global list */ + + interface_info = acpi_ut_get_interface(interface_name); + if (interface_info) { + /* + * The interface already exists in the list. This is OK if the + * interface has been marked invalid -- just clear the bit. + */ + if (interface_info->flags & ACPI_OSI_INVALID) { + interface_info->flags &= ~ACPI_OSI_INVALID; + status = AE_OK; + } else { + status = AE_ALREADY_EXISTS; + } + } else { + /* New interface name, install into the global list */ + + status = acpi_ut_install_interface(interface_name); + } + + acpi_os_release_mutex(acpi_gbl_osi_mutex); + return (status); +} + +ACPI_EXPORT_SYMBOL(acpi_install_interface) + +/***************************************************************************** + * + * FUNCTION: acpi_remove_interface + * + * PARAMETERS: interface_name - The interface to remove + * + * RETURN: Status + * + * DESCRIPTION: Remove an _OSI interface from the global list + * + ****************************************************************************/ +acpi_status acpi_remove_interface(acpi_string interface_name) +{ + acpi_status status; + + /* Parameter validation */ + + if (!interface_name || (ACPI_STRLEN(interface_name) == 0)) { + return (AE_BAD_PARAMETER); + } + + (void)acpi_os_acquire_mutex(acpi_gbl_osi_mutex, ACPI_WAIT_FOREVER); + + status = acpi_ut_remove_interface(interface_name); + + acpi_os_release_mutex(acpi_gbl_osi_mutex); + return (status); +} + +ACPI_EXPORT_SYMBOL(acpi_remove_interface) + +/***************************************************************************** + * + * FUNCTION: acpi_install_interface_handler + * + * PARAMETERS: Handler - The _OSI interface handler to install + * NULL means "remove existing handler" + * + * RETURN: Status + * + * DESCRIPTION: Install a handler for the predefined _OSI ACPI method. + * invoked during execution of the internal implementation of + * _OSI. A NULL handler simply removes any existing handler. + * + ****************************************************************************/ +acpi_status acpi_install_interface_handler(acpi_interface_handler handler) +{ + acpi_status status = AE_OK; + + (void)acpi_os_acquire_mutex(acpi_gbl_osi_mutex, ACPI_WAIT_FOREVER); + + if (handler && acpi_gbl_interface_handler) { + status = AE_ALREADY_EXISTS; + } else { + acpi_gbl_interface_handler = handler; + } + + acpi_os_release_mutex(acpi_gbl_osi_mutex); + return (status); +} + +ACPI_EXPORT_SYMBOL(acpi_install_interface_handler) +#endif /* !ACPI_ASL_COMPILER */ |