aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/osl.c
diff options
context:
space:
mode:
authorLin Ming <ming.m.lin@intel.com>2010-08-05 21:35:51 -0400
committerLen Brown <len.brown@intel.com>2010-10-01 01:47:43 -0400
commitb0ed7a915abac309fcb5a51bccd3782e3daa7417 (patch)
tree0bffdd098549d61180e6959217c84a05dadb99fa /drivers/acpi/osl.c
parent09387b43153953006471dbb06ece6bf779d10937 (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.c88
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);
96static DEFINE_SPINLOCK(acpi_res_lock); 96static DEFINE_SPINLOCK(acpi_res_lock);
97 97
98#define OSI_STRING_LENGTH_MAX 64 /* arbitrary */ 98#define OSI_STRING_LENGTH_MAX 64 /* arbitrary */
99static char osi_additional_string[OSI_STRING_LENGTH_MAX]; 99static char osi_setup_string[OSI_STRING_LENGTH_MAX];
100
101static 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
143static 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
141static void __init acpi_request_region (struct acpi_generic_address *addr, 157static 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 */
1016int __init acpi_osi_setup(char *str) 1040static 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
1060int __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
1300acpi_status
1301acpi_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
1319static inline int acpi_res_list_add(struct acpi_res_list *res) 1323static 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;