diff options
author | Lv Zheng <lv.zheng@intel.com> | 2016-05-03 04:49:01 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2016-05-04 18:13:53 -0400 |
commit | e5f660ebef68e3ed1a988ad06ba23562153cee5c (patch) | |
tree | 0209aa2078743b40d9d4819c51dae3de9c450d43 | |
parent | d5a91d74c6d7da2cebadbb9f2d03e56f84d7be62 (diff) |
ACPI / osi: Collect _OSI handling into one single file
_OSI handling code grows giant and it's time to move them into one file.
This patch collects all _OSI handling code into one single file.
So that we only have the following functions to be used externally:
early_acpi_osi_init(): Used by DMI detections;
acpi_osi_init(): Used to initialize OSI command line settings and install
Linux specific _OSI handler;
acpi_osi_setup(): The API that should be used by the external quirks.
acpi_osi_is_win8(): The API is used by the external drivers to determine
if BIOS supports Win8.
CONFIG_DMI is not useful as stub dmi_check_system() can make everything
stub because of strip.
No functional changes.
Tested-by: Lukas Wunner <lukas@wunner.de>
Tested-by: Chen Yu <yu.c.chen@intel.com>
Signed-off-by: Lv Zheng <lv.zheng@intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r-- | drivers/acpi/Makefile | 2 | ||||
-rw-r--r-- | drivers/acpi/blacklist.c | 219 | ||||
-rw-r--r-- | drivers/acpi/internal.h | 2 | ||||
-rw-r--r-- | drivers/acpi/osi.c | 522 | ||||
-rw-r--r-- | drivers/acpi/osl.c | 256 | ||||
-rw-r--r-- | include/linux/acpi.h | 2 |
6 files changed, 531 insertions, 472 deletions
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index edeb2d1d99be..345df7f960b6 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile | |||
@@ -18,7 +18,7 @@ obj-$(CONFIG_ACPI) += acpi.o \ | |||
18 | acpica/ | 18 | acpica/ |
19 | 19 | ||
20 | # All the builtin files are in the "acpi." module_param namespace. | 20 | # All the builtin files are in the "acpi." module_param namespace. |
21 | acpi-y += osl.o utils.o reboot.o | 21 | acpi-y += osi.o osl.o utils.o reboot.o |
22 | acpi-y += nvs.o | 22 | acpi-y += nvs.o |
23 | 23 | ||
24 | # Power management related files | 24 | # Power management related files |
diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c index ba1601d26c48..bdc67bad61a7 100644 --- a/drivers/acpi/blacklist.c +++ b/drivers/acpi/blacklist.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Check to see if the given machine has a known bad ACPI BIOS | 4 | * Check to see if the given machine has a known bad ACPI BIOS |
5 | * or if the BIOS is too old. | 5 | * or if the BIOS is too old. |
6 | * Check given machine against acpi_osi_dmi_table[]. | 6 | * Check given machine against acpi_rev_dmi_table[]. |
7 | * | 7 | * |
8 | * Copyright (C) 2004 Len Brown <len.brown@intel.com> | 8 | * Copyright (C) 2004 Len Brown <len.brown@intel.com> |
9 | * Copyright (C) 2002 Andy Grover <andrew.grover@intel.com> | 9 | * Copyright (C) 2002 Andy Grover <andrew.grover@intel.com> |
@@ -47,7 +47,7 @@ struct acpi_blacklist_item { | |||
47 | u32 is_critical_error; | 47 | u32 is_critical_error; |
48 | }; | 48 | }; |
49 | 49 | ||
50 | static struct dmi_system_id acpi_osi_dmi_table[] __initdata; | 50 | static struct dmi_system_id acpi_rev_dmi_table[] __initdata; |
51 | 51 | ||
52 | /* | 52 | /* |
53 | * POLICY: If *anything* doesn't work, put it on the blacklist. | 53 | * POLICY: If *anything* doesn't work, put it on the blacklist. |
@@ -128,41 +128,12 @@ int __init acpi_blacklisted(void) | |||
128 | } | 128 | } |
129 | } | 129 | } |
130 | 130 | ||
131 | dmi_check_system(acpi_osi_dmi_table); | 131 | (void)early_acpi_osi_init(); |
132 | dmi_check_system(acpi_rev_dmi_table); | ||
132 | 133 | ||
133 | return blacklisted; | 134 | return blacklisted; |
134 | } | 135 | } |
135 | #ifdef CONFIG_DMI | 136 | #ifdef CONFIG_DMI |
136 | static int __init dmi_enable_osi_darwin(const struct dmi_system_id *d) | ||
137 | { | ||
138 | acpi_osi_dmi_darwin(true, d); | ||
139 | return 0; | ||
140 | } | ||
141 | static int __init dmi_enable_osi_linux(const struct dmi_system_id *d) | ||
142 | { | ||
143 | acpi_osi_dmi_linux(true, d); | ||
144 | return 0; | ||
145 | } | ||
146 | static int __init dmi_disable_osi_vista(const struct dmi_system_id *d) | ||
147 | { | ||
148 | pr_notice(PREFIX "DMI detected: %s\n", d->ident); | ||
149 | acpi_osi_setup("!Windows 2006"); | ||
150 | acpi_osi_setup("!Windows 2006 SP1"); | ||
151 | acpi_osi_setup("!Windows 2006 SP2"); | ||
152 | return 0; | ||
153 | } | ||
154 | static int __init dmi_disable_osi_win7(const struct dmi_system_id *d) | ||
155 | { | ||
156 | pr_notice(PREFIX "DMI detected: %s\n", d->ident); | ||
157 | acpi_osi_setup("!Windows 2009"); | ||
158 | return 0; | ||
159 | } | ||
160 | static int __init dmi_disable_osi_win8(const struct dmi_system_id *d) | ||
161 | { | ||
162 | pr_notice(PREFIX "DMI detected: %s\n", d->ident); | ||
163 | acpi_osi_setup("!Windows 2012"); | ||
164 | return 0; | ||
165 | } | ||
166 | #ifdef CONFIG_ACPI_REV_OVERRIDE_POSSIBLE | 137 | #ifdef CONFIG_ACPI_REV_OVERRIDE_POSSIBLE |
167 | static int __init dmi_enable_rev_override(const struct dmi_system_id *d) | 138 | static int __init dmi_enable_rev_override(const struct dmi_system_id *d) |
168 | { | 139 | { |
@@ -173,187 +144,7 @@ static int __init dmi_enable_rev_override(const struct dmi_system_id *d) | |||
173 | } | 144 | } |
174 | #endif | 145 | #endif |
175 | 146 | ||
176 | static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { | 147 | static struct dmi_system_id acpi_rev_dmi_table[] __initdata = { |
177 | { | ||
178 | .callback = dmi_disable_osi_vista, | ||
179 | .ident = "Fujitsu Siemens", | ||
180 | .matches = { | ||
181 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), | ||
182 | DMI_MATCH(DMI_PRODUCT_NAME, "ESPRIMO Mobile V5505"), | ||
183 | }, | ||
184 | }, | ||
185 | { | ||
186 | /* | ||
187 | * There have a NVIF method in MSI GX723 DSDT need call by Nvidia | ||
188 | * driver (e.g. nouveau) when user press brightness hotkey. | ||
189 | * Currently, nouveau driver didn't do the job and it causes there | ||
190 | * have a infinite while loop in DSDT when user press hotkey. | ||
191 | * We add MSI GX723's dmi information to this table for workaround | ||
192 | * this issue. | ||
193 | * Will remove MSI GX723 from the table after nouveau grows support. | ||
194 | */ | ||
195 | .callback = dmi_disable_osi_vista, | ||
196 | .ident = "MSI GX723", | ||
197 | .matches = { | ||
198 | DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"), | ||
199 | DMI_MATCH(DMI_PRODUCT_NAME, "GX723"), | ||
200 | }, | ||
201 | }, | ||
202 | { | ||
203 | .callback = dmi_disable_osi_vista, | ||
204 | .ident = "Sony VGN-NS10J_S", | ||
205 | .matches = { | ||
206 | DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), | ||
207 | DMI_MATCH(DMI_PRODUCT_NAME, "VGN-NS10J_S"), | ||
208 | }, | ||
209 | }, | ||
210 | { | ||
211 | .callback = dmi_disable_osi_vista, | ||
212 | .ident = "Sony VGN-SR290J", | ||
213 | .matches = { | ||
214 | DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), | ||
215 | DMI_MATCH(DMI_PRODUCT_NAME, "VGN-SR290J"), | ||
216 | }, | ||
217 | }, | ||
218 | { | ||
219 | .callback = dmi_disable_osi_vista, | ||
220 | .ident = "VGN-NS50B_L", | ||
221 | .matches = { | ||
222 | DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), | ||
223 | DMI_MATCH(DMI_PRODUCT_NAME, "VGN-NS50B_L"), | ||
224 | }, | ||
225 | }, | ||
226 | { | ||
227 | .callback = dmi_disable_osi_vista, | ||
228 | .ident = "VGN-SR19XN", | ||
229 | .matches = { | ||
230 | DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), | ||
231 | DMI_MATCH(DMI_PRODUCT_NAME, "VGN-SR19XN"), | ||
232 | }, | ||
233 | }, | ||
234 | { | ||
235 | .callback = dmi_disable_osi_vista, | ||
236 | .ident = "Toshiba Satellite L355", | ||
237 | .matches = { | ||
238 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | ||
239 | DMI_MATCH(DMI_PRODUCT_VERSION, "Satellite L355"), | ||
240 | }, | ||
241 | }, | ||
242 | { | ||
243 | .callback = dmi_disable_osi_win7, | ||
244 | .ident = "ASUS K50IJ", | ||
245 | .matches = { | ||
246 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), | ||
247 | DMI_MATCH(DMI_PRODUCT_NAME, "K50IJ"), | ||
248 | }, | ||
249 | }, | ||
250 | { | ||
251 | .callback = dmi_disable_osi_vista, | ||
252 | .ident = "Toshiba P305D", | ||
253 | .matches = { | ||
254 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | ||
255 | DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P305D"), | ||
256 | }, | ||
257 | }, | ||
258 | { | ||
259 | .callback = dmi_disable_osi_vista, | ||
260 | .ident = "Toshiba NB100", | ||
261 | .matches = { | ||
262 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | ||
263 | DMI_MATCH(DMI_PRODUCT_NAME, "NB100"), | ||
264 | }, | ||
265 | }, | ||
266 | |||
267 | /* | ||
268 | * The wireless hotkey does not work on those machines when | ||
269 | * returning true for _OSI("Windows 2012") | ||
270 | */ | ||
271 | { | ||
272 | .callback = dmi_disable_osi_win8, | ||
273 | .ident = "Dell Inspiron 7737", | ||
274 | .matches = { | ||
275 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
276 | DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 7737"), | ||
277 | }, | ||
278 | }, | ||
279 | { | ||
280 | .callback = dmi_disable_osi_win8, | ||
281 | .ident = "Dell Inspiron 7537", | ||
282 | .matches = { | ||
283 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
284 | DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 7537"), | ||
285 | }, | ||
286 | }, | ||
287 | { | ||
288 | .callback = dmi_disable_osi_win8, | ||
289 | .ident = "Dell Inspiron 5437", | ||
290 | .matches = { | ||
291 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
292 | DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 5437"), | ||
293 | }, | ||
294 | }, | ||
295 | { | ||
296 | .callback = dmi_disable_osi_win8, | ||
297 | .ident = "Dell Inspiron 3437", | ||
298 | .matches = { | ||
299 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
300 | DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 3437"), | ||
301 | }, | ||
302 | }, | ||
303 | { | ||
304 | .callback = dmi_disable_osi_win8, | ||
305 | .ident = "Dell Vostro 3446", | ||
306 | .matches = { | ||
307 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
308 | DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 3446"), | ||
309 | }, | ||
310 | }, | ||
311 | { | ||
312 | .callback = dmi_disable_osi_win8, | ||
313 | .ident = "Dell Vostro 3546", | ||
314 | .matches = { | ||
315 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
316 | DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 3546"), | ||
317 | }, | ||
318 | }, | ||
319 | |||
320 | /* | ||
321 | * BIOS invocation of _OSI(Linux) is almost always a BIOS bug. | ||
322 | * Linux ignores it, except for the machines enumerated below. | ||
323 | */ | ||
324 | |||
325 | /* | ||
326 | * Without this this EEEpc exports a non working WMI interface, with | ||
327 | * this it exports a working "good old" eeepc_laptop interface, fixing | ||
328 | * both brightness control, and rfkill not working. | ||
329 | */ | ||
330 | { | ||
331 | .callback = dmi_enable_osi_linux, | ||
332 | .ident = "Asus EEE PC 1015PX", | ||
333 | .matches = { | ||
334 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer INC."), | ||
335 | DMI_MATCH(DMI_PRODUCT_NAME, "1015PX"), | ||
336 | }, | ||
337 | }, | ||
338 | |||
339 | /* | ||
340 | * Enable _OSI("Darwin") for all apple platforms. | ||
341 | */ | ||
342 | { | ||
343 | .callback = dmi_enable_osi_darwin, | ||
344 | .ident = "Apple hardware", | ||
345 | .matches = { | ||
346 | DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), | ||
347 | }, | ||
348 | }, | ||
349 | { | ||
350 | .callback = dmi_enable_osi_darwin, | ||
351 | .ident = "Apple hardware", | ||
352 | .matches = { | ||
353 | DMI_MATCH(DMI_SYS_VENDOR, "Apple Computer, Inc."), | ||
354 | }, | ||
355 | }, | ||
356 | |||
357 | #ifdef CONFIG_ACPI_REV_OVERRIDE_POSSIBLE | 148 | #ifdef CONFIG_ACPI_REV_OVERRIDE_POSSIBLE |
358 | /* | 149 | /* |
359 | * DELL XPS 13 (2015) switches sound between HDA and I2S | 150 | * DELL XPS 13 (2015) switches sound between HDA and I2S |
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index 7c188472d9c2..a8780a2e1975 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h | |||
@@ -20,6 +20,8 @@ | |||
20 | 20 | ||
21 | #define PREFIX "ACPI: " | 21 | #define PREFIX "ACPI: " |
22 | 22 | ||
23 | int early_acpi_osi_init(void); | ||
24 | int acpi_osi_init(void); | ||
23 | void acpi_initrd_initialize_tables(void); | 25 | void acpi_initrd_initialize_tables(void); |
24 | acpi_status acpi_os_initialize1(void); | 26 | acpi_status acpi_os_initialize1(void); |
25 | void init_acpi_device_notify(void); | 27 | void init_acpi_device_notify(void); |
diff --git a/drivers/acpi/osi.c b/drivers/acpi/osi.c new file mode 100644 index 000000000000..849f9d2245ca --- /dev/null +++ b/drivers/acpi/osi.c | |||
@@ -0,0 +1,522 @@ | |||
1 | /* | ||
2 | * osi.c - _OSI implementation | ||
3 | * | ||
4 | * Copyright (C) 2016 Intel Corporation | ||
5 | * Author: Lv Zheng <lv.zheng@intel.com> | ||
6 | * | ||
7 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or (at | ||
12 | * your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, but | ||
15 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
17 | * General Public License for more details. | ||
18 | * | ||
19 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
20 | */ | ||
21 | |||
22 | /* Uncomment next line to get verbose printout */ | ||
23 | /* #define DEBUG */ | ||
24 | #define pr_fmt(fmt) "ACPI: " fmt | ||
25 | |||
26 | #include <linux/module.h> | ||
27 | #include <linux/kernel.h> | ||
28 | #include <linux/acpi.h> | ||
29 | #include <linux/dmi.h> | ||
30 | |||
31 | #include "internal.h" | ||
32 | |||
33 | |||
34 | #define OSI_STRING_LENGTH_MAX 64 | ||
35 | #define OSI_STRING_ENTRIES_MAX 16 | ||
36 | |||
37 | struct acpi_osi_entry { | ||
38 | char string[OSI_STRING_LENGTH_MAX]; | ||
39 | bool enable; | ||
40 | }; | ||
41 | |||
42 | static struct acpi_osi_config { | ||
43 | u8 default_disabling; | ||
44 | unsigned int linux_enable:1; | ||
45 | unsigned int linux_dmi:1; | ||
46 | unsigned int linux_cmdline:1; | ||
47 | unsigned int darwin_enable:1; | ||
48 | unsigned int darwin_dmi:1; | ||
49 | unsigned int darwin_cmdline:1; | ||
50 | } osi_config; | ||
51 | |||
52 | static struct acpi_osi_config osi_config; | ||
53 | static struct acpi_osi_entry | ||
54 | osi_setup_entries[OSI_STRING_ENTRIES_MAX] __initdata = { | ||
55 | {"Module Device", true}, | ||
56 | {"Processor Device", true}, | ||
57 | {"3.0 _SCP Extensions", true}, | ||
58 | {"Processor Aggregator Device", true}, | ||
59 | }; | ||
60 | |||
61 | static u32 acpi_osi_handler(acpi_string interface, u32 supported) | ||
62 | { | ||
63 | if (!strcmp("Linux", interface)) { | ||
64 | pr_notice_once(FW_BUG | ||
65 | "BIOS _OSI(Linux) query %s%s\n", | ||
66 | osi_config.linux_enable ? "honored" : "ignored", | ||
67 | osi_config.linux_cmdline ? " via cmdline" : | ||
68 | osi_config.linux_dmi ? " via DMI" : ""); | ||
69 | } | ||
70 | if (!strcmp("Darwin", interface)) { | ||
71 | pr_notice_once( | ||
72 | "BIOS _OSI(Darwin) query %s%s\n", | ||
73 | osi_config.darwin_enable ? "honored" : "ignored", | ||
74 | osi_config.darwin_cmdline ? " via cmdline" : | ||
75 | osi_config.darwin_dmi ? " via DMI" : ""); | ||
76 | } | ||
77 | |||
78 | return supported; | ||
79 | } | ||
80 | |||
81 | void __init acpi_osi_setup(char *str) | ||
82 | { | ||
83 | struct acpi_osi_entry *osi; | ||
84 | bool enable = true; | ||
85 | int i; | ||
86 | |||
87 | if (!acpi_gbl_create_osi_method) | ||
88 | return; | ||
89 | |||
90 | if (str == NULL || *str == '\0') { | ||
91 | pr_info("_OSI method disabled\n"); | ||
92 | acpi_gbl_create_osi_method = FALSE; | ||
93 | return; | ||
94 | } | ||
95 | |||
96 | if (*str == '!') { | ||
97 | str++; | ||
98 | if (*str == '\0') { | ||
99 | /* Do not override acpi_osi=!* */ | ||
100 | if (!osi_config.default_disabling) | ||
101 | osi_config.default_disabling = | ||
102 | ACPI_DISABLE_ALL_VENDOR_STRINGS; | ||
103 | return; | ||
104 | } else if (*str == '*') { | ||
105 | osi_config.default_disabling = ACPI_DISABLE_ALL_STRINGS; | ||
106 | for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) { | ||
107 | osi = &osi_setup_entries[i]; | ||
108 | osi->enable = false; | ||
109 | } | ||
110 | return; | ||
111 | } else if (*str == '!') { | ||
112 | osi_config.default_disabling = 0; | ||
113 | return; | ||
114 | } | ||
115 | enable = false; | ||
116 | } | ||
117 | |||
118 | for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) { | ||
119 | osi = &osi_setup_entries[i]; | ||
120 | if (!strcmp(osi->string, str)) { | ||
121 | osi->enable = enable; | ||
122 | break; | ||
123 | } else if (osi->string[0] == '\0') { | ||
124 | osi->enable = enable; | ||
125 | strncpy(osi->string, str, OSI_STRING_LENGTH_MAX); | ||
126 | break; | ||
127 | } | ||
128 | } | ||
129 | } | ||
130 | |||
131 | static void __init __acpi_osi_setup_darwin(bool enable) | ||
132 | { | ||
133 | osi_config.darwin_enable = !!enable; | ||
134 | if (enable) { | ||
135 | acpi_osi_setup("!"); | ||
136 | acpi_osi_setup("Darwin"); | ||
137 | } else { | ||
138 | acpi_osi_setup("!!"); | ||
139 | acpi_osi_setup("!Darwin"); | ||
140 | } | ||
141 | } | ||
142 | |||
143 | static void __init acpi_osi_setup_darwin(bool enable) | ||
144 | { | ||
145 | /* Override acpi_osi_dmi_blacklisted() */ | ||
146 | osi_config.darwin_dmi = 0; | ||
147 | osi_config.darwin_cmdline = 1; | ||
148 | __acpi_osi_setup_darwin(enable); | ||
149 | } | ||
150 | |||
151 | /* | ||
152 | * The story of _OSI(Linux) | ||
153 | * | ||
154 | * From pre-history through Linux-2.6.22, Linux responded TRUE upon a BIOS | ||
155 | * OSI(Linux) query. | ||
156 | * | ||
157 | * Unfortunately, reference BIOS writers got wind of this and put | ||
158 | * OSI(Linux) in their example code, quickly exposing this string as | ||
159 | * ill-conceived and opening the door to an un-bounded number of BIOS | ||
160 | * incompatibilities. | ||
161 | * | ||
162 | * For example, OSI(Linux) was used on resume to re-POST a video card on | ||
163 | * one system, because Linux at that time could not do a speedy restore in | ||
164 | * its native driver. But then upon gaining quick native restore | ||
165 | * capability, Linux has no way to tell the BIOS to skip the time-consuming | ||
166 | * POST -- putting Linux at a permanent performance disadvantage. On | ||
167 | * another system, the BIOS writer used OSI(Linux) to infer native OS | ||
168 | * support for IPMI! On other systems, OSI(Linux) simply got in the way of | ||
169 | * Linux claiming to be compatible with other operating systems, exposing | ||
170 | * BIOS issues such as skipped device initialization. | ||
171 | * | ||
172 | * So "Linux" turned out to be a really poor chose of OSI string, and from | ||
173 | * Linux-2.6.23 onward we respond FALSE. | ||
174 | * | ||
175 | * BIOS writers should NOT query _OSI(Linux) on future systems. Linux will | ||
176 | * complain on the console when it sees it, and return FALSE. To get Linux | ||
177 | * to return TRUE for your system will require a kernel source update to | ||
178 | * add a DMI entry, or boot with "acpi_osi=Linux" | ||
179 | */ | ||
180 | static void __init __acpi_osi_setup_linux(bool enable) | ||
181 | { | ||
182 | osi_config.linux_enable = !!enable; | ||
183 | if (enable) | ||
184 | acpi_osi_setup("Linux"); | ||
185 | else | ||
186 | acpi_osi_setup("!Linux"); | ||
187 | } | ||
188 | |||
189 | static void __init acpi_osi_setup_linux(bool enable) | ||
190 | { | ||
191 | /* Override acpi_osi_dmi_blacklisted() */ | ||
192 | osi_config.linux_dmi = 0; | ||
193 | osi_config.linux_cmdline = 1; | ||
194 | __acpi_osi_setup_linux(enable); | ||
195 | } | ||
196 | |||
197 | /* | ||
198 | * Modify the list of "OS Interfaces" reported to BIOS via _OSI | ||
199 | * | ||
200 | * empty string disables _OSI | ||
201 | * string starting with '!' disables that string | ||
202 | * otherwise string is added to list, augmenting built-in strings | ||
203 | */ | ||
204 | static void __init acpi_osi_setup_late(void) | ||
205 | { | ||
206 | struct acpi_osi_entry *osi; | ||
207 | char *str; | ||
208 | int i; | ||
209 | acpi_status status; | ||
210 | |||
211 | if (osi_config.default_disabling) { | ||
212 | status = acpi_update_interfaces(osi_config.default_disabling); | ||
213 | if (ACPI_SUCCESS(status)) | ||
214 | pr_info("Disabled all _OSI OS vendors%s\n", | ||
215 | osi_config.default_disabling == | ||
216 | ACPI_DISABLE_ALL_STRINGS ? | ||
217 | " and feature groups" : ""); | ||
218 | } | ||
219 | |||
220 | for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) { | ||
221 | osi = &osi_setup_entries[i]; | ||
222 | str = osi->string; | ||
223 | if (*str == '\0') | ||
224 | break; | ||
225 | if (osi->enable) { | ||
226 | status = acpi_install_interface(str); | ||
227 | if (ACPI_SUCCESS(status)) | ||
228 | pr_info("Added _OSI(%s)\n", str); | ||
229 | } else { | ||
230 | status = acpi_remove_interface(str); | ||
231 | if (ACPI_SUCCESS(status)) | ||
232 | pr_info("Deleted _OSI(%s)\n", str); | ||
233 | } | ||
234 | } | ||
235 | } | ||
236 | |||
237 | static int __init osi_setup(char *str) | ||
238 | { | ||
239 | if (str && !strcmp("Linux", str)) | ||
240 | acpi_osi_setup_linux(true); | ||
241 | else if (str && !strcmp("!Linux", str)) | ||
242 | acpi_osi_setup_linux(false); | ||
243 | else if (str && !strcmp("Darwin", str)) | ||
244 | acpi_osi_setup_darwin(true); | ||
245 | else if (str && !strcmp("!Darwin", str)) | ||
246 | acpi_osi_setup_darwin(false); | ||
247 | else | ||
248 | acpi_osi_setup(str); | ||
249 | |||
250 | return 1; | ||
251 | } | ||
252 | __setup("acpi_osi=", osi_setup); | ||
253 | |||
254 | bool acpi_osi_is_win8(void) | ||
255 | { | ||
256 | return acpi_gbl_osi_data >= ACPI_OSI_WIN_8; | ||
257 | } | ||
258 | EXPORT_SYMBOL(acpi_osi_is_win8); | ||
259 | |||
260 | static void __init acpi_osi_dmi_darwin(bool enable, | ||
261 | const struct dmi_system_id *d) | ||
262 | { | ||
263 | pr_notice("DMI detected to setup _OSI(\"Darwin\"): %s\n", d->ident); | ||
264 | osi_config.darwin_dmi = 1; | ||
265 | __acpi_osi_setup_darwin(enable); | ||
266 | } | ||
267 | |||
268 | void __init acpi_osi_dmi_linux(bool enable, const struct dmi_system_id *d) | ||
269 | { | ||
270 | pr_notice("DMI detected to setup _OSI(\"Linux\"): %s\n", d->ident); | ||
271 | osi_config.linux_dmi = 1; | ||
272 | __acpi_osi_setup_linux(enable); | ||
273 | } | ||
274 | |||
275 | static int __init dmi_enable_osi_darwin(const struct dmi_system_id *d) | ||
276 | { | ||
277 | acpi_osi_dmi_darwin(true, d); | ||
278 | |||
279 | return 0; | ||
280 | } | ||
281 | |||
282 | static int __init dmi_enable_osi_linux(const struct dmi_system_id *d) | ||
283 | { | ||
284 | acpi_osi_dmi_linux(true, d); | ||
285 | |||
286 | return 0; | ||
287 | } | ||
288 | |||
289 | static int __init dmi_disable_osi_vista(const struct dmi_system_id *d) | ||
290 | { | ||
291 | pr_notice("DMI detected: %s\n", d->ident); | ||
292 | acpi_osi_setup("!Windows 2006"); | ||
293 | acpi_osi_setup("!Windows 2006 SP1"); | ||
294 | acpi_osi_setup("!Windows 2006 SP2"); | ||
295 | |||
296 | return 0; | ||
297 | } | ||
298 | |||
299 | static int __init dmi_disable_osi_win7(const struct dmi_system_id *d) | ||
300 | { | ||
301 | pr_notice("DMI detected: %s\n", d->ident); | ||
302 | acpi_osi_setup("!Windows 2009"); | ||
303 | |||
304 | return 0; | ||
305 | } | ||
306 | |||
307 | static int __init dmi_disable_osi_win8(const struct dmi_system_id *d) | ||
308 | { | ||
309 | pr_notice("DMI detected: %s\n", d->ident); | ||
310 | acpi_osi_setup("!Windows 2012"); | ||
311 | |||
312 | return 0; | ||
313 | } | ||
314 | |||
315 | /* | ||
316 | * Linux default _OSI response behavior is determined by this DMI table. | ||
317 | * | ||
318 | * Note that _OSI("Linux")/_OSI("Darwin") determined here can be overridden | ||
319 | * by acpi_osi=!Linux/acpi_osi=!Darwin command line options. | ||
320 | */ | ||
321 | static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { | ||
322 | { | ||
323 | .callback = dmi_disable_osi_vista, | ||
324 | .ident = "Fujitsu Siemens", | ||
325 | .matches = { | ||
326 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), | ||
327 | DMI_MATCH(DMI_PRODUCT_NAME, "ESPRIMO Mobile V5505"), | ||
328 | }, | ||
329 | }, | ||
330 | { | ||
331 | /* | ||
332 | * There have a NVIF method in MSI GX723 DSDT need call by Nvidia | ||
333 | * driver (e.g. nouveau) when user press brightness hotkey. | ||
334 | * Currently, nouveau driver didn't do the job and it causes there | ||
335 | * have a infinite while loop in DSDT when user press hotkey. | ||
336 | * We add MSI GX723's dmi information to this table for workaround | ||
337 | * this issue. | ||
338 | * Will remove MSI GX723 from the table after nouveau grows support. | ||
339 | */ | ||
340 | .callback = dmi_disable_osi_vista, | ||
341 | .ident = "MSI GX723", | ||
342 | .matches = { | ||
343 | DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"), | ||
344 | DMI_MATCH(DMI_PRODUCT_NAME, "GX723"), | ||
345 | }, | ||
346 | }, | ||
347 | { | ||
348 | .callback = dmi_disable_osi_vista, | ||
349 | .ident = "Sony VGN-NS10J_S", | ||
350 | .matches = { | ||
351 | DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), | ||
352 | DMI_MATCH(DMI_PRODUCT_NAME, "VGN-NS10J_S"), | ||
353 | }, | ||
354 | }, | ||
355 | { | ||
356 | .callback = dmi_disable_osi_vista, | ||
357 | .ident = "Sony VGN-SR290J", | ||
358 | .matches = { | ||
359 | DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), | ||
360 | DMI_MATCH(DMI_PRODUCT_NAME, "VGN-SR290J"), | ||
361 | }, | ||
362 | }, | ||
363 | { | ||
364 | .callback = dmi_disable_osi_vista, | ||
365 | .ident = "VGN-NS50B_L", | ||
366 | .matches = { | ||
367 | DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), | ||
368 | DMI_MATCH(DMI_PRODUCT_NAME, "VGN-NS50B_L"), | ||
369 | }, | ||
370 | }, | ||
371 | { | ||
372 | .callback = dmi_disable_osi_vista, | ||
373 | .ident = "VGN-SR19XN", | ||
374 | .matches = { | ||
375 | DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), | ||
376 | DMI_MATCH(DMI_PRODUCT_NAME, "VGN-SR19XN"), | ||
377 | }, | ||
378 | }, | ||
379 | { | ||
380 | .callback = dmi_disable_osi_vista, | ||
381 | .ident = "Toshiba Satellite L355", | ||
382 | .matches = { | ||
383 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | ||
384 | DMI_MATCH(DMI_PRODUCT_VERSION, "Satellite L355"), | ||
385 | }, | ||
386 | }, | ||
387 | { | ||
388 | .callback = dmi_disable_osi_win7, | ||
389 | .ident = "ASUS K50IJ", | ||
390 | .matches = { | ||
391 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), | ||
392 | DMI_MATCH(DMI_PRODUCT_NAME, "K50IJ"), | ||
393 | }, | ||
394 | }, | ||
395 | { | ||
396 | .callback = dmi_disable_osi_vista, | ||
397 | .ident = "Toshiba P305D", | ||
398 | .matches = { | ||
399 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | ||
400 | DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P305D"), | ||
401 | }, | ||
402 | }, | ||
403 | { | ||
404 | .callback = dmi_disable_osi_vista, | ||
405 | .ident = "Toshiba NB100", | ||
406 | .matches = { | ||
407 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | ||
408 | DMI_MATCH(DMI_PRODUCT_NAME, "NB100"), | ||
409 | }, | ||
410 | }, | ||
411 | |||
412 | /* | ||
413 | * The wireless hotkey does not work on those machines when | ||
414 | * returning true for _OSI("Windows 2012") | ||
415 | */ | ||
416 | { | ||
417 | .callback = dmi_disable_osi_win8, | ||
418 | .ident = "Dell Inspiron 7737", | ||
419 | .matches = { | ||
420 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
421 | DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 7737"), | ||
422 | }, | ||
423 | }, | ||
424 | { | ||
425 | .callback = dmi_disable_osi_win8, | ||
426 | .ident = "Dell Inspiron 7537", | ||
427 | .matches = { | ||
428 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
429 | DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 7537"), | ||
430 | }, | ||
431 | }, | ||
432 | { | ||
433 | .callback = dmi_disable_osi_win8, | ||
434 | .ident = "Dell Inspiron 5437", | ||
435 | .matches = { | ||
436 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
437 | DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 5437"), | ||
438 | }, | ||
439 | }, | ||
440 | { | ||
441 | .callback = dmi_disable_osi_win8, | ||
442 | .ident = "Dell Inspiron 3437", | ||
443 | .matches = { | ||
444 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
445 | DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 3437"), | ||
446 | }, | ||
447 | }, | ||
448 | { | ||
449 | .callback = dmi_disable_osi_win8, | ||
450 | .ident = "Dell Vostro 3446", | ||
451 | .matches = { | ||
452 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
453 | DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 3446"), | ||
454 | }, | ||
455 | }, | ||
456 | { | ||
457 | .callback = dmi_disable_osi_win8, | ||
458 | .ident = "Dell Vostro 3546", | ||
459 | .matches = { | ||
460 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
461 | DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 3546"), | ||
462 | }, | ||
463 | }, | ||
464 | |||
465 | /* | ||
466 | * BIOS invocation of _OSI(Linux) is almost always a BIOS bug. | ||
467 | * Linux ignores it, except for the machines enumerated below. | ||
468 | */ | ||
469 | |||
470 | /* | ||
471 | * Without this this EEEpc exports a non working WMI interface, with | ||
472 | * this it exports a working "good old" eeepc_laptop interface, fixing | ||
473 | * both brightness control, and rfkill not working. | ||
474 | */ | ||
475 | { | ||
476 | .callback = dmi_enable_osi_linux, | ||
477 | .ident = "Asus EEE PC 1015PX", | ||
478 | .matches = { | ||
479 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer INC."), | ||
480 | DMI_MATCH(DMI_PRODUCT_NAME, "1015PX"), | ||
481 | }, | ||
482 | }, | ||
483 | |||
484 | /* | ||
485 | * Enable _OSI("Darwin") for all apple platforms. | ||
486 | */ | ||
487 | { | ||
488 | .callback = dmi_enable_osi_darwin, | ||
489 | .ident = "Apple hardware", | ||
490 | .matches = { | ||
491 | DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), | ||
492 | }, | ||
493 | }, | ||
494 | { | ||
495 | .callback = dmi_enable_osi_darwin, | ||
496 | .ident = "Apple hardware", | ||
497 | .matches = { | ||
498 | DMI_MATCH(DMI_SYS_VENDOR, "Apple Computer, Inc."), | ||
499 | }, | ||
500 | }, | ||
501 | {} | ||
502 | }; | ||
503 | |||
504 | static __init void acpi_osi_dmi_blacklisted(void) | ||
505 | { | ||
506 | dmi_check_system(acpi_osi_dmi_table); | ||
507 | } | ||
508 | |||
509 | int __init early_acpi_osi_init(void) | ||
510 | { | ||
511 | acpi_osi_dmi_blacklisted(); | ||
512 | |||
513 | return 0; | ||
514 | } | ||
515 | |||
516 | int __init acpi_osi_init(void) | ||
517 | { | ||
518 | acpi_install_interface_handler(acpi_osi_handler); | ||
519 | acpi_osi_setup_late(); | ||
520 | |||
521 | return 0; | ||
522 | } | ||
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 134051689d72..29af6b40c93f 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c | |||
@@ -96,74 +96,6 @@ struct acpi_ioremap { | |||
96 | static LIST_HEAD(acpi_ioremaps); | 96 | static LIST_HEAD(acpi_ioremaps); |
97 | static DEFINE_MUTEX(acpi_ioremap_lock); | 97 | static DEFINE_MUTEX(acpi_ioremap_lock); |
98 | 98 | ||
99 | static void __init acpi_osi_setup_late(void); | ||
100 | |||
101 | /* | ||
102 | * The story of _OSI(Linux) | ||
103 | * | ||
104 | * From pre-history through Linux-2.6.22, | ||
105 | * Linux responded TRUE upon a BIOS OSI(Linux) query. | ||
106 | * | ||
107 | * Unfortunately, reference BIOS writers got wind of this | ||
108 | * and put OSI(Linux) in their example code, quickly exposing | ||
109 | * this string as ill-conceived and opening the door to | ||
110 | * an un-bounded number of BIOS incompatibilities. | ||
111 | * | ||
112 | * For example, OSI(Linux) was used on resume to re-POST a | ||
113 | * video card on one system, because Linux at that time | ||
114 | * could not do a speedy restore in its native driver. | ||
115 | * But then upon gaining quick native restore capability, | ||
116 | * Linux has no way to tell the BIOS to skip the time-consuming | ||
117 | * POST -- putting Linux at a permanent performance disadvantage. | ||
118 | * On another system, the BIOS writer used OSI(Linux) | ||
119 | * to infer native OS support for IPMI! On other systems, | ||
120 | * OSI(Linux) simply got in the way of Linux claiming to | ||
121 | * be compatible with other operating systems, exposing | ||
122 | * BIOS issues such as skipped device initialization. | ||
123 | * | ||
124 | * So "Linux" turned out to be a really poor chose of | ||
125 | * OSI string, and from Linux-2.6.23 onward we respond FALSE. | ||
126 | * | ||
127 | * BIOS writers should NOT query _OSI(Linux) on future systems. | ||
128 | * Linux will complain on the console when it sees it, and return FALSE. | ||
129 | * To get Linux to return TRUE for your system will require | ||
130 | * a kernel source update to add a DMI entry, | ||
131 | * or boot with "acpi_osi=Linux" | ||
132 | */ | ||
133 | |||
134 | static struct acpi_osi_config { | ||
135 | unsigned int linux_enable:1; | ||
136 | unsigned int linux_dmi:1; | ||
137 | unsigned int linux_cmdline:1; | ||
138 | unsigned int darwin_enable:1; | ||
139 | unsigned int darwin_dmi:1; | ||
140 | unsigned int darwin_cmdline:1; | ||
141 | u8 default_disabling; | ||
142 | } osi_config; | ||
143 | |||
144 | static u32 acpi_osi_handler(acpi_string interface, u32 supported) | ||
145 | { | ||
146 | if (!strcmp("Linux", interface)) { | ||
147 | |||
148 | pr_notice_once(FW_BUG PREFIX | ||
149 | "BIOS _OSI(Linux) query %s%s\n", | ||
150 | osi_config.linux_enable ? "honored" : "ignored", | ||
151 | osi_config.linux_cmdline ? " via cmdline" : | ||
152 | osi_config.linux_dmi ? " via DMI" : ""); | ||
153 | } | ||
154 | |||
155 | if (!strcmp("Darwin", interface)) { | ||
156 | |||
157 | pr_notice_once(PREFIX | ||
158 | "BIOS _OSI(Darwin) query %s%s\n", | ||
159 | osi_config.darwin_enable ? "honored" : "ignored", | ||
160 | osi_config.darwin_cmdline ? " via cmdline" : | ||
161 | osi_config.darwin_dmi ? " via DMI" : ""); | ||
162 | } | ||
163 | |||
164 | return supported; | ||
165 | } | ||
166 | |||
167 | static void __init acpi_request_region (struct acpi_generic_address *gas, | 99 | static void __init acpi_request_region (struct acpi_generic_address *gas, |
168 | unsigned int length, char *desc) | 100 | unsigned int length, char *desc) |
169 | { | 101 | { |
@@ -1719,185 +1651,6 @@ static int __init acpi_os_name_setup(char *str) | |||
1719 | 1651 | ||
1720 | __setup("acpi_os_name=", acpi_os_name_setup); | 1652 | __setup("acpi_os_name=", acpi_os_name_setup); |
1721 | 1653 | ||
1722 | #define OSI_STRING_LENGTH_MAX 64 | ||
1723 | #define OSI_STRING_ENTRIES_MAX 16 | ||
1724 | |||
1725 | struct acpi_osi_entry { | ||
1726 | char string[OSI_STRING_LENGTH_MAX]; | ||
1727 | bool enable; | ||
1728 | }; | ||
1729 | |||
1730 | static struct acpi_osi_entry | ||
1731 | osi_setup_entries[OSI_STRING_ENTRIES_MAX] __initdata = { | ||
1732 | {"Module Device", true}, | ||
1733 | {"Processor Device", true}, | ||
1734 | {"3.0 _SCP Extensions", true}, | ||
1735 | {"Processor Aggregator Device", true}, | ||
1736 | }; | ||
1737 | |||
1738 | void __init acpi_osi_setup(char *str) | ||
1739 | { | ||
1740 | struct acpi_osi_entry *osi; | ||
1741 | bool enable = true; | ||
1742 | int i; | ||
1743 | |||
1744 | if (!acpi_gbl_create_osi_method) | ||
1745 | return; | ||
1746 | |||
1747 | if (str == NULL || *str == '\0') { | ||
1748 | pr_info(PREFIX "_OSI method disabled\n"); | ||
1749 | acpi_gbl_create_osi_method = FALSE; | ||
1750 | return; | ||
1751 | } | ||
1752 | |||
1753 | if (*str == '!') { | ||
1754 | str++; | ||
1755 | if (*str == '\0') { | ||
1756 | /* Do not override acpi_osi=!* */ | ||
1757 | if (!osi_config.default_disabling) | ||
1758 | osi_config.default_disabling = | ||
1759 | ACPI_DISABLE_ALL_VENDOR_STRINGS; | ||
1760 | return; | ||
1761 | } else if (*str == '*') { | ||
1762 | osi_config.default_disabling = ACPI_DISABLE_ALL_STRINGS; | ||
1763 | for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) { | ||
1764 | osi = &osi_setup_entries[i]; | ||
1765 | osi->enable = false; | ||
1766 | } | ||
1767 | return; | ||
1768 | } else if (*str == '!') { | ||
1769 | osi_config.default_disabling = 0; | ||
1770 | return; | ||
1771 | } | ||
1772 | enable = false; | ||
1773 | } | ||
1774 | |||
1775 | for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) { | ||
1776 | osi = &osi_setup_entries[i]; | ||
1777 | if (!strcmp(osi->string, str)) { | ||
1778 | osi->enable = enable; | ||
1779 | break; | ||
1780 | } else if (osi->string[0] == '\0') { | ||
1781 | osi->enable = enable; | ||
1782 | strncpy(osi->string, str, OSI_STRING_LENGTH_MAX); | ||
1783 | break; | ||
1784 | } | ||
1785 | } | ||
1786 | } | ||
1787 | |||
1788 | static void __init __acpi_osi_setup_darwin(bool enable) | ||
1789 | { | ||
1790 | osi_config.darwin_enable = !!enable; | ||
1791 | if (enable) { | ||
1792 | acpi_osi_setup("!"); | ||
1793 | acpi_osi_setup("Darwin"); | ||
1794 | } else { | ||
1795 | acpi_osi_setup("!!"); | ||
1796 | acpi_osi_setup("!Darwin"); | ||
1797 | } | ||
1798 | } | ||
1799 | |||
1800 | static void __init acpi_osi_setup_darwin(bool enable) | ||
1801 | { | ||
1802 | osi_config.darwin_cmdline = 1; | ||
1803 | osi_config.darwin_dmi = 0; | ||
1804 | __acpi_osi_setup_darwin(enable); | ||
1805 | } | ||
1806 | |||
1807 | void __init acpi_osi_dmi_darwin(bool enable, const struct dmi_system_id *d) | ||
1808 | { | ||
1809 | pr_notice(PREFIX "DMI detected to setup _OSI(\"Darwin\"): %s\n", | ||
1810 | d->ident); | ||
1811 | osi_config.darwin_dmi = 1; | ||
1812 | __acpi_osi_setup_darwin(enable); | ||
1813 | } | ||
1814 | |||
1815 | static void __init __acpi_osi_setup_linux(bool enable) | ||
1816 | { | ||
1817 | osi_config.linux_enable = !!enable; | ||
1818 | if (enable) | ||
1819 | acpi_osi_setup("Linux"); | ||
1820 | else | ||
1821 | acpi_osi_setup("!Linux"); | ||
1822 | } | ||
1823 | |||
1824 | static void __init acpi_osi_setup_linux(bool enable) | ||
1825 | { | ||
1826 | osi_config.linux_cmdline = 1; | ||
1827 | osi_config.linux_dmi = 0; | ||
1828 | __acpi_osi_setup_linux(enable); | ||
1829 | } | ||
1830 | |||
1831 | void __init acpi_osi_dmi_linux(bool enable, const struct dmi_system_id *d) | ||
1832 | { | ||
1833 | pr_notice(PREFIX "DMI detected to setup _OSI(\"Linux\"): %s\n", | ||
1834 | d->ident); | ||
1835 | osi_config.linux_dmi = 1; | ||
1836 | __acpi_osi_setup_linux(enable); | ||
1837 | } | ||
1838 | |||
1839 | /* | ||
1840 | * Modify the list of "OS Interfaces" reported to BIOS via _OSI | ||
1841 | * | ||
1842 | * empty string disables _OSI | ||
1843 | * string starting with '!' disables that string | ||
1844 | * otherwise string is added to list, augmenting built-in strings | ||
1845 | */ | ||
1846 | static void __init acpi_osi_setup_late(void) | ||
1847 | { | ||
1848 | struct acpi_osi_entry *osi; | ||
1849 | char *str; | ||
1850 | int i; | ||
1851 | acpi_status status; | ||
1852 | |||
1853 | if (osi_config.default_disabling) { | ||
1854 | status = acpi_update_interfaces(osi_config.default_disabling); | ||
1855 | |||
1856 | if (ACPI_SUCCESS(status)) | ||
1857 | pr_info(PREFIX "Disabled all _OSI OS vendors%s\n", | ||
1858 | osi_config.default_disabling == | ||
1859 | ACPI_DISABLE_ALL_STRINGS ? | ||
1860 | " and feature groups" : ""); | ||
1861 | } | ||
1862 | |||
1863 | for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) { | ||
1864 | osi = &osi_setup_entries[i]; | ||
1865 | str = osi->string; | ||
1866 | |||
1867 | if (*str == '\0') | ||
1868 | break; | ||
1869 | if (osi->enable) { | ||
1870 | status = acpi_install_interface(str); | ||
1871 | |||
1872 | if (ACPI_SUCCESS(status)) | ||
1873 | pr_info(PREFIX "Added _OSI(%s)\n", str); | ||
1874 | } else { | ||
1875 | status = acpi_remove_interface(str); | ||
1876 | |||
1877 | if (ACPI_SUCCESS(status)) | ||
1878 | pr_info(PREFIX "Deleted _OSI(%s)\n", str); | ||
1879 | } | ||
1880 | } | ||
1881 | } | ||
1882 | |||
1883 | static int __init osi_setup(char *str) | ||
1884 | { | ||
1885 | if (str && !strcmp("Linux", str)) | ||
1886 | acpi_osi_setup_linux(true); | ||
1887 | else if (str && !strcmp("!Linux", str)) | ||
1888 | acpi_osi_setup_linux(false); | ||
1889 | else if (str && !strcmp("Darwin", str)) | ||
1890 | acpi_osi_setup_darwin(true); | ||
1891 | else if (str && !strcmp("!Darwin", str)) | ||
1892 | acpi_osi_setup_darwin(false); | ||
1893 | else | ||
1894 | acpi_osi_setup(str); | ||
1895 | |||
1896 | return 1; | ||
1897 | } | ||
1898 | |||
1899 | __setup("acpi_osi=", osi_setup); | ||
1900 | |||
1901 | /* | 1654 | /* |
1902 | * Disable the auto-serialization of named objects creation methods. | 1655 | * Disable the auto-serialization of named objects creation methods. |
1903 | * | 1656 | * |
@@ -2017,12 +1770,6 @@ int acpi_resources_are_enforced(void) | |||
2017 | } | 1770 | } |
2018 | EXPORT_SYMBOL(acpi_resources_are_enforced); | 1771 | EXPORT_SYMBOL(acpi_resources_are_enforced); |
2019 | 1772 | ||
2020 | bool acpi_osi_is_win8(void) | ||
2021 | { | ||
2022 | return acpi_gbl_osi_data >= ACPI_OSI_WIN_8; | ||
2023 | } | ||
2024 | EXPORT_SYMBOL(acpi_osi_is_win8); | ||
2025 | |||
2026 | /* | 1773 | /* |
2027 | * Deallocate the memory for a spinlock. | 1774 | * Deallocate the memory for a spinlock. |
2028 | */ | 1775 | */ |
@@ -2188,8 +1935,7 @@ acpi_status __init acpi_os_initialize1(void) | |||
2188 | BUG_ON(!kacpid_wq); | 1935 | BUG_ON(!kacpid_wq); |
2189 | BUG_ON(!kacpi_notify_wq); | 1936 | BUG_ON(!kacpi_notify_wq); |
2190 | BUG_ON(!kacpi_hotplug_wq); | 1937 | BUG_ON(!kacpi_hotplug_wq); |
2191 | acpi_install_interface_handler(acpi_osi_handler); | 1938 | acpi_osi_init(); |
2192 | acpi_osi_setup_late(); | ||
2193 | return AE_OK; | 1939 | return AE_OK; |
2194 | } | 1940 | } |
2195 | 1941 | ||
diff --git a/include/linux/acpi.h b/include/linux/acpi.h index bf0adc611aad..58f707a399c2 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h | |||
@@ -359,8 +359,6 @@ extern bool wmi_has_guid(const char *guid); | |||
359 | extern char acpi_video_backlight_string[]; | 359 | extern char acpi_video_backlight_string[]; |
360 | extern long acpi_is_video_device(acpi_handle handle); | 360 | extern long acpi_is_video_device(acpi_handle handle); |
361 | extern int acpi_blacklisted(void); | 361 | extern int acpi_blacklisted(void); |
362 | extern void acpi_osi_dmi_linux(bool enable, const struct dmi_system_id *d); | ||
363 | extern void acpi_osi_dmi_darwin(bool enable, const struct dmi_system_id *d); | ||
364 | extern void acpi_osi_setup(char *str); | 362 | extern void acpi_osi_setup(char *str); |
365 | extern bool acpi_osi_is_win8(void); | 363 | extern bool acpi_osi_is_win8(void); |
366 | 364 | ||