diff options
author | Lin Ming <ming.m.lin@intel.com> | 2010-08-05 21:35:51 -0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2010-10-01 01:47:43 -0400 |
commit | b0ed7a915abac309fcb5a51bccd3782e3daa7417 (patch) | |
tree | 0bffdd098549d61180e6959217c84a05dadb99fa /drivers/acpi/osl.c | |
parent | 09387b43153953006471dbb06ece6bf779d10937 (diff) |
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/osl.c')
-rw-r--r-- | drivers/acpi/osl.c | 88 |
1 files changed, 46 insertions, 42 deletions
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index a351291496ff..6652c4929391 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c | |||
@@ -96,7 +96,9 @@ static LIST_HEAD(resource_list_head); | |||
96 | static DEFINE_SPINLOCK(acpi_res_lock); | 96 | static DEFINE_SPINLOCK(acpi_res_lock); |
97 | 97 | ||
98 | #define OSI_STRING_LENGTH_MAX 64 /* arbitrary */ | 98 | #define OSI_STRING_LENGTH_MAX 64 /* arbitrary */ |
99 | static char osi_additional_string[OSI_STRING_LENGTH_MAX]; | 99 | static char osi_setup_string[OSI_STRING_LENGTH_MAX]; |
100 | |||
101 | static void __init acpi_osi_setup_late(void); | ||
100 | 102 | ||
101 | /* | 103 | /* |
102 | * The story of _OSI(Linux) | 104 | * The story of _OSI(Linux) |
@@ -138,6 +140,20 @@ static struct osi_linux { | |||
138 | unsigned int known:1; | 140 | unsigned int known:1; |
139 | } osi_linux = { 0, 0, 0, 0}; | 141 | } osi_linux = { 0, 0, 0, 0}; |
140 | 142 | ||
143 | static u32 acpi_osi_handler(acpi_string interface, u32 supported) | ||
144 | { | ||
145 | if (!strcmp("Linux", interface)) { | ||
146 | |||
147 | printk(KERN_NOTICE PREFIX | ||
148 | "BIOS _OSI(Linux) query %s%s\n", | ||
149 | osi_linux.enable ? "honored" : "ignored", | ||
150 | osi_linux.cmdline ? " via cmdline" : | ||
151 | osi_linux.dmi ? " via DMI" : ""); | ||
152 | } | ||
153 | |||
154 | return supported; | ||
155 | } | ||
156 | |||
141 | static void __init acpi_request_region (struct acpi_generic_address *addr, | 157 | static void __init acpi_request_region (struct acpi_generic_address *addr, |
142 | unsigned int length, char *desc) | 158 | unsigned int length, char *desc) |
143 | { | 159 | { |
@@ -198,6 +214,8 @@ acpi_status acpi_os_initialize1(void) | |||
198 | BUG_ON(!kacpid_wq); | 214 | BUG_ON(!kacpid_wq); |
199 | BUG_ON(!kacpi_notify_wq); | 215 | BUG_ON(!kacpi_notify_wq); |
200 | BUG_ON(!kacpi_hotplug_wq); | 216 | BUG_ON(!kacpi_hotplug_wq); |
217 | acpi_install_interface_handler(acpi_osi_handler); | ||
218 | acpi_osi_setup_late(); | ||
201 | return AE_OK; | 219 | return AE_OK; |
202 | } | 220 | } |
203 | 221 | ||
@@ -979,6 +997,12 @@ static void __init set_osi_linux(unsigned int enable) | |||
979 | printk(KERN_NOTICE PREFIX "%sed _OSI(Linux)\n", | 997 | printk(KERN_NOTICE PREFIX "%sed _OSI(Linux)\n", |
980 | enable ? "Add": "Delet"); | 998 | enable ? "Add": "Delet"); |
981 | } | 999 | } |
1000 | |||
1001 | if (osi_linux.enable) | ||
1002 | acpi_osi_setup("Linux"); | ||
1003 | else | ||
1004 | acpi_osi_setup("!Linux"); | ||
1005 | |||
982 | return; | 1006 | return; |
983 | } | 1007 | } |
984 | 1008 | ||
@@ -1013,21 +1037,33 @@ void __init acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d) | |||
1013 | * string starting with '!' disables that string | 1037 | * string starting with '!' disables that string |
1014 | * otherwise string is added to list, augmenting built-in strings | 1038 | * otherwise string is added to list, augmenting built-in strings |
1015 | */ | 1039 | */ |
1016 | int __init acpi_osi_setup(char *str) | 1040 | static void __init acpi_osi_setup_late(void) |
1017 | { | 1041 | { |
1018 | if (str == NULL || *str == '\0') { | 1042 | char *str = osi_setup_string; |
1019 | printk(KERN_INFO PREFIX "_OSI method disabled\n"); | 1043 | |
1020 | acpi_gbl_create_osi_method = FALSE; | 1044 | if (*str == '\0') |
1021 | } else if (!strcmp("!Linux", str)) { | 1045 | return; |
1046 | |||
1047 | if (!strcmp("!Linux", str)) { | ||
1022 | acpi_cmdline_osi_linux(0); /* !enable */ | 1048 | acpi_cmdline_osi_linux(0); /* !enable */ |
1023 | } else if (*str == '!') { | 1049 | } else if (*str == '!') { |
1024 | if (acpi_osi_invalidate(++str) == AE_OK) | 1050 | if (acpi_remove_interface(++str) == AE_OK) |
1025 | printk(KERN_INFO PREFIX "Deleted _OSI(%s)\n", str); | 1051 | printk(KERN_INFO PREFIX "Deleted _OSI(%s)\n", str); |
1026 | } else if (!strcmp("Linux", str)) { | 1052 | } else if (!strcmp("Linux", str)) { |
1027 | acpi_cmdline_osi_linux(1); /* enable */ | 1053 | acpi_cmdline_osi_linux(1); /* enable */ |
1028 | } else if (*osi_additional_string == '\0') { | 1054 | } else { |
1029 | strncpy(osi_additional_string, str, OSI_STRING_LENGTH_MAX); | 1055 | if (acpi_install_interface(str) == AE_OK) |
1030 | printk(KERN_INFO PREFIX "Added _OSI(%s)\n", str); | 1056 | printk(KERN_INFO PREFIX "Added _OSI(%s)\n", str); |
1057 | } | ||
1058 | } | ||
1059 | |||
1060 | int __init acpi_osi_setup(char *str) | ||
1061 | { | ||
1062 | if (str == NULL || *str == '\0') { | ||
1063 | printk(KERN_INFO PREFIX "_OSI method disabled\n"); | ||
1064 | acpi_gbl_create_osi_method = FALSE; | ||
1065 | } else { | ||
1066 | strncpy(osi_setup_string, str, OSI_STRING_LENGTH_MAX); | ||
1031 | } | 1067 | } |
1032 | 1068 | ||
1033 | return 1; | 1069 | return 1; |
@@ -1284,38 +1320,6 @@ acpi_status acpi_os_release_object(acpi_cache_t * cache, void *object) | |||
1284 | return (AE_OK); | 1320 | return (AE_OK); |
1285 | } | 1321 | } |
1286 | 1322 | ||
1287 | /****************************************************************************** | ||
1288 | * | ||
1289 | * FUNCTION: acpi_os_validate_interface | ||
1290 | * | ||
1291 | * PARAMETERS: interface - Requested interface to be validated | ||
1292 | * | ||
1293 | * RETURN: AE_OK if interface is supported, AE_SUPPORT otherwise | ||
1294 | * | ||
1295 | * DESCRIPTION: Match an interface string to the interfaces supported by the | ||
1296 | * host. Strings originate from an AML call to the _OSI method. | ||
1297 | * | ||
1298 | *****************************************************************************/ | ||
1299 | |||
1300 | acpi_status | ||
1301 | acpi_os_validate_interface (char *interface) | ||
1302 | { | ||
1303 | if (!strncmp(osi_additional_string, interface, OSI_STRING_LENGTH_MAX)) | ||
1304 | return AE_OK; | ||
1305 | if (!strcmp("Linux", interface)) { | ||
1306 | |||
1307 | printk(KERN_NOTICE PREFIX | ||
1308 | "BIOS _OSI(Linux) query %s%s\n", | ||
1309 | osi_linux.enable ? "honored" : "ignored", | ||
1310 | osi_linux.cmdline ? " via cmdline" : | ||
1311 | osi_linux.dmi ? " via DMI" : ""); | ||
1312 | |||
1313 | if (osi_linux.enable) | ||
1314 | return AE_OK; | ||
1315 | } | ||
1316 | return AE_SUPPORT; | ||
1317 | } | ||
1318 | |||
1319 | static inline int acpi_res_list_add(struct acpi_res_list *res) | 1323 | static inline int acpi_res_list_add(struct acpi_res_list *res) |
1320 | { | 1324 | { |
1321 | struct acpi_res_list *res_list_elem; | 1325 | struct acpi_res_list *res_list_elem; |