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>
This commit is contained in:
@@ -96,7 +96,9 @@ static LIST_HEAD(resource_list_head);
|
||||
static DEFINE_SPINLOCK(acpi_res_lock);
|
||||
|
||||
#define OSI_STRING_LENGTH_MAX 64 /* arbitrary */
|
||||
static char osi_additional_string[OSI_STRING_LENGTH_MAX];
|
||||
static char osi_setup_string[OSI_STRING_LENGTH_MAX];
|
||||
|
||||
static void __init acpi_osi_setup_late(void);
|
||||
|
||||
/*
|
||||
* The story of _OSI(Linux)
|
||||
@@ -138,6 +140,20 @@ static struct osi_linux {
|
||||
unsigned int known:1;
|
||||
} osi_linux = { 0, 0, 0, 0};
|
||||
|
||||
static u32 acpi_osi_handler(acpi_string interface, u32 supported)
|
||||
{
|
||||
if (!strcmp("Linux", interface)) {
|
||||
|
||||
printk(KERN_NOTICE PREFIX
|
||||
"BIOS _OSI(Linux) query %s%s\n",
|
||||
osi_linux.enable ? "honored" : "ignored",
|
||||
osi_linux.cmdline ? " via cmdline" :
|
||||
osi_linux.dmi ? " via DMI" : "");
|
||||
}
|
||||
|
||||
return supported;
|
||||
}
|
||||
|
||||
static void __init acpi_request_region (struct acpi_generic_address *addr,
|
||||
unsigned int length, char *desc)
|
||||
{
|
||||
@@ -198,6 +214,8 @@ acpi_status acpi_os_initialize1(void)
|
||||
BUG_ON(!kacpid_wq);
|
||||
BUG_ON(!kacpi_notify_wq);
|
||||
BUG_ON(!kacpi_hotplug_wq);
|
||||
acpi_install_interface_handler(acpi_osi_handler);
|
||||
acpi_osi_setup_late();
|
||||
return AE_OK;
|
||||
}
|
||||
|
||||
@@ -979,6 +997,12 @@ static void __init set_osi_linux(unsigned int enable)
|
||||
printk(KERN_NOTICE PREFIX "%sed _OSI(Linux)\n",
|
||||
enable ? "Add": "Delet");
|
||||
}
|
||||
|
||||
if (osi_linux.enable)
|
||||
acpi_osi_setup("Linux");
|
||||
else
|
||||
acpi_osi_setup("!Linux");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1013,21 +1037,33 @@ void __init acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d)
|
||||
* string starting with '!' disables that string
|
||||
* otherwise string is added to list, augmenting built-in strings
|
||||
*/
|
||||
static void __init acpi_osi_setup_late(void)
|
||||
{
|
||||
char *str = osi_setup_string;
|
||||
|
||||
if (*str == '\0')
|
||||
return;
|
||||
|
||||
if (!strcmp("!Linux", str)) {
|
||||
acpi_cmdline_osi_linux(0); /* !enable */
|
||||
} else if (*str == '!') {
|
||||
if (acpi_remove_interface(++str) == AE_OK)
|
||||
printk(KERN_INFO PREFIX "Deleted _OSI(%s)\n", str);
|
||||
} else if (!strcmp("Linux", str)) {
|
||||
acpi_cmdline_osi_linux(1); /* enable */
|
||||
} else {
|
||||
if (acpi_install_interface(str) == AE_OK)
|
||||
printk(KERN_INFO PREFIX "Added _OSI(%s)\n", str);
|
||||
}
|
||||
}
|
||||
|
||||
int __init acpi_osi_setup(char *str)
|
||||
{
|
||||
if (str == NULL || *str == '\0') {
|
||||
printk(KERN_INFO PREFIX "_OSI method disabled\n");
|
||||
acpi_gbl_create_osi_method = FALSE;
|
||||
} else if (!strcmp("!Linux", str)) {
|
||||
acpi_cmdline_osi_linux(0); /* !enable */
|
||||
} else if (*str == '!') {
|
||||
if (acpi_osi_invalidate(++str) == AE_OK)
|
||||
printk(KERN_INFO PREFIX "Deleted _OSI(%s)\n", str);
|
||||
} else if (!strcmp("Linux", str)) {
|
||||
acpi_cmdline_osi_linux(1); /* enable */
|
||||
} else if (*osi_additional_string == '\0') {
|
||||
strncpy(osi_additional_string, str, OSI_STRING_LENGTH_MAX);
|
||||
printk(KERN_INFO PREFIX "Added _OSI(%s)\n", str);
|
||||
} else {
|
||||
strncpy(osi_setup_string, str, OSI_STRING_LENGTH_MAX);
|
||||
}
|
||||
|
||||
return 1;
|
||||
@@ -1284,38 +1320,6 @@ acpi_status acpi_os_release_object(acpi_cache_t * cache, void *object)
|
||||
return (AE_OK);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_os_validate_interface
|
||||
*
|
||||
* PARAMETERS: interface - Requested interface to be validated
|
||||
*
|
||||
* RETURN: AE_OK if interface is supported, AE_SUPPORT otherwise
|
||||
*
|
||||
* DESCRIPTION: Match an interface string to the interfaces supported by the
|
||||
* host. Strings originate from an AML call to the _OSI method.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
acpi_status
|
||||
acpi_os_validate_interface (char *interface)
|
||||
{
|
||||
if (!strncmp(osi_additional_string, interface, OSI_STRING_LENGTH_MAX))
|
||||
return AE_OK;
|
||||
if (!strcmp("Linux", interface)) {
|
||||
|
||||
printk(KERN_NOTICE PREFIX
|
||||
"BIOS _OSI(Linux) query %s%s\n",
|
||||
osi_linux.enable ? "honored" : "ignored",
|
||||
osi_linux.cmdline ? " via cmdline" :
|
||||
osi_linux.dmi ? " via DMI" : "");
|
||||
|
||||
if (osi_linux.enable)
|
||||
return AE_OK;
|
||||
}
|
||||
return AE_SUPPORT;
|
||||
}
|
||||
|
||||
static inline int acpi_res_list_add(struct acpi_res_list *res)
|
||||
{
|
||||
struct acpi_res_list *res_list_elem;
|
||||
|
Reference in New Issue
Block a user