diff options
Diffstat (limited to 'drivers/acpi')
131 files changed, 2524 insertions, 3109 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 6efe2ac6902f..5d9248526d78 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig | |||
@@ -56,23 +56,6 @@ config ACPI_PROCFS | |||
56 | 56 | ||
57 | Say N to delete /proc/acpi/ files that have moved to /sys/ | 57 | Say N to delete /proc/acpi/ files that have moved to /sys/ |
58 | 58 | ||
59 | config ACPI_PROCFS_POWER | ||
60 | bool "Deprecated power /proc/acpi directories" | ||
61 | depends on PROC_FS | ||
62 | help | ||
63 | For backwards compatibility, this option allows | ||
64 | deprecated power /proc/acpi/ directories to exist, even when | ||
65 | they have been replaced by functions in /sys. | ||
66 | The deprecated directories (and their replacements) include: | ||
67 | /proc/acpi/battery/* (/sys/class/power_supply/*) | ||
68 | /proc/acpi/ac_adapter/* (sys/class/power_supply/*) | ||
69 | This option has no effect on /proc/acpi/ directories | ||
70 | and functions, which do not yet exist in /sys | ||
71 | This option, together with the proc directories, will be | ||
72 | deleted in 2.6.39. | ||
73 | |||
74 | Say N to delete power /proc/acpi/ directories that have moved to /sys/ | ||
75 | |||
76 | config ACPI_EC_DEBUGFS | 59 | config ACPI_EC_DEBUGFS |
77 | tristate "EC read/write access through /sys/kernel/debug/ec" | 60 | tristate "EC read/write access through /sys/kernel/debug/ec" |
78 | default n | 61 | default n |
@@ -175,9 +158,10 @@ config ACPI_PROCESSOR | |||
175 | 158 | ||
176 | To compile this driver as a module, choose M here: | 159 | To compile this driver as a module, choose M here: |
177 | the module will be called processor. | 160 | the module will be called processor. |
161 | |||
178 | config ACPI_IPMI | 162 | config ACPI_IPMI |
179 | tristate "IPMI" | 163 | tristate "IPMI" |
180 | depends on IPMI_SI && IPMI_HANDLER | 164 | depends on IPMI_SI |
181 | default n | 165 | default n |
182 | help | 166 | help |
183 | This driver enables the ACPI to access the BMC controller. And it | 167 | This driver enables the ACPI to access the BMC controller. And it |
@@ -251,17 +235,6 @@ config ACPI_INITRD_TABLE_OVERRIDE | |||
251 | initrd, therefore it's safe to say Y. | 235 | initrd, therefore it's safe to say Y. |
252 | See Documentation/acpi/initrd_table_override.txt for details | 236 | See Documentation/acpi/initrd_table_override.txt for details |
253 | 237 | ||
254 | config ACPI_BLACKLIST_YEAR | ||
255 | int "Disable ACPI for systems before Jan 1st this year" if X86_32 | ||
256 | default 0 | ||
257 | help | ||
258 | Enter a 4-digit year, e.g., 2001, to disable ACPI by default | ||
259 | on platforms with DMI BIOS date before January 1st that year. | ||
260 | "acpi=force" can be used to override this mechanism. | ||
261 | |||
262 | Enter 0 to disable this mechanism and allow ACPI to | ||
263 | run by default no matter what the year. (default) | ||
264 | |||
265 | config ACPI_DEBUG | 238 | config ACPI_DEBUG |
266 | bool "Debug Statements" | 239 | bool "Debug Statements" |
267 | default n | 240 | default n |
@@ -372,4 +345,25 @@ config ACPI_BGRT | |||
372 | 345 | ||
373 | source "drivers/acpi/apei/Kconfig" | 346 | source "drivers/acpi/apei/Kconfig" |
374 | 347 | ||
348 | config ACPI_EXTLOG | ||
349 | tristate "Extended Error Log support" | ||
350 | depends on X86_MCE && X86_LOCAL_APIC | ||
351 | select EFI | ||
352 | select UEFI_CPER | ||
353 | default n | ||
354 | help | ||
355 | Certain usages such as Predictive Failure Analysis (PFA) require | ||
356 | more information about the error than what can be described in | ||
357 | processor machine check banks. Most server processors log | ||
358 | additional information about the error in processor uncore | ||
359 | registers. Since the addresses and layout of these registers vary | ||
360 | widely from one processor to another, system software cannot | ||
361 | readily make use of them. To complicate matters further, some of | ||
362 | the additional error information cannot be constructed without | ||
363 | detailed knowledge about platform topology. | ||
364 | |||
365 | Enhanced MCA Logging allows firmware to provide additional error | ||
366 | information to system software, synchronous with MCE or CMCI. This | ||
367 | driver adds support for that functionality. | ||
368 | |||
375 | endif # ACPI | 369 | endif # ACPI |
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index cdaf68b58b00..0331f91d56e6 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile | |||
@@ -47,7 +47,6 @@ acpi-y += sysfs.o | |||
47 | acpi-$(CONFIG_X86) += acpi_cmos_rtc.o | 47 | acpi-$(CONFIG_X86) += acpi_cmos_rtc.o |
48 | acpi-$(CONFIG_DEBUG_FS) += debugfs.o | 48 | acpi-$(CONFIG_DEBUG_FS) += debugfs.o |
49 | acpi-$(CONFIG_ACPI_NUMA) += numa.o | 49 | acpi-$(CONFIG_ACPI_NUMA) += numa.o |
50 | acpi-$(CONFIG_ACPI_PROCFS_POWER) += cm_sbs.o | ||
51 | ifdef CONFIG_ACPI_VIDEO | 50 | ifdef CONFIG_ACPI_VIDEO |
52 | acpi-y += video_detect.o | 51 | acpi-y += video_detect.o |
53 | endif | 52 | endif |
@@ -82,3 +81,5 @@ processor-$(CONFIG_CPU_FREQ) += processor_perflib.o | |||
82 | obj-$(CONFIG_ACPI_PROCESSOR_AGGREGATOR) += acpi_pad.o | 81 | obj-$(CONFIG_ACPI_PROCESSOR_AGGREGATOR) += acpi_pad.o |
83 | 82 | ||
84 | obj-$(CONFIG_ACPI_APEI) += apei/ | 83 | obj-$(CONFIG_ACPI_APEI) += apei/ |
84 | |||
85 | obj-$(CONFIG_ACPI_EXTLOG) += acpi_extlog.o | ||
diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c index f37beaa32750..8711e3797165 100644 --- a/drivers/acpi/ac.c +++ b/drivers/acpi/ac.c | |||
@@ -30,10 +30,7 @@ | |||
30 | #include <linux/types.h> | 30 | #include <linux/types.h> |
31 | #include <linux/dmi.h> | 31 | #include <linux/dmi.h> |
32 | #include <linux/delay.h> | 32 | #include <linux/delay.h> |
33 | #ifdef CONFIG_ACPI_PROCFS_POWER | 33 | #include <linux/platform_device.h> |
34 | #include <linux/proc_fs.h> | ||
35 | #include <linux/seq_file.h> | ||
36 | #endif | ||
37 | #include <linux/power_supply.h> | 34 | #include <linux/power_supply.h> |
38 | #include <acpi/acpi_bus.h> | 35 | #include <acpi/acpi_bus.h> |
39 | #include <acpi/acpi_drivers.h> | 36 | #include <acpi/acpi_drivers.h> |
@@ -55,75 +52,30 @@ MODULE_AUTHOR("Paul Diefenbaugh"); | |||
55 | MODULE_DESCRIPTION("ACPI AC Adapter Driver"); | 52 | MODULE_DESCRIPTION("ACPI AC Adapter Driver"); |
56 | MODULE_LICENSE("GPL"); | 53 | MODULE_LICENSE("GPL"); |
57 | 54 | ||
58 | #ifdef CONFIG_ACPI_PROCFS_POWER | ||
59 | extern struct proc_dir_entry *acpi_lock_ac_dir(void); | ||
60 | extern void *acpi_unlock_ac_dir(struct proc_dir_entry *acpi_ac_dir); | ||
61 | static int acpi_ac_open_fs(struct inode *inode, struct file *file); | ||
62 | #endif | ||
63 | |||
64 | static int acpi_ac_add(struct acpi_device *device); | ||
65 | static int acpi_ac_remove(struct acpi_device *device); | ||
66 | static void acpi_ac_notify(struct acpi_device *device, u32 event); | ||
67 | |||
68 | static const struct acpi_device_id ac_device_ids[] = { | ||
69 | {"ACPI0003", 0}, | ||
70 | {"", 0}, | ||
71 | }; | ||
72 | MODULE_DEVICE_TABLE(acpi, ac_device_ids); | ||
73 | |||
74 | #ifdef CONFIG_PM_SLEEP | ||
75 | static int acpi_ac_resume(struct device *dev); | ||
76 | #endif | ||
77 | static SIMPLE_DEV_PM_OPS(acpi_ac_pm, NULL, acpi_ac_resume); | ||
78 | |||
79 | static int ac_sleep_before_get_state_ms; | 55 | static int ac_sleep_before_get_state_ms; |
80 | 56 | ||
81 | static struct acpi_driver acpi_ac_driver = { | ||
82 | .name = "ac", | ||
83 | .class = ACPI_AC_CLASS, | ||
84 | .ids = ac_device_ids, | ||
85 | .flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS, | ||
86 | .ops = { | ||
87 | .add = acpi_ac_add, | ||
88 | .remove = acpi_ac_remove, | ||
89 | .notify = acpi_ac_notify, | ||
90 | }, | ||
91 | .drv.pm = &acpi_ac_pm, | ||
92 | }; | ||
93 | |||
94 | struct acpi_ac { | 57 | struct acpi_ac { |
95 | struct power_supply charger; | 58 | struct power_supply charger; |
96 | struct acpi_device * device; | 59 | struct platform_device *pdev; |
97 | unsigned long long state; | 60 | unsigned long long state; |
98 | }; | 61 | }; |
99 | 62 | ||
100 | #define to_acpi_ac(x) container_of(x, struct acpi_ac, charger) | 63 | #define to_acpi_ac(x) container_of(x, struct acpi_ac, charger) |
101 | 64 | ||
102 | #ifdef CONFIG_ACPI_PROCFS_POWER | ||
103 | static const struct file_operations acpi_ac_fops = { | ||
104 | .owner = THIS_MODULE, | ||
105 | .open = acpi_ac_open_fs, | ||
106 | .read = seq_read, | ||
107 | .llseek = seq_lseek, | ||
108 | .release = single_release, | ||
109 | }; | ||
110 | #endif | ||
111 | |||
112 | /* -------------------------------------------------------------------------- | 65 | /* -------------------------------------------------------------------------- |
113 | AC Adapter Management | 66 | AC Adapter Management |
114 | -------------------------------------------------------------------------- */ | 67 | -------------------------------------------------------------------------- */ |
115 | 68 | ||
116 | static int acpi_ac_get_state(struct acpi_ac *ac) | 69 | static int acpi_ac_get_state(struct acpi_ac *ac) |
117 | { | 70 | { |
118 | acpi_status status = AE_OK; | 71 | acpi_status status; |
119 | 72 | acpi_handle handle = ACPI_HANDLE(&ac->pdev->dev); | |
120 | |||
121 | if (!ac) | ||
122 | return -EINVAL; | ||
123 | 73 | ||
124 | status = acpi_evaluate_integer(ac->device->handle, "_PSR", NULL, &ac->state); | 74 | status = acpi_evaluate_integer(handle, "_PSR", NULL, |
75 | &ac->state); | ||
125 | if (ACPI_FAILURE(status)) { | 76 | if (ACPI_FAILURE(status)) { |
126 | ACPI_EXCEPTION((AE_INFO, status, "Error reading AC Adapter state")); | 77 | ACPI_EXCEPTION((AE_INFO, status, |
78 | "Error reading AC Adapter state")); | ||
127 | ac->state = ACPI_AC_STATUS_UNKNOWN; | 79 | ac->state = ACPI_AC_STATUS_UNKNOWN; |
128 | return -ENODEV; | 80 | return -ENODEV; |
129 | } | 81 | } |
@@ -160,91 +112,14 @@ static enum power_supply_property ac_props[] = { | |||
160 | POWER_SUPPLY_PROP_ONLINE, | 112 | POWER_SUPPLY_PROP_ONLINE, |
161 | }; | 113 | }; |
162 | 114 | ||
163 | #ifdef CONFIG_ACPI_PROCFS_POWER | ||
164 | /* -------------------------------------------------------------------------- | ||
165 | FS Interface (/proc) | ||
166 | -------------------------------------------------------------------------- */ | ||
167 | |||
168 | static struct proc_dir_entry *acpi_ac_dir; | ||
169 | |||
170 | static int acpi_ac_seq_show(struct seq_file *seq, void *offset) | ||
171 | { | ||
172 | struct acpi_ac *ac = seq->private; | ||
173 | |||
174 | |||
175 | if (!ac) | ||
176 | return 0; | ||
177 | |||
178 | if (acpi_ac_get_state(ac)) { | ||
179 | seq_puts(seq, "ERROR: Unable to read AC Adapter state\n"); | ||
180 | return 0; | ||
181 | } | ||
182 | |||
183 | seq_puts(seq, "state: "); | ||
184 | switch (ac->state) { | ||
185 | case ACPI_AC_STATUS_OFFLINE: | ||
186 | seq_puts(seq, "off-line\n"); | ||
187 | break; | ||
188 | case ACPI_AC_STATUS_ONLINE: | ||
189 | seq_puts(seq, "on-line\n"); | ||
190 | break; | ||
191 | default: | ||
192 | seq_puts(seq, "unknown\n"); | ||
193 | break; | ||
194 | } | ||
195 | |||
196 | return 0; | ||
197 | } | ||
198 | |||
199 | static int acpi_ac_open_fs(struct inode *inode, struct file *file) | ||
200 | { | ||
201 | return single_open(file, acpi_ac_seq_show, PDE_DATA(inode)); | ||
202 | } | ||
203 | |||
204 | static int acpi_ac_add_fs(struct acpi_device *device) | ||
205 | { | ||
206 | struct proc_dir_entry *entry = NULL; | ||
207 | |||
208 | printk(KERN_WARNING PREFIX "Deprecated procfs I/F for AC is loaded," | ||
209 | " please retry with CONFIG_ACPI_PROCFS_POWER cleared\n"); | ||
210 | if (!acpi_device_dir(device)) { | ||
211 | acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), | ||
212 | acpi_ac_dir); | ||
213 | if (!acpi_device_dir(device)) | ||
214 | return -ENODEV; | ||
215 | } | ||
216 | |||
217 | /* 'state' [R] */ | ||
218 | entry = proc_create_data(ACPI_AC_FILE_STATE, | ||
219 | S_IRUGO, acpi_device_dir(device), | ||
220 | &acpi_ac_fops, acpi_driver_data(device)); | ||
221 | if (!entry) | ||
222 | return -ENODEV; | ||
223 | return 0; | ||
224 | } | ||
225 | |||
226 | static int acpi_ac_remove_fs(struct acpi_device *device) | ||
227 | { | ||
228 | |||
229 | if (acpi_device_dir(device)) { | ||
230 | remove_proc_entry(ACPI_AC_FILE_STATE, acpi_device_dir(device)); | ||
231 | |||
232 | remove_proc_entry(acpi_device_bid(device), acpi_ac_dir); | ||
233 | acpi_device_dir(device) = NULL; | ||
234 | } | ||
235 | |||
236 | return 0; | ||
237 | } | ||
238 | #endif | ||
239 | |||
240 | /* -------------------------------------------------------------------------- | 115 | /* -------------------------------------------------------------------------- |
241 | Driver Model | 116 | Driver Model |
242 | -------------------------------------------------------------------------- */ | 117 | -------------------------------------------------------------------------- */ |
243 | 118 | ||
244 | static void acpi_ac_notify(struct acpi_device *device, u32 event) | 119 | static void acpi_ac_notify_handler(acpi_handle handle, u32 event, void *data) |
245 | { | 120 | { |
246 | struct acpi_ac *ac = acpi_driver_data(device); | 121 | struct acpi_ac *ac = data; |
247 | 122 | struct acpi_device *adev; | |
248 | 123 | ||
249 | if (!ac) | 124 | if (!ac) |
250 | return; | 125 | return; |
@@ -267,10 +142,11 @@ static void acpi_ac_notify(struct acpi_device *device, u32 event) | |||
267 | msleep(ac_sleep_before_get_state_ms); | 142 | msleep(ac_sleep_before_get_state_ms); |
268 | 143 | ||
269 | acpi_ac_get_state(ac); | 144 | acpi_ac_get_state(ac); |
270 | acpi_bus_generate_netlink_event(device->pnp.device_class, | 145 | adev = ACPI_COMPANION(&ac->pdev->dev); |
271 | dev_name(&device->dev), event, | 146 | acpi_bus_generate_netlink_event(adev->pnp.device_class, |
272 | (u32) ac->state); | 147 | dev_name(&ac->pdev->dev), |
273 | acpi_notifier_call_chain(device, event, (u32) ac->state); | 148 | event, (u32) ac->state); |
149 | acpi_notifier_call_chain(adev, event, (u32) ac->state); | ||
274 | kobject_uevent(&ac->charger.dev->kobj, KOBJ_CHANGE); | 150 | kobject_uevent(&ac->charger.dev->kobj, KOBJ_CHANGE); |
275 | } | 151 | } |
276 | 152 | ||
@@ -295,53 +171,54 @@ static struct dmi_system_id ac_dmi_table[] = { | |||
295 | {}, | 171 | {}, |
296 | }; | 172 | }; |
297 | 173 | ||
298 | static int acpi_ac_add(struct acpi_device *device) | 174 | static int acpi_ac_probe(struct platform_device *pdev) |
299 | { | 175 | { |
300 | int result = 0; | 176 | int result = 0; |
301 | struct acpi_ac *ac = NULL; | 177 | struct acpi_ac *ac = NULL; |
178 | struct acpi_device *adev; | ||
302 | 179 | ||
303 | 180 | if (!pdev) | |
304 | if (!device) | ||
305 | return -EINVAL; | 181 | return -EINVAL; |
306 | 182 | ||
183 | adev = ACPI_COMPANION(&pdev->dev); | ||
184 | if (!adev) | ||
185 | return -ENODEV; | ||
186 | |||
307 | ac = kzalloc(sizeof(struct acpi_ac), GFP_KERNEL); | 187 | ac = kzalloc(sizeof(struct acpi_ac), GFP_KERNEL); |
308 | if (!ac) | 188 | if (!ac) |
309 | return -ENOMEM; | 189 | return -ENOMEM; |
310 | 190 | ||
311 | ac->device = device; | 191 | strcpy(acpi_device_name(adev), ACPI_AC_DEVICE_NAME); |
312 | strcpy(acpi_device_name(device), ACPI_AC_DEVICE_NAME); | 192 | strcpy(acpi_device_class(adev), ACPI_AC_CLASS); |
313 | strcpy(acpi_device_class(device), ACPI_AC_CLASS); | 193 | ac->pdev = pdev; |
314 | device->driver_data = ac; | 194 | platform_set_drvdata(pdev, ac); |
315 | 195 | ||
316 | result = acpi_ac_get_state(ac); | 196 | result = acpi_ac_get_state(ac); |
317 | if (result) | 197 | if (result) |
318 | goto end; | 198 | goto end; |
319 | 199 | ||
320 | #ifdef CONFIG_ACPI_PROCFS_POWER | 200 | ac->charger.name = acpi_device_bid(adev); |
321 | result = acpi_ac_add_fs(device); | ||
322 | #endif | ||
323 | if (result) | ||
324 | goto end; | ||
325 | ac->charger.name = acpi_device_bid(device); | ||
326 | ac->charger.type = POWER_SUPPLY_TYPE_MAINS; | 201 | ac->charger.type = POWER_SUPPLY_TYPE_MAINS; |
327 | ac->charger.properties = ac_props; | 202 | ac->charger.properties = ac_props; |
328 | ac->charger.num_properties = ARRAY_SIZE(ac_props); | 203 | ac->charger.num_properties = ARRAY_SIZE(ac_props); |
329 | ac->charger.get_property = get_ac_property; | 204 | ac->charger.get_property = get_ac_property; |
330 | result = power_supply_register(&ac->device->dev, &ac->charger); | 205 | result = power_supply_register(&pdev->dev, &ac->charger); |
331 | if (result) | 206 | if (result) |
332 | goto end; | 207 | goto end; |
333 | 208 | ||
209 | result = acpi_install_notify_handler(ACPI_HANDLE(&pdev->dev), | ||
210 | ACPI_DEVICE_NOTIFY, acpi_ac_notify_handler, ac); | ||
211 | if (result) { | ||
212 | power_supply_unregister(&ac->charger); | ||
213 | goto end; | ||
214 | } | ||
334 | printk(KERN_INFO PREFIX "%s [%s] (%s)\n", | 215 | printk(KERN_INFO PREFIX "%s [%s] (%s)\n", |
335 | acpi_device_name(device), acpi_device_bid(device), | 216 | acpi_device_name(adev), acpi_device_bid(adev), |
336 | ac->state ? "on-line" : "off-line"); | 217 | ac->state ? "on-line" : "off-line"); |
337 | 218 | ||
338 | end: | 219 | end: |
339 | if (result) { | 220 | if (result) |
340 | #ifdef CONFIG_ACPI_PROCFS_POWER | ||
341 | acpi_ac_remove_fs(device); | ||
342 | #endif | ||
343 | kfree(ac); | 221 | kfree(ac); |
344 | } | ||
345 | 222 | ||
346 | dmi_check_system(ac_dmi_table); | 223 | dmi_check_system(ac_dmi_table); |
347 | return result; | 224 | return result; |
@@ -356,7 +233,7 @@ static int acpi_ac_resume(struct device *dev) | |||
356 | if (!dev) | 233 | if (!dev) |
357 | return -EINVAL; | 234 | return -EINVAL; |
358 | 235 | ||
359 | ac = acpi_driver_data(to_acpi_device(dev)); | 236 | ac = platform_get_drvdata(to_platform_device(dev)); |
360 | if (!ac) | 237 | if (!ac) |
361 | return -EINVAL; | 238 | return -EINVAL; |
362 | 239 | ||
@@ -368,28 +245,44 @@ static int acpi_ac_resume(struct device *dev) | |||
368 | return 0; | 245 | return 0; |
369 | } | 246 | } |
370 | #endif | 247 | #endif |
248 | static SIMPLE_DEV_PM_OPS(acpi_ac_pm_ops, NULL, acpi_ac_resume); | ||
371 | 249 | ||
372 | static int acpi_ac_remove(struct acpi_device *device) | 250 | static int acpi_ac_remove(struct platform_device *pdev) |
373 | { | 251 | { |
374 | struct acpi_ac *ac = NULL; | 252 | struct acpi_ac *ac; |
375 | |||
376 | 253 | ||
377 | if (!device || !acpi_driver_data(device)) | 254 | if (!pdev) |
378 | return -EINVAL; | 255 | return -EINVAL; |
379 | 256 | ||
380 | ac = acpi_driver_data(device); | 257 | acpi_remove_notify_handler(ACPI_HANDLE(&pdev->dev), |
258 | ACPI_DEVICE_NOTIFY, acpi_ac_notify_handler); | ||
381 | 259 | ||
260 | ac = platform_get_drvdata(pdev); | ||
382 | if (ac->charger.dev) | 261 | if (ac->charger.dev) |
383 | power_supply_unregister(&ac->charger); | 262 | power_supply_unregister(&ac->charger); |
384 | #ifdef CONFIG_ACPI_PROCFS_POWER | ||
385 | acpi_ac_remove_fs(device); | ||
386 | #endif | ||
387 | 263 | ||
388 | kfree(ac); | 264 | kfree(ac); |
389 | 265 | ||
390 | return 0; | 266 | return 0; |
391 | } | 267 | } |
392 | 268 | ||
269 | static const struct acpi_device_id acpi_ac_match[] = { | ||
270 | { "ACPI0003", 0 }, | ||
271 | { } | ||
272 | }; | ||
273 | MODULE_DEVICE_TABLE(acpi, acpi_ac_match); | ||
274 | |||
275 | static struct platform_driver acpi_ac_driver = { | ||
276 | .probe = acpi_ac_probe, | ||
277 | .remove = acpi_ac_remove, | ||
278 | .driver = { | ||
279 | .name = "acpi-ac", | ||
280 | .owner = THIS_MODULE, | ||
281 | .pm = &acpi_ac_pm_ops, | ||
282 | .acpi_match_table = ACPI_PTR(acpi_ac_match), | ||
283 | }, | ||
284 | }; | ||
285 | |||
393 | static int __init acpi_ac_init(void) | 286 | static int __init acpi_ac_init(void) |
394 | { | 287 | { |
395 | int result; | 288 | int result; |
@@ -397,34 +290,16 @@ static int __init acpi_ac_init(void) | |||
397 | if (acpi_disabled) | 290 | if (acpi_disabled) |
398 | return -ENODEV; | 291 | return -ENODEV; |
399 | 292 | ||
400 | #ifdef CONFIG_ACPI_PROCFS_POWER | 293 | result = platform_driver_register(&acpi_ac_driver); |
401 | acpi_ac_dir = acpi_lock_ac_dir(); | 294 | if (result < 0) |
402 | if (!acpi_ac_dir) | ||
403 | return -ENODEV; | 295 | return -ENODEV; |
404 | #endif | ||
405 | |||
406 | result = acpi_bus_register_driver(&acpi_ac_driver); | ||
407 | if (result < 0) { | ||
408 | #ifdef CONFIG_ACPI_PROCFS_POWER | ||
409 | acpi_unlock_ac_dir(acpi_ac_dir); | ||
410 | #endif | ||
411 | return -ENODEV; | ||
412 | } | ||
413 | 296 | ||
414 | return 0; | 297 | return 0; |
415 | } | 298 | } |
416 | 299 | ||
417 | static void __exit acpi_ac_exit(void) | 300 | static void __exit acpi_ac_exit(void) |
418 | { | 301 | { |
419 | 302 | platform_driver_unregister(&acpi_ac_driver); | |
420 | acpi_bus_unregister_driver(&acpi_ac_driver); | ||
421 | |||
422 | #ifdef CONFIG_ACPI_PROCFS_POWER | ||
423 | acpi_unlock_ac_dir(acpi_ac_dir); | ||
424 | #endif | ||
425 | |||
426 | return; | ||
427 | } | 303 | } |
428 | |||
429 | module_init(acpi_ac_init); | 304 | module_init(acpi_ac_init); |
430 | module_exit(acpi_ac_exit); | 305 | module_exit(acpi_ac_exit); |
diff --git a/drivers/acpi/acpi_extlog.c b/drivers/acpi/acpi_extlog.c new file mode 100644 index 000000000000..a6869e110ce5 --- /dev/null +++ b/drivers/acpi/acpi_extlog.c | |||
@@ -0,0 +1,327 @@ | |||
1 | /* | ||
2 | * Extended Error Log driver | ||
3 | * | ||
4 | * Copyright (C) 2013 Intel Corp. | ||
5 | * Author: Chen, Gong <gong.chen@intel.com> | ||
6 | * | ||
7 | * This file is licensed under GPLv2. | ||
8 | */ | ||
9 | |||
10 | #include <linux/module.h> | ||
11 | #include <linux/acpi.h> | ||
12 | #include <acpi/acpi_bus.h> | ||
13 | #include <linux/cper.h> | ||
14 | #include <linux/ratelimit.h> | ||
15 | #include <asm/cpu.h> | ||
16 | #include <asm/mce.h> | ||
17 | |||
18 | #include "apei/apei-internal.h" | ||
19 | |||
20 | #define EXT_ELOG_ENTRY_MASK GENMASK_ULL(51, 0) /* elog entry address mask */ | ||
21 | |||
22 | #define EXTLOG_DSM_REV 0x0 | ||
23 | #define EXTLOG_FN_QUERY 0x0 | ||
24 | #define EXTLOG_FN_ADDR 0x1 | ||
25 | |||
26 | #define FLAG_OS_OPTIN BIT(0) | ||
27 | #define EXTLOG_QUERY_L1_EXIST BIT(1) | ||
28 | #define ELOG_ENTRY_VALID (1ULL<<63) | ||
29 | #define ELOG_ENTRY_LEN 0x1000 | ||
30 | |||
31 | #define EMCA_BUG \ | ||
32 | "Can not request iomem region <0x%016llx-0x%016llx> - eMCA disabled\n" | ||
33 | |||
34 | struct extlog_l1_head { | ||
35 | u32 ver; /* Header Version */ | ||
36 | u32 hdr_len; /* Header Length */ | ||
37 | u64 total_len; /* entire L1 Directory length including this header */ | ||
38 | u64 elog_base; /* MCA Error Log Directory base address */ | ||
39 | u64 elog_len; /* MCA Error Log Directory length */ | ||
40 | u32 flags; /* bit 0 - OS/VMM Opt-in */ | ||
41 | u8 rev0[12]; | ||
42 | u32 entries; /* Valid L1 Directory entries per logical processor */ | ||
43 | u8 rev1[12]; | ||
44 | }; | ||
45 | |||
46 | static u8 extlog_dsm_uuid[] = "663E35AF-CC10-41A4-88EA-5470AF055295"; | ||
47 | |||
48 | /* L1 table related physical address */ | ||
49 | static u64 elog_base; | ||
50 | static size_t elog_size; | ||
51 | static u64 l1_dirbase; | ||
52 | static size_t l1_size; | ||
53 | |||
54 | /* L1 table related virtual address */ | ||
55 | static void __iomem *extlog_l1_addr; | ||
56 | static void __iomem *elog_addr; | ||
57 | |||
58 | static void *elog_buf; | ||
59 | |||
60 | static u64 *l1_entry_base; | ||
61 | static u32 l1_percpu_entry; | ||
62 | |||
63 | #define ELOG_IDX(cpu, bank) \ | ||
64 | (cpu_physical_id(cpu) * l1_percpu_entry + (bank)) | ||
65 | |||
66 | #define ELOG_ENTRY_DATA(idx) \ | ||
67 | (*(l1_entry_base + (idx))) | ||
68 | |||
69 | #define ELOG_ENTRY_ADDR(phyaddr) \ | ||
70 | (phyaddr - elog_base + (u8 *)elog_addr) | ||
71 | |||
72 | static struct acpi_generic_status *extlog_elog_entry_check(int cpu, int bank) | ||
73 | { | ||
74 | int idx; | ||
75 | u64 data; | ||
76 | struct acpi_generic_status *estatus; | ||
77 | |||
78 | WARN_ON(cpu < 0); | ||
79 | idx = ELOG_IDX(cpu, bank); | ||
80 | data = ELOG_ENTRY_DATA(idx); | ||
81 | if ((data & ELOG_ENTRY_VALID) == 0) | ||
82 | return NULL; | ||
83 | |||
84 | data &= EXT_ELOG_ENTRY_MASK; | ||
85 | estatus = (struct acpi_generic_status *)ELOG_ENTRY_ADDR(data); | ||
86 | |||
87 | /* if no valid data in elog entry, just return */ | ||
88 | if (estatus->block_status == 0) | ||
89 | return NULL; | ||
90 | |||
91 | return estatus; | ||
92 | } | ||
93 | |||
94 | static void __print_extlog_rcd(const char *pfx, | ||
95 | struct acpi_generic_status *estatus, int cpu) | ||
96 | { | ||
97 | static atomic_t seqno; | ||
98 | unsigned int curr_seqno; | ||
99 | char pfx_seq[64]; | ||
100 | |||
101 | if (!pfx) { | ||
102 | if (estatus->error_severity <= CPER_SEV_CORRECTED) | ||
103 | pfx = KERN_INFO; | ||
104 | else | ||
105 | pfx = KERN_ERR; | ||
106 | } | ||
107 | curr_seqno = atomic_inc_return(&seqno); | ||
108 | snprintf(pfx_seq, sizeof(pfx_seq), "%s{%u}", pfx, curr_seqno); | ||
109 | printk("%s""Hardware error detected on CPU%d\n", pfx_seq, cpu); | ||
110 | cper_estatus_print(pfx_seq, estatus); | ||
111 | } | ||
112 | |||
113 | static int print_extlog_rcd(const char *pfx, | ||
114 | struct acpi_generic_status *estatus, int cpu) | ||
115 | { | ||
116 | /* Not more than 2 messages every 5 seconds */ | ||
117 | static DEFINE_RATELIMIT_STATE(ratelimit_corrected, 5*HZ, 2); | ||
118 | static DEFINE_RATELIMIT_STATE(ratelimit_uncorrected, 5*HZ, 2); | ||
119 | struct ratelimit_state *ratelimit; | ||
120 | |||
121 | if (estatus->error_severity == CPER_SEV_CORRECTED || | ||
122 | (estatus->error_severity == CPER_SEV_INFORMATIONAL)) | ||
123 | ratelimit = &ratelimit_corrected; | ||
124 | else | ||
125 | ratelimit = &ratelimit_uncorrected; | ||
126 | if (__ratelimit(ratelimit)) { | ||
127 | __print_extlog_rcd(pfx, estatus, cpu); | ||
128 | return 0; | ||
129 | } | ||
130 | |||
131 | return 1; | ||
132 | } | ||
133 | |||
134 | static int extlog_print(struct notifier_block *nb, unsigned long val, | ||
135 | void *data) | ||
136 | { | ||
137 | struct mce *mce = (struct mce *)data; | ||
138 | int bank = mce->bank; | ||
139 | int cpu = mce->extcpu; | ||
140 | struct acpi_generic_status *estatus; | ||
141 | int rc; | ||
142 | |||
143 | estatus = extlog_elog_entry_check(cpu, bank); | ||
144 | if (estatus == NULL) | ||
145 | return NOTIFY_DONE; | ||
146 | |||
147 | memcpy(elog_buf, (void *)estatus, ELOG_ENTRY_LEN); | ||
148 | /* clear record status to enable BIOS to update it again */ | ||
149 | estatus->block_status = 0; | ||
150 | |||
151 | rc = print_extlog_rcd(NULL, (struct acpi_generic_status *)elog_buf, cpu); | ||
152 | |||
153 | return NOTIFY_DONE; | ||
154 | } | ||
155 | |||
156 | static int extlog_get_dsm(acpi_handle handle, int rev, int func, u64 *ret) | ||
157 | { | ||
158 | struct acpi_buffer buf = {ACPI_ALLOCATE_BUFFER, NULL}; | ||
159 | struct acpi_object_list input; | ||
160 | union acpi_object params[4], *obj; | ||
161 | u8 uuid[16]; | ||
162 | int i; | ||
163 | |||
164 | acpi_str_to_uuid(extlog_dsm_uuid, uuid); | ||
165 | input.count = 4; | ||
166 | input.pointer = params; | ||
167 | params[0].type = ACPI_TYPE_BUFFER; | ||
168 | params[0].buffer.length = 16; | ||
169 | params[0].buffer.pointer = uuid; | ||
170 | params[1].type = ACPI_TYPE_INTEGER; | ||
171 | params[1].integer.value = rev; | ||
172 | params[2].type = ACPI_TYPE_INTEGER; | ||
173 | params[2].integer.value = func; | ||
174 | params[3].type = ACPI_TYPE_PACKAGE; | ||
175 | params[3].package.count = 0; | ||
176 | params[3].package.elements = NULL; | ||
177 | |||
178 | if (ACPI_FAILURE(acpi_evaluate_object(handle, "_DSM", &input, &buf))) | ||
179 | return -1; | ||
180 | |||
181 | *ret = 0; | ||
182 | obj = (union acpi_object *)buf.pointer; | ||
183 | if (obj->type == ACPI_TYPE_INTEGER) { | ||
184 | *ret = obj->integer.value; | ||
185 | } else if (obj->type == ACPI_TYPE_BUFFER) { | ||
186 | if (obj->buffer.length <= 8) { | ||
187 | for (i = 0; i < obj->buffer.length; i++) | ||
188 | *ret |= (obj->buffer.pointer[i] << (i * 8)); | ||
189 | } | ||
190 | } | ||
191 | kfree(buf.pointer); | ||
192 | |||
193 | return 0; | ||
194 | } | ||
195 | |||
196 | static bool extlog_get_l1addr(void) | ||
197 | { | ||
198 | acpi_handle handle; | ||
199 | u64 ret; | ||
200 | |||
201 | if (ACPI_FAILURE(acpi_get_handle(NULL, "\\_SB", &handle))) | ||
202 | return false; | ||
203 | |||
204 | if (extlog_get_dsm(handle, EXTLOG_DSM_REV, EXTLOG_FN_QUERY, &ret) || | ||
205 | !(ret & EXTLOG_QUERY_L1_EXIST)) | ||
206 | return false; | ||
207 | |||
208 | if (extlog_get_dsm(handle, EXTLOG_DSM_REV, EXTLOG_FN_ADDR, &ret)) | ||
209 | return false; | ||
210 | |||
211 | l1_dirbase = ret; | ||
212 | /* Spec says L1 directory must be 4K aligned, bail out if it isn't */ | ||
213 | if (l1_dirbase & ((1 << 12) - 1)) { | ||
214 | pr_warn(FW_BUG "L1 Directory is invalid at physical %llx\n", | ||
215 | l1_dirbase); | ||
216 | return false; | ||
217 | } | ||
218 | |||
219 | return true; | ||
220 | } | ||
221 | static struct notifier_block extlog_mce_dec = { | ||
222 | .notifier_call = extlog_print, | ||
223 | }; | ||
224 | |||
225 | static int __init extlog_init(void) | ||
226 | { | ||
227 | struct extlog_l1_head *l1_head; | ||
228 | void __iomem *extlog_l1_hdr; | ||
229 | size_t l1_hdr_size; | ||
230 | struct resource *r; | ||
231 | u64 cap; | ||
232 | int rc; | ||
233 | |||
234 | rc = -ENODEV; | ||
235 | |||
236 | rdmsrl(MSR_IA32_MCG_CAP, cap); | ||
237 | if (!(cap & MCG_ELOG_P)) | ||
238 | return rc; | ||
239 | |||
240 | if (!extlog_get_l1addr()) | ||
241 | return rc; | ||
242 | |||
243 | rc = -EINVAL; | ||
244 | /* get L1 header to fetch necessary information */ | ||
245 | l1_hdr_size = sizeof(struct extlog_l1_head); | ||
246 | r = request_mem_region(l1_dirbase, l1_hdr_size, "L1 DIR HDR"); | ||
247 | if (!r) { | ||
248 | pr_warn(FW_BUG EMCA_BUG, | ||
249 | (unsigned long long)l1_dirbase, | ||
250 | (unsigned long long)l1_dirbase + l1_hdr_size); | ||
251 | goto err; | ||
252 | } | ||
253 | |||
254 | extlog_l1_hdr = acpi_os_map_memory(l1_dirbase, l1_hdr_size); | ||
255 | l1_head = (struct extlog_l1_head *)extlog_l1_hdr; | ||
256 | l1_size = l1_head->total_len; | ||
257 | l1_percpu_entry = l1_head->entries; | ||
258 | elog_base = l1_head->elog_base; | ||
259 | elog_size = l1_head->elog_len; | ||
260 | acpi_os_unmap_memory(extlog_l1_hdr, l1_hdr_size); | ||
261 | release_mem_region(l1_dirbase, l1_hdr_size); | ||
262 | |||
263 | /* remap L1 header again based on completed information */ | ||
264 | r = request_mem_region(l1_dirbase, l1_size, "L1 Table"); | ||
265 | if (!r) { | ||
266 | pr_warn(FW_BUG EMCA_BUG, | ||
267 | (unsigned long long)l1_dirbase, | ||
268 | (unsigned long long)l1_dirbase + l1_size); | ||
269 | goto err; | ||
270 | } | ||
271 | extlog_l1_addr = acpi_os_map_memory(l1_dirbase, l1_size); | ||
272 | l1_entry_base = (u64 *)((u8 *)extlog_l1_addr + l1_hdr_size); | ||
273 | |||
274 | /* remap elog table */ | ||
275 | r = request_mem_region(elog_base, elog_size, "Elog Table"); | ||
276 | if (!r) { | ||
277 | pr_warn(FW_BUG EMCA_BUG, | ||
278 | (unsigned long long)elog_base, | ||
279 | (unsigned long long)elog_base + elog_size); | ||
280 | goto err_release_l1_dir; | ||
281 | } | ||
282 | elog_addr = acpi_os_map_memory(elog_base, elog_size); | ||
283 | |||
284 | rc = -ENOMEM; | ||
285 | /* allocate buffer to save elog record */ | ||
286 | elog_buf = kmalloc(ELOG_ENTRY_LEN, GFP_KERNEL); | ||
287 | if (elog_buf == NULL) | ||
288 | goto err_release_elog; | ||
289 | |||
290 | mce_register_decode_chain(&extlog_mce_dec); | ||
291 | /* enable OS to be involved to take over management from BIOS */ | ||
292 | ((struct extlog_l1_head *)extlog_l1_addr)->flags |= FLAG_OS_OPTIN; | ||
293 | |||
294 | return 0; | ||
295 | |||
296 | err_release_elog: | ||
297 | if (elog_addr) | ||
298 | acpi_os_unmap_memory(elog_addr, elog_size); | ||
299 | release_mem_region(elog_base, elog_size); | ||
300 | err_release_l1_dir: | ||
301 | if (extlog_l1_addr) | ||
302 | acpi_os_unmap_memory(extlog_l1_addr, l1_size); | ||
303 | release_mem_region(l1_dirbase, l1_size); | ||
304 | err: | ||
305 | pr_warn(FW_BUG "Extended error log disabled because of problems parsing f/w tables\n"); | ||
306 | return rc; | ||
307 | } | ||
308 | |||
309 | static void __exit extlog_exit(void) | ||
310 | { | ||
311 | mce_unregister_decode_chain(&extlog_mce_dec); | ||
312 | ((struct extlog_l1_head *)extlog_l1_addr)->flags &= ~FLAG_OS_OPTIN; | ||
313 | if (extlog_l1_addr) | ||
314 | acpi_os_unmap_memory(extlog_l1_addr, l1_size); | ||
315 | if (elog_addr) | ||
316 | acpi_os_unmap_memory(elog_addr, elog_size); | ||
317 | release_mem_region(elog_base, elog_size); | ||
318 | release_mem_region(l1_dirbase, l1_size); | ||
319 | kfree(elog_buf); | ||
320 | } | ||
321 | |||
322 | module_init(extlog_init); | ||
323 | module_exit(extlog_exit); | ||
324 | |||
325 | MODULE_AUTHOR("Chen, Gong <gong.chen@intel.com>"); | ||
326 | MODULE_DESCRIPTION("Extended MCA Error Log Driver"); | ||
327 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/acpi/acpi_ipmi.c b/drivers/acpi/acpi_ipmi.c index a6977e12d574..ac0f52f6df2b 100644 --- a/drivers/acpi/acpi_ipmi.c +++ b/drivers/acpi/acpi_ipmi.c | |||
@@ -1,8 +1,9 @@ | |||
1 | /* | 1 | /* |
2 | * acpi_ipmi.c - ACPI IPMI opregion | 2 | * acpi_ipmi.c - ACPI IPMI opregion |
3 | * | 3 | * |
4 | * Copyright (C) 2010 Intel Corporation | 4 | * Copyright (C) 2010, 2013 Intel Corporation |
5 | * Copyright (C) 2010 Zhao Yakui <yakui.zhao@intel.com> | 5 | * Author: Zhao Yakui <yakui.zhao@intel.com> |
6 | * Lv Zheng <lv.zheng@intel.com> | ||
6 | * | 7 | * |
7 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 8 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
8 | * | 9 | * |
@@ -23,60 +24,58 @@ | |||
23 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 24 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
24 | */ | 25 | */ |
25 | 26 | ||
26 | #include <linux/kernel.h> | ||
27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
28 | #include <linux/init.h> | 28 | #include <linux/acpi.h> |
29 | #include <linux/types.h> | ||
30 | #include <linux/delay.h> | ||
31 | #include <linux/proc_fs.h> | ||
32 | #include <linux/seq_file.h> | ||
33 | #include <linux/interrupt.h> | ||
34 | #include <linux/list.h> | ||
35 | #include <linux/spinlock.h> | ||
36 | #include <linux/io.h> | ||
37 | #include <acpi/acpi_bus.h> | ||
38 | #include <acpi/acpi_drivers.h> | ||
39 | #include <linux/ipmi.h> | 29 | #include <linux/ipmi.h> |
40 | #include <linux/device.h> | ||
41 | #include <linux/pnp.h> | ||
42 | #include <linux/spinlock.h> | 30 | #include <linux/spinlock.h> |
43 | 31 | ||
44 | MODULE_AUTHOR("Zhao Yakui"); | 32 | MODULE_AUTHOR("Zhao Yakui"); |
45 | MODULE_DESCRIPTION("ACPI IPMI Opregion driver"); | 33 | MODULE_DESCRIPTION("ACPI IPMI Opregion driver"); |
46 | MODULE_LICENSE("GPL"); | 34 | MODULE_LICENSE("GPL"); |
47 | 35 | ||
48 | #define IPMI_FLAGS_HANDLER_INSTALL 0 | ||
49 | |||
50 | #define ACPI_IPMI_OK 0 | 36 | #define ACPI_IPMI_OK 0 |
51 | #define ACPI_IPMI_TIMEOUT 0x10 | 37 | #define ACPI_IPMI_TIMEOUT 0x10 |
52 | #define ACPI_IPMI_UNKNOWN 0x07 | 38 | #define ACPI_IPMI_UNKNOWN 0x07 |
53 | /* the IPMI timeout is 5s */ | 39 | /* the IPMI timeout is 5s */ |
54 | #define IPMI_TIMEOUT (5 * HZ) | 40 | #define IPMI_TIMEOUT (5000) |
41 | #define ACPI_IPMI_MAX_MSG_LENGTH 64 | ||
55 | 42 | ||
56 | struct acpi_ipmi_device { | 43 | struct acpi_ipmi_device { |
57 | /* the device list attached to driver_data.ipmi_devices */ | 44 | /* the device list attached to driver_data.ipmi_devices */ |
58 | struct list_head head; | 45 | struct list_head head; |
46 | |||
59 | /* the IPMI request message list */ | 47 | /* the IPMI request message list */ |
60 | struct list_head tx_msg_list; | 48 | struct list_head tx_msg_list; |
61 | spinlock_t tx_msg_lock; | 49 | |
50 | spinlock_t tx_msg_lock; | ||
62 | acpi_handle handle; | 51 | acpi_handle handle; |
63 | struct pnp_dev *pnp_dev; | 52 | struct device *dev; |
64 | ipmi_user_t user_interface; | 53 | ipmi_user_t user_interface; |
65 | int ipmi_ifnum; /* IPMI interface number */ | 54 | int ipmi_ifnum; /* IPMI interface number */ |
66 | long curr_msgid; | 55 | long curr_msgid; |
67 | unsigned long flags; | 56 | bool dead; |
68 | struct ipmi_smi_info smi_data; | 57 | struct kref kref; |
69 | }; | 58 | }; |
70 | 59 | ||
71 | struct ipmi_driver_data { | 60 | struct ipmi_driver_data { |
72 | struct list_head ipmi_devices; | 61 | struct list_head ipmi_devices; |
73 | struct ipmi_smi_watcher bmc_events; | 62 | struct ipmi_smi_watcher bmc_events; |
74 | struct ipmi_user_hndl ipmi_hndlrs; | 63 | struct ipmi_user_hndl ipmi_hndlrs; |
75 | struct mutex ipmi_lock; | 64 | struct mutex ipmi_lock; |
65 | |||
66 | /* | ||
67 | * NOTE: IPMI System Interface Selection | ||
68 | * There is no system interface specified by the IPMI operation | ||
69 | * region access. We try to select one system interface with ACPI | ||
70 | * handle set. IPMI messages passed from the ACPI codes are sent | ||
71 | * to this selected global IPMI system interface. | ||
72 | */ | ||
73 | struct acpi_ipmi_device *selected_smi; | ||
76 | }; | 74 | }; |
77 | 75 | ||
78 | struct acpi_ipmi_msg { | 76 | struct acpi_ipmi_msg { |
79 | struct list_head head; | 77 | struct list_head head; |
78 | |||
80 | /* | 79 | /* |
81 | * General speaking the addr type should be SI_ADDR_TYPE. And | 80 | * General speaking the addr type should be SI_ADDR_TYPE. And |
82 | * the addr channel should be BMC. | 81 | * the addr channel should be BMC. |
@@ -86,30 +85,31 @@ struct acpi_ipmi_msg { | |||
86 | */ | 85 | */ |
87 | struct ipmi_addr addr; | 86 | struct ipmi_addr addr; |
88 | long tx_msgid; | 87 | long tx_msgid; |
88 | |||
89 | /* it is used to track whether the IPMI message is finished */ | 89 | /* it is used to track whether the IPMI message is finished */ |
90 | struct completion tx_complete; | 90 | struct completion tx_complete; |
91 | |||
91 | struct kernel_ipmi_msg tx_message; | 92 | struct kernel_ipmi_msg tx_message; |
92 | int msg_done; | 93 | int msg_done; |
93 | /* tx data . And copy it from ACPI object buffer */ | 94 | |
94 | u8 tx_data[64]; | 95 | /* tx/rx data . And copy it from/to ACPI object buffer */ |
95 | int tx_len; | 96 | u8 data[ACPI_IPMI_MAX_MSG_LENGTH]; |
96 | u8 rx_data[64]; | 97 | u8 rx_len; |
97 | int rx_len; | 98 | |
98 | struct acpi_ipmi_device *device; | 99 | struct acpi_ipmi_device *device; |
100 | struct kref kref; | ||
99 | }; | 101 | }; |
100 | 102 | ||
101 | /* IPMI request/response buffer per ACPI 4.0, sec 5.5.2.4.3.2 */ | 103 | /* IPMI request/response buffer per ACPI 4.0, sec 5.5.2.4.3.2 */ |
102 | struct acpi_ipmi_buffer { | 104 | struct acpi_ipmi_buffer { |
103 | u8 status; | 105 | u8 status; |
104 | u8 length; | 106 | u8 length; |
105 | u8 data[64]; | 107 | u8 data[ACPI_IPMI_MAX_MSG_LENGTH]; |
106 | }; | 108 | }; |
107 | 109 | ||
108 | static void ipmi_register_bmc(int iface, struct device *dev); | 110 | static void ipmi_register_bmc(int iface, struct device *dev); |
109 | static void ipmi_bmc_gone(int iface); | 111 | static void ipmi_bmc_gone(int iface); |
110 | static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data); | 112 | static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data); |
111 | static void acpi_add_ipmi_device(struct acpi_ipmi_device *ipmi_device); | ||
112 | static void acpi_remove_ipmi_device(struct acpi_ipmi_device *ipmi_device); | ||
113 | 113 | ||
114 | static struct ipmi_driver_data driver_data = { | 114 | static struct ipmi_driver_data driver_data = { |
115 | .ipmi_devices = LIST_HEAD_INIT(driver_data.ipmi_devices), | 115 | .ipmi_devices = LIST_HEAD_INIT(driver_data.ipmi_devices), |
@@ -121,29 +121,142 @@ static struct ipmi_driver_data driver_data = { | |||
121 | .ipmi_hndlrs = { | 121 | .ipmi_hndlrs = { |
122 | .ipmi_recv_hndl = ipmi_msg_handler, | 122 | .ipmi_recv_hndl = ipmi_msg_handler, |
123 | }, | 123 | }, |
124 | .ipmi_lock = __MUTEX_INITIALIZER(driver_data.ipmi_lock) | ||
124 | }; | 125 | }; |
125 | 126 | ||
126 | static struct acpi_ipmi_msg *acpi_alloc_ipmi_msg(struct acpi_ipmi_device *ipmi) | 127 | static struct acpi_ipmi_device * |
128 | ipmi_dev_alloc(int iface, struct device *dev, acpi_handle handle) | ||
129 | { | ||
130 | struct acpi_ipmi_device *ipmi_device; | ||
131 | int err; | ||
132 | ipmi_user_t user; | ||
133 | |||
134 | ipmi_device = kzalloc(sizeof(*ipmi_device), GFP_KERNEL); | ||
135 | if (!ipmi_device) | ||
136 | return NULL; | ||
137 | |||
138 | kref_init(&ipmi_device->kref); | ||
139 | INIT_LIST_HEAD(&ipmi_device->head); | ||
140 | INIT_LIST_HEAD(&ipmi_device->tx_msg_list); | ||
141 | spin_lock_init(&ipmi_device->tx_msg_lock); | ||
142 | ipmi_device->handle = handle; | ||
143 | ipmi_device->dev = get_device(dev); | ||
144 | ipmi_device->ipmi_ifnum = iface; | ||
145 | |||
146 | err = ipmi_create_user(iface, &driver_data.ipmi_hndlrs, | ||
147 | ipmi_device, &user); | ||
148 | if (err) { | ||
149 | put_device(dev); | ||
150 | kfree(ipmi_device); | ||
151 | return NULL; | ||
152 | } | ||
153 | ipmi_device->user_interface = user; | ||
154 | |||
155 | return ipmi_device; | ||
156 | } | ||
157 | |||
158 | static void ipmi_dev_release(struct acpi_ipmi_device *ipmi_device) | ||
159 | { | ||
160 | ipmi_destroy_user(ipmi_device->user_interface); | ||
161 | put_device(ipmi_device->dev); | ||
162 | kfree(ipmi_device); | ||
163 | } | ||
164 | |||
165 | static void ipmi_dev_release_kref(struct kref *kref) | ||
166 | { | ||
167 | struct acpi_ipmi_device *ipmi = | ||
168 | container_of(kref, struct acpi_ipmi_device, kref); | ||
169 | |||
170 | ipmi_dev_release(ipmi); | ||
171 | } | ||
172 | |||
173 | static void __ipmi_dev_kill(struct acpi_ipmi_device *ipmi_device) | ||
174 | { | ||
175 | list_del(&ipmi_device->head); | ||
176 | if (driver_data.selected_smi == ipmi_device) | ||
177 | driver_data.selected_smi = NULL; | ||
178 | |||
179 | /* | ||
180 | * Always setting dead flag after deleting from the list or | ||
181 | * list_for_each_entry() codes must get changed. | ||
182 | */ | ||
183 | ipmi_device->dead = true; | ||
184 | } | ||
185 | |||
186 | static struct acpi_ipmi_device *acpi_ipmi_dev_get(void) | ||
187 | { | ||
188 | struct acpi_ipmi_device *ipmi_device = NULL; | ||
189 | |||
190 | mutex_lock(&driver_data.ipmi_lock); | ||
191 | if (driver_data.selected_smi) { | ||
192 | ipmi_device = driver_data.selected_smi; | ||
193 | kref_get(&ipmi_device->kref); | ||
194 | } | ||
195 | mutex_unlock(&driver_data.ipmi_lock); | ||
196 | |||
197 | return ipmi_device; | ||
198 | } | ||
199 | |||
200 | static void acpi_ipmi_dev_put(struct acpi_ipmi_device *ipmi_device) | ||
201 | { | ||
202 | kref_put(&ipmi_device->kref, ipmi_dev_release_kref); | ||
203 | } | ||
204 | |||
205 | static struct acpi_ipmi_msg *ipmi_msg_alloc(void) | ||
127 | { | 206 | { |
207 | struct acpi_ipmi_device *ipmi; | ||
128 | struct acpi_ipmi_msg *ipmi_msg; | 208 | struct acpi_ipmi_msg *ipmi_msg; |
129 | struct pnp_dev *pnp_dev = ipmi->pnp_dev; | 209 | |
210 | ipmi = acpi_ipmi_dev_get(); | ||
211 | if (!ipmi) | ||
212 | return NULL; | ||
130 | 213 | ||
131 | ipmi_msg = kzalloc(sizeof(struct acpi_ipmi_msg), GFP_KERNEL); | 214 | ipmi_msg = kzalloc(sizeof(struct acpi_ipmi_msg), GFP_KERNEL); |
132 | if (!ipmi_msg) { | 215 | if (!ipmi_msg) { |
133 | dev_warn(&pnp_dev->dev, "Can't allocate memory for ipmi_msg\n"); | 216 | acpi_ipmi_dev_put(ipmi); |
134 | return NULL; | 217 | return NULL; |
135 | } | 218 | } |
219 | |||
220 | kref_init(&ipmi_msg->kref); | ||
136 | init_completion(&ipmi_msg->tx_complete); | 221 | init_completion(&ipmi_msg->tx_complete); |
137 | INIT_LIST_HEAD(&ipmi_msg->head); | 222 | INIT_LIST_HEAD(&ipmi_msg->head); |
138 | ipmi_msg->device = ipmi; | 223 | ipmi_msg->device = ipmi; |
224 | ipmi_msg->msg_done = ACPI_IPMI_UNKNOWN; | ||
225 | |||
139 | return ipmi_msg; | 226 | return ipmi_msg; |
140 | } | 227 | } |
141 | 228 | ||
142 | #define IPMI_OP_RGN_NETFN(offset) ((offset >> 8) & 0xff) | 229 | static void ipmi_msg_release(struct acpi_ipmi_msg *tx_msg) |
143 | #define IPMI_OP_RGN_CMD(offset) (offset & 0xff) | 230 | { |
144 | static void acpi_format_ipmi_msg(struct acpi_ipmi_msg *tx_msg, | 231 | acpi_ipmi_dev_put(tx_msg->device); |
145 | acpi_physical_address address, | 232 | kfree(tx_msg); |
146 | acpi_integer *value) | 233 | } |
234 | |||
235 | static void ipmi_msg_release_kref(struct kref *kref) | ||
236 | { | ||
237 | struct acpi_ipmi_msg *tx_msg = | ||
238 | container_of(kref, struct acpi_ipmi_msg, kref); | ||
239 | |||
240 | ipmi_msg_release(tx_msg); | ||
241 | } | ||
242 | |||
243 | static struct acpi_ipmi_msg *acpi_ipmi_msg_get(struct acpi_ipmi_msg *tx_msg) | ||
244 | { | ||
245 | kref_get(&tx_msg->kref); | ||
246 | |||
247 | return tx_msg; | ||
248 | } | ||
249 | |||
250 | static void acpi_ipmi_msg_put(struct acpi_ipmi_msg *tx_msg) | ||
251 | { | ||
252 | kref_put(&tx_msg->kref, ipmi_msg_release_kref); | ||
253 | } | ||
254 | |||
255 | #define IPMI_OP_RGN_NETFN(offset) ((offset >> 8) & 0xff) | ||
256 | #define IPMI_OP_RGN_CMD(offset) (offset & 0xff) | ||
257 | static int acpi_format_ipmi_request(struct acpi_ipmi_msg *tx_msg, | ||
258 | acpi_physical_address address, | ||
259 | acpi_integer *value) | ||
147 | { | 260 | { |
148 | struct kernel_ipmi_msg *msg; | 261 | struct kernel_ipmi_msg *msg; |
149 | struct acpi_ipmi_buffer *buffer; | 262 | struct acpi_ipmi_buffer *buffer; |
@@ -151,21 +264,31 @@ static void acpi_format_ipmi_msg(struct acpi_ipmi_msg *tx_msg, | |||
151 | unsigned long flags; | 264 | unsigned long flags; |
152 | 265 | ||
153 | msg = &tx_msg->tx_message; | 266 | msg = &tx_msg->tx_message; |
267 | |||
154 | /* | 268 | /* |
155 | * IPMI network function and command are encoded in the address | 269 | * IPMI network function and command are encoded in the address |
156 | * within the IPMI OpRegion; see ACPI 4.0, sec 5.5.2.4.3. | 270 | * within the IPMI OpRegion; see ACPI 4.0, sec 5.5.2.4.3. |
157 | */ | 271 | */ |
158 | msg->netfn = IPMI_OP_RGN_NETFN(address); | 272 | msg->netfn = IPMI_OP_RGN_NETFN(address); |
159 | msg->cmd = IPMI_OP_RGN_CMD(address); | 273 | msg->cmd = IPMI_OP_RGN_CMD(address); |
160 | msg->data = tx_msg->tx_data; | 274 | msg->data = tx_msg->data; |
275 | |||
161 | /* | 276 | /* |
162 | * value is the parameter passed by the IPMI opregion space handler. | 277 | * value is the parameter passed by the IPMI opregion space handler. |
163 | * It points to the IPMI request message buffer | 278 | * It points to the IPMI request message buffer |
164 | */ | 279 | */ |
165 | buffer = (struct acpi_ipmi_buffer *)value; | 280 | buffer = (struct acpi_ipmi_buffer *)value; |
281 | |||
166 | /* copy the tx message data */ | 282 | /* copy the tx message data */ |
283 | if (buffer->length > ACPI_IPMI_MAX_MSG_LENGTH) { | ||
284 | dev_WARN_ONCE(tx_msg->device->dev, true, | ||
285 | "Unexpected request (msg len %d).\n", | ||
286 | buffer->length); | ||
287 | return -EINVAL; | ||
288 | } | ||
167 | msg->data_len = buffer->length; | 289 | msg->data_len = buffer->length; |
168 | memcpy(tx_msg->tx_data, buffer->data, msg->data_len); | 290 | memcpy(tx_msg->data, buffer->data, msg->data_len); |
291 | |||
169 | /* | 292 | /* |
170 | * now the default type is SYSTEM_INTERFACE and channel type is BMC. | 293 | * now the default type is SYSTEM_INTERFACE and channel type is BMC. |
171 | * If the netfn is APP_REQUEST and the cmd is SEND_MESSAGE, | 294 | * If the netfn is APP_REQUEST and the cmd is SEND_MESSAGE, |
@@ -179,14 +302,17 @@ static void acpi_format_ipmi_msg(struct acpi_ipmi_msg *tx_msg, | |||
179 | 302 | ||
180 | /* Get the msgid */ | 303 | /* Get the msgid */ |
181 | device = tx_msg->device; | 304 | device = tx_msg->device; |
305 | |||
182 | spin_lock_irqsave(&device->tx_msg_lock, flags); | 306 | spin_lock_irqsave(&device->tx_msg_lock, flags); |
183 | device->curr_msgid++; | 307 | device->curr_msgid++; |
184 | tx_msg->tx_msgid = device->curr_msgid; | 308 | tx_msg->tx_msgid = device->curr_msgid; |
185 | spin_unlock_irqrestore(&device->tx_msg_lock, flags); | 309 | spin_unlock_irqrestore(&device->tx_msg_lock, flags); |
310 | |||
311 | return 0; | ||
186 | } | 312 | } |
187 | 313 | ||
188 | static void acpi_format_ipmi_response(struct acpi_ipmi_msg *msg, | 314 | static void acpi_format_ipmi_response(struct acpi_ipmi_msg *msg, |
189 | acpi_integer *value, int rem_time) | 315 | acpi_integer *value) |
190 | { | 316 | { |
191 | struct acpi_ipmi_buffer *buffer; | 317 | struct acpi_ipmi_buffer *buffer; |
192 | 318 | ||
@@ -195,110 +321,158 @@ static void acpi_format_ipmi_response(struct acpi_ipmi_msg *msg, | |||
195 | * IPMI message returned by IPMI command. | 321 | * IPMI message returned by IPMI command. |
196 | */ | 322 | */ |
197 | buffer = (struct acpi_ipmi_buffer *)value; | 323 | buffer = (struct acpi_ipmi_buffer *)value; |
198 | if (!rem_time && !msg->msg_done) { | 324 | |
199 | buffer->status = ACPI_IPMI_TIMEOUT; | ||
200 | return; | ||
201 | } | ||
202 | /* | 325 | /* |
203 | * If the flag of msg_done is not set or the recv length is zero, it | 326 | * If the flag of msg_done is not set, it means that the IPMI command is |
204 | * means that the IPMI command is not executed correctly. | 327 | * not executed correctly. |
205 | * The status code will be ACPI_IPMI_UNKNOWN. | ||
206 | */ | 328 | */ |
207 | if (!msg->msg_done || !msg->rx_len) { | 329 | buffer->status = msg->msg_done; |
208 | buffer->status = ACPI_IPMI_UNKNOWN; | 330 | if (msg->msg_done != ACPI_IPMI_OK) |
209 | return; | 331 | return; |
210 | } | 332 | |
211 | /* | 333 | /* |
212 | * If the IPMI response message is obtained correctly, the status code | 334 | * If the IPMI response message is obtained correctly, the status code |
213 | * will be ACPI_IPMI_OK | 335 | * will be ACPI_IPMI_OK |
214 | */ | 336 | */ |
215 | buffer->status = ACPI_IPMI_OK; | ||
216 | buffer->length = msg->rx_len; | 337 | buffer->length = msg->rx_len; |
217 | memcpy(buffer->data, msg->rx_data, msg->rx_len); | 338 | memcpy(buffer->data, msg->data, msg->rx_len); |
218 | } | 339 | } |
219 | 340 | ||
220 | static void ipmi_flush_tx_msg(struct acpi_ipmi_device *ipmi) | 341 | static void ipmi_flush_tx_msg(struct acpi_ipmi_device *ipmi) |
221 | { | 342 | { |
222 | struct acpi_ipmi_msg *tx_msg, *temp; | 343 | struct acpi_ipmi_msg *tx_msg; |
223 | int count = HZ / 10; | 344 | unsigned long flags; |
224 | struct pnp_dev *pnp_dev = ipmi->pnp_dev; | 345 | |
346 | /* | ||
347 | * NOTE: On-going ipmi_recv_msg | ||
348 | * ipmi_msg_handler() may still be invoked by ipmi_si after | ||
349 | * flushing. But it is safe to do a fast flushing on module_exit() | ||
350 | * without waiting for all ipmi_recv_msg(s) to complete from | ||
351 | * ipmi_msg_handler() as it is ensured by ipmi_si that all | ||
352 | * ipmi_recv_msg(s) are freed after invoking ipmi_destroy_user(). | ||
353 | */ | ||
354 | spin_lock_irqsave(&ipmi->tx_msg_lock, flags); | ||
355 | while (!list_empty(&ipmi->tx_msg_list)) { | ||
356 | tx_msg = list_first_entry(&ipmi->tx_msg_list, | ||
357 | struct acpi_ipmi_msg, | ||
358 | head); | ||
359 | list_del(&tx_msg->head); | ||
360 | spin_unlock_irqrestore(&ipmi->tx_msg_lock, flags); | ||
225 | 361 | ||
226 | list_for_each_entry_safe(tx_msg, temp, &ipmi->tx_msg_list, head) { | ||
227 | /* wake up the sleep thread on the Tx msg */ | 362 | /* wake up the sleep thread on the Tx msg */ |
228 | complete(&tx_msg->tx_complete); | 363 | complete(&tx_msg->tx_complete); |
364 | acpi_ipmi_msg_put(tx_msg); | ||
365 | spin_lock_irqsave(&ipmi->tx_msg_lock, flags); | ||
229 | } | 366 | } |
367 | spin_unlock_irqrestore(&ipmi->tx_msg_lock, flags); | ||
368 | } | ||
369 | |||
370 | static void ipmi_cancel_tx_msg(struct acpi_ipmi_device *ipmi, | ||
371 | struct acpi_ipmi_msg *msg) | ||
372 | { | ||
373 | struct acpi_ipmi_msg *tx_msg, *temp; | ||
374 | bool msg_found = false; | ||
375 | unsigned long flags; | ||
230 | 376 | ||
231 | /* wait for about 100ms to flush the tx message list */ | 377 | spin_lock_irqsave(&ipmi->tx_msg_lock, flags); |
232 | while (count--) { | 378 | list_for_each_entry_safe(tx_msg, temp, &ipmi->tx_msg_list, head) { |
233 | if (list_empty(&ipmi->tx_msg_list)) | 379 | if (msg == tx_msg) { |
380 | msg_found = true; | ||
381 | list_del(&tx_msg->head); | ||
234 | break; | 382 | break; |
235 | schedule_timeout(1); | 383 | } |
236 | } | 384 | } |
237 | if (!list_empty(&ipmi->tx_msg_list)) | 385 | spin_unlock_irqrestore(&ipmi->tx_msg_lock, flags); |
238 | dev_warn(&pnp_dev->dev, "tx msg list is not NULL\n"); | 386 | |
387 | if (msg_found) | ||
388 | acpi_ipmi_msg_put(tx_msg); | ||
239 | } | 389 | } |
240 | 390 | ||
241 | static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data) | 391 | static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data) |
242 | { | 392 | { |
243 | struct acpi_ipmi_device *ipmi_device = user_msg_data; | 393 | struct acpi_ipmi_device *ipmi_device = user_msg_data; |
244 | int msg_found = 0; | 394 | bool msg_found = false; |
245 | struct acpi_ipmi_msg *tx_msg; | 395 | struct acpi_ipmi_msg *tx_msg, *temp; |
246 | struct pnp_dev *pnp_dev = ipmi_device->pnp_dev; | 396 | struct device *dev = ipmi_device->dev; |
247 | unsigned long flags; | 397 | unsigned long flags; |
248 | 398 | ||
249 | if (msg->user != ipmi_device->user_interface) { | 399 | if (msg->user != ipmi_device->user_interface) { |
250 | dev_warn(&pnp_dev->dev, "Unexpected response is returned. " | 400 | dev_warn(dev, |
251 | "returned user %p, expected user %p\n", | 401 | "Unexpected response is returned. returned user %p, expected user %p\n", |
252 | msg->user, ipmi_device->user_interface); | 402 | msg->user, ipmi_device->user_interface); |
253 | ipmi_free_recv_msg(msg); | 403 | goto out_msg; |
254 | return; | ||
255 | } | 404 | } |
405 | |||
256 | spin_lock_irqsave(&ipmi_device->tx_msg_lock, flags); | 406 | spin_lock_irqsave(&ipmi_device->tx_msg_lock, flags); |
257 | list_for_each_entry(tx_msg, &ipmi_device->tx_msg_list, head) { | 407 | list_for_each_entry_safe(tx_msg, temp, &ipmi_device->tx_msg_list, head) { |
258 | if (msg->msgid == tx_msg->tx_msgid) { | 408 | if (msg->msgid == tx_msg->tx_msgid) { |
259 | msg_found = 1; | 409 | msg_found = true; |
410 | list_del(&tx_msg->head); | ||
260 | break; | 411 | break; |
261 | } | 412 | } |
262 | } | 413 | } |
263 | |||
264 | spin_unlock_irqrestore(&ipmi_device->tx_msg_lock, flags); | 414 | spin_unlock_irqrestore(&ipmi_device->tx_msg_lock, flags); |
415 | |||
265 | if (!msg_found) { | 416 | if (!msg_found) { |
266 | dev_warn(&pnp_dev->dev, "Unexpected response (msg id %ld) is " | 417 | dev_warn(dev, |
267 | "returned.\n", msg->msgid); | 418 | "Unexpected response (msg id %ld) is returned.\n", |
268 | ipmi_free_recv_msg(msg); | 419 | msg->msgid); |
269 | return; | 420 | goto out_msg; |
270 | } | 421 | } |
271 | 422 | ||
272 | if (msg->msg.data_len) { | 423 | /* copy the response data to Rx_data buffer */ |
273 | /* copy the response data to Rx_data buffer */ | 424 | if (msg->msg.data_len > ACPI_IPMI_MAX_MSG_LENGTH) { |
274 | memcpy(tx_msg->rx_data, msg->msg_data, msg->msg.data_len); | 425 | dev_WARN_ONCE(dev, true, |
275 | tx_msg->rx_len = msg->msg.data_len; | 426 | "Unexpected response (msg len %d).\n", |
276 | tx_msg->msg_done = 1; | 427 | msg->msg.data_len); |
428 | goto out_comp; | ||
277 | } | 429 | } |
430 | |||
431 | /* response msg is an error msg */ | ||
432 | msg->recv_type = IPMI_RESPONSE_RECV_TYPE; | ||
433 | if (msg->recv_type == IPMI_RESPONSE_RECV_TYPE && | ||
434 | msg->msg.data_len == 1) { | ||
435 | if (msg->msg.data[0] == IPMI_TIMEOUT_COMPLETION_CODE) { | ||
436 | dev_WARN_ONCE(dev, true, | ||
437 | "Unexpected response (timeout).\n"); | ||
438 | tx_msg->msg_done = ACPI_IPMI_TIMEOUT; | ||
439 | } | ||
440 | goto out_comp; | ||
441 | } | ||
442 | |||
443 | tx_msg->rx_len = msg->msg.data_len; | ||
444 | memcpy(tx_msg->data, msg->msg.data, tx_msg->rx_len); | ||
445 | tx_msg->msg_done = ACPI_IPMI_OK; | ||
446 | |||
447 | out_comp: | ||
278 | complete(&tx_msg->tx_complete); | 448 | complete(&tx_msg->tx_complete); |
449 | acpi_ipmi_msg_put(tx_msg); | ||
450 | out_msg: | ||
279 | ipmi_free_recv_msg(msg); | 451 | ipmi_free_recv_msg(msg); |
280 | }; | 452 | } |
281 | 453 | ||
282 | static void ipmi_register_bmc(int iface, struct device *dev) | 454 | static void ipmi_register_bmc(int iface, struct device *dev) |
283 | { | 455 | { |
284 | struct acpi_ipmi_device *ipmi_device, *temp; | 456 | struct acpi_ipmi_device *ipmi_device, *temp; |
285 | struct pnp_dev *pnp_dev; | ||
286 | ipmi_user_t user; | ||
287 | int err; | 457 | int err; |
288 | struct ipmi_smi_info smi_data; | 458 | struct ipmi_smi_info smi_data; |
289 | acpi_handle handle; | 459 | acpi_handle handle; |
290 | 460 | ||
291 | err = ipmi_get_smi_info(iface, &smi_data); | 461 | err = ipmi_get_smi_info(iface, &smi_data); |
292 | |||
293 | if (err) | 462 | if (err) |
294 | return; | 463 | return; |
295 | 464 | ||
296 | if (smi_data.addr_src != SI_ACPI) { | 465 | if (smi_data.addr_src != SI_ACPI) |
297 | put_device(smi_data.dev); | 466 | goto err_ref; |
298 | return; | ||
299 | } | ||
300 | |||
301 | handle = smi_data.addr_info.acpi_info.acpi_handle; | 467 | handle = smi_data.addr_info.acpi_info.acpi_handle; |
468 | if (!handle) | ||
469 | goto err_ref; | ||
470 | |||
471 | ipmi_device = ipmi_dev_alloc(iface, smi_data.dev, handle); | ||
472 | if (!ipmi_device) { | ||
473 | dev_warn(smi_data.dev, "Can't create IPMI user interface\n"); | ||
474 | goto err_ref; | ||
475 | } | ||
302 | 476 | ||
303 | mutex_lock(&driver_data.ipmi_lock); | 477 | mutex_lock(&driver_data.ipmi_lock); |
304 | list_for_each_entry(temp, &driver_data.ipmi_devices, head) { | 478 | list_for_each_entry(temp, &driver_data.ipmi_devices, head) { |
@@ -307,34 +481,20 @@ static void ipmi_register_bmc(int iface, struct device *dev) | |||
307 | * to the device list, don't add it again. | 481 | * to the device list, don't add it again. |
308 | */ | 482 | */ |
309 | if (temp->handle == handle) | 483 | if (temp->handle == handle) |
310 | goto out; | 484 | goto err_lock; |
311 | } | 485 | } |
312 | 486 | if (!driver_data.selected_smi) | |
313 | ipmi_device = kzalloc(sizeof(*ipmi_device), GFP_KERNEL); | 487 | driver_data.selected_smi = ipmi_device; |
314 | 488 | list_add_tail(&ipmi_device->head, &driver_data.ipmi_devices); | |
315 | if (!ipmi_device) | ||
316 | goto out; | ||
317 | |||
318 | pnp_dev = to_pnp_dev(smi_data.dev); | ||
319 | ipmi_device->handle = handle; | ||
320 | ipmi_device->pnp_dev = pnp_dev; | ||
321 | |||
322 | err = ipmi_create_user(iface, &driver_data.ipmi_hndlrs, | ||
323 | ipmi_device, &user); | ||
324 | if (err) { | ||
325 | dev_warn(&pnp_dev->dev, "Can't create IPMI user interface\n"); | ||
326 | kfree(ipmi_device); | ||
327 | goto out; | ||
328 | } | ||
329 | acpi_add_ipmi_device(ipmi_device); | ||
330 | ipmi_device->user_interface = user; | ||
331 | ipmi_device->ipmi_ifnum = iface; | ||
332 | mutex_unlock(&driver_data.ipmi_lock); | 489 | mutex_unlock(&driver_data.ipmi_lock); |
333 | memcpy(&ipmi_device->smi_data, &smi_data, sizeof(struct ipmi_smi_info)); | 490 | |
491 | put_device(smi_data.dev); | ||
334 | return; | 492 | return; |
335 | 493 | ||
336 | out: | 494 | err_lock: |
337 | mutex_unlock(&driver_data.ipmi_lock); | 495 | mutex_unlock(&driver_data.ipmi_lock); |
496 | ipmi_dev_release(ipmi_device); | ||
497 | err_ref: | ||
338 | put_device(smi_data.dev); | 498 | put_device(smi_data.dev); |
339 | return; | 499 | return; |
340 | } | 500 | } |
@@ -342,23 +502,29 @@ out: | |||
342 | static void ipmi_bmc_gone(int iface) | 502 | static void ipmi_bmc_gone(int iface) |
343 | { | 503 | { |
344 | struct acpi_ipmi_device *ipmi_device, *temp; | 504 | struct acpi_ipmi_device *ipmi_device, *temp; |
505 | bool dev_found = false; | ||
345 | 506 | ||
346 | mutex_lock(&driver_data.ipmi_lock); | 507 | mutex_lock(&driver_data.ipmi_lock); |
347 | list_for_each_entry_safe(ipmi_device, temp, | 508 | list_for_each_entry_safe(ipmi_device, temp, |
348 | &driver_data.ipmi_devices, head) { | 509 | &driver_data.ipmi_devices, head) { |
349 | if (ipmi_device->ipmi_ifnum != iface) | 510 | if (ipmi_device->ipmi_ifnum != iface) { |
350 | continue; | 511 | dev_found = true; |
351 | 512 | __ipmi_dev_kill(ipmi_device); | |
352 | acpi_remove_ipmi_device(ipmi_device); | 513 | break; |
353 | put_device(ipmi_device->smi_data.dev); | 514 | } |
354 | kfree(ipmi_device); | ||
355 | break; | ||
356 | } | 515 | } |
516 | if (!driver_data.selected_smi) | ||
517 | driver_data.selected_smi = list_first_entry_or_null( | ||
518 | &driver_data.ipmi_devices, | ||
519 | struct acpi_ipmi_device, head); | ||
357 | mutex_unlock(&driver_data.ipmi_lock); | 520 | mutex_unlock(&driver_data.ipmi_lock); |
521 | |||
522 | if (dev_found) { | ||
523 | ipmi_flush_tx_msg(ipmi_device); | ||
524 | acpi_ipmi_dev_put(ipmi_device); | ||
525 | } | ||
358 | } | 526 | } |
359 | /* -------------------------------------------------------------------------- | 527 | |
360 | * Address Space Management | ||
361 | * -------------------------------------------------------------------------- */ | ||
362 | /* | 528 | /* |
363 | * This is the IPMI opregion space handler. | 529 | * This is the IPMI opregion space handler. |
364 | * @function: indicates the read/write. In fact as the IPMI message is driven | 530 | * @function: indicates the read/write. In fact as the IPMI message is driven |
@@ -371,17 +537,17 @@ static void ipmi_bmc_gone(int iface) | |||
371 | * the response IPMI message returned by IPMI command. | 537 | * the response IPMI message returned by IPMI command. |
372 | * @handler_context: IPMI device context. | 538 | * @handler_context: IPMI device context. |
373 | */ | 539 | */ |
374 | |||
375 | static acpi_status | 540 | static acpi_status |
376 | acpi_ipmi_space_handler(u32 function, acpi_physical_address address, | 541 | acpi_ipmi_space_handler(u32 function, acpi_physical_address address, |
377 | u32 bits, acpi_integer *value, | 542 | u32 bits, acpi_integer *value, |
378 | void *handler_context, void *region_context) | 543 | void *handler_context, void *region_context) |
379 | { | 544 | { |
380 | struct acpi_ipmi_msg *tx_msg; | 545 | struct acpi_ipmi_msg *tx_msg; |
381 | struct acpi_ipmi_device *ipmi_device = handler_context; | 546 | struct acpi_ipmi_device *ipmi_device; |
382 | int err, rem_time; | 547 | int err; |
383 | acpi_status status; | 548 | acpi_status status; |
384 | unsigned long flags; | 549 | unsigned long flags; |
550 | |||
385 | /* | 551 | /* |
386 | * IPMI opregion message. | 552 | * IPMI opregion message. |
387 | * IPMI message is firstly written to the BMC and system software | 553 | * IPMI message is firstly written to the BMC and system software |
@@ -391,118 +557,75 @@ acpi_ipmi_space_handler(u32 function, acpi_physical_address address, | |||
391 | if ((function & ACPI_IO_MASK) == ACPI_READ) | 557 | if ((function & ACPI_IO_MASK) == ACPI_READ) |
392 | return AE_TYPE; | 558 | return AE_TYPE; |
393 | 559 | ||
394 | if (!ipmi_device->user_interface) | 560 | tx_msg = ipmi_msg_alloc(); |
561 | if (!tx_msg) | ||
395 | return AE_NOT_EXIST; | 562 | return AE_NOT_EXIST; |
563 | ipmi_device = tx_msg->device; | ||
396 | 564 | ||
397 | tx_msg = acpi_alloc_ipmi_msg(ipmi_device); | 565 | if (acpi_format_ipmi_request(tx_msg, address, value) != 0) { |
398 | if (!tx_msg) | 566 | ipmi_msg_release(tx_msg); |
399 | return AE_NO_MEMORY; | 567 | return AE_TYPE; |
568 | } | ||
400 | 569 | ||
401 | acpi_format_ipmi_msg(tx_msg, address, value); | 570 | acpi_ipmi_msg_get(tx_msg); |
571 | mutex_lock(&driver_data.ipmi_lock); | ||
572 | /* Do not add a tx_msg that can not be flushed. */ | ||
573 | if (ipmi_device->dead) { | ||
574 | mutex_unlock(&driver_data.ipmi_lock); | ||
575 | ipmi_msg_release(tx_msg); | ||
576 | return AE_NOT_EXIST; | ||
577 | } | ||
402 | spin_lock_irqsave(&ipmi_device->tx_msg_lock, flags); | 578 | spin_lock_irqsave(&ipmi_device->tx_msg_lock, flags); |
403 | list_add_tail(&tx_msg->head, &ipmi_device->tx_msg_list); | 579 | list_add_tail(&tx_msg->head, &ipmi_device->tx_msg_list); |
404 | spin_unlock_irqrestore(&ipmi_device->tx_msg_lock, flags); | 580 | spin_unlock_irqrestore(&ipmi_device->tx_msg_lock, flags); |
581 | mutex_unlock(&driver_data.ipmi_lock); | ||
582 | |||
405 | err = ipmi_request_settime(ipmi_device->user_interface, | 583 | err = ipmi_request_settime(ipmi_device->user_interface, |
406 | &tx_msg->addr, | 584 | &tx_msg->addr, |
407 | tx_msg->tx_msgid, | 585 | tx_msg->tx_msgid, |
408 | &tx_msg->tx_message, | 586 | &tx_msg->tx_message, |
409 | NULL, 0, 0, 0); | 587 | NULL, 0, 0, IPMI_TIMEOUT); |
410 | if (err) { | 588 | if (err) { |
411 | status = AE_ERROR; | 589 | status = AE_ERROR; |
412 | goto end_label; | 590 | goto out_msg; |
413 | } | 591 | } |
414 | rem_time = wait_for_completion_timeout(&tx_msg->tx_complete, | 592 | wait_for_completion(&tx_msg->tx_complete); |
415 | IPMI_TIMEOUT); | 593 | |
416 | acpi_format_ipmi_response(tx_msg, value, rem_time); | 594 | acpi_format_ipmi_response(tx_msg, value); |
417 | status = AE_OK; | 595 | status = AE_OK; |
418 | 596 | ||
419 | end_label: | 597 | out_msg: |
420 | spin_lock_irqsave(&ipmi_device->tx_msg_lock, flags); | 598 | ipmi_cancel_tx_msg(ipmi_device, tx_msg); |
421 | list_del(&tx_msg->head); | 599 | acpi_ipmi_msg_put(tx_msg); |
422 | spin_unlock_irqrestore(&ipmi_device->tx_msg_lock, flags); | ||
423 | kfree(tx_msg); | ||
424 | return status; | 600 | return status; |
425 | } | 601 | } |
426 | 602 | ||
427 | static void ipmi_remove_space_handler(struct acpi_ipmi_device *ipmi) | 603 | static int __init acpi_ipmi_init(void) |
428 | { | ||
429 | if (!test_bit(IPMI_FLAGS_HANDLER_INSTALL, &ipmi->flags)) | ||
430 | return; | ||
431 | |||
432 | acpi_remove_address_space_handler(ipmi->handle, | ||
433 | ACPI_ADR_SPACE_IPMI, &acpi_ipmi_space_handler); | ||
434 | |||
435 | clear_bit(IPMI_FLAGS_HANDLER_INSTALL, &ipmi->flags); | ||
436 | } | ||
437 | |||
438 | static int ipmi_install_space_handler(struct acpi_ipmi_device *ipmi) | ||
439 | { | 604 | { |
605 | int result; | ||
440 | acpi_status status; | 606 | acpi_status status; |
441 | 607 | ||
442 | if (test_bit(IPMI_FLAGS_HANDLER_INSTALL, &ipmi->flags)) | 608 | if (acpi_disabled) |
443 | return 0; | 609 | return 0; |
444 | 610 | ||
445 | status = acpi_install_address_space_handler(ipmi->handle, | 611 | status = acpi_install_address_space_handler(ACPI_ROOT_OBJECT, |
446 | ACPI_ADR_SPACE_IPMI, | 612 | ACPI_ADR_SPACE_IPMI, |
447 | &acpi_ipmi_space_handler, | 613 | &acpi_ipmi_space_handler, |
448 | NULL, ipmi); | 614 | NULL, NULL); |
449 | if (ACPI_FAILURE(status)) { | 615 | if (ACPI_FAILURE(status)) { |
450 | struct pnp_dev *pnp_dev = ipmi->pnp_dev; | 616 | pr_warn("Can't register IPMI opregion space handle\n"); |
451 | dev_warn(&pnp_dev->dev, "Can't register IPMI opregion space " | ||
452 | "handle\n"); | ||
453 | return -EINVAL; | 617 | return -EINVAL; |
454 | } | 618 | } |
455 | set_bit(IPMI_FLAGS_HANDLER_INSTALL, &ipmi->flags); | ||
456 | return 0; | ||
457 | } | ||
458 | |||
459 | static void acpi_add_ipmi_device(struct acpi_ipmi_device *ipmi_device) | ||
460 | { | ||
461 | |||
462 | INIT_LIST_HEAD(&ipmi_device->head); | ||
463 | |||
464 | spin_lock_init(&ipmi_device->tx_msg_lock); | ||
465 | INIT_LIST_HEAD(&ipmi_device->tx_msg_list); | ||
466 | ipmi_install_space_handler(ipmi_device); | ||
467 | |||
468 | list_add_tail(&ipmi_device->head, &driver_data.ipmi_devices); | ||
469 | } | ||
470 | |||
471 | static void acpi_remove_ipmi_device(struct acpi_ipmi_device *ipmi_device) | ||
472 | { | ||
473 | /* | ||
474 | * If the IPMI user interface is created, it should be | ||
475 | * destroyed. | ||
476 | */ | ||
477 | if (ipmi_device->user_interface) { | ||
478 | ipmi_destroy_user(ipmi_device->user_interface); | ||
479 | ipmi_device->user_interface = NULL; | ||
480 | } | ||
481 | /* flush the Tx_msg list */ | ||
482 | if (!list_empty(&ipmi_device->tx_msg_list)) | ||
483 | ipmi_flush_tx_msg(ipmi_device); | ||
484 | |||
485 | list_del(&ipmi_device->head); | ||
486 | ipmi_remove_space_handler(ipmi_device); | ||
487 | } | ||
488 | |||
489 | static int __init acpi_ipmi_init(void) | ||
490 | { | ||
491 | int result = 0; | ||
492 | |||
493 | if (acpi_disabled) | ||
494 | return result; | ||
495 | |||
496 | mutex_init(&driver_data.ipmi_lock); | ||
497 | |||
498 | result = ipmi_smi_watcher_register(&driver_data.bmc_events); | 619 | result = ipmi_smi_watcher_register(&driver_data.bmc_events); |
620 | if (result) | ||
621 | pr_err("Can't register IPMI system interface watcher\n"); | ||
499 | 622 | ||
500 | return result; | 623 | return result; |
501 | } | 624 | } |
502 | 625 | ||
503 | static void __exit acpi_ipmi_exit(void) | 626 | static void __exit acpi_ipmi_exit(void) |
504 | { | 627 | { |
505 | struct acpi_ipmi_device *ipmi_device, *temp; | 628 | struct acpi_ipmi_device *ipmi_device; |
506 | 629 | ||
507 | if (acpi_disabled) | 630 | if (acpi_disabled) |
508 | return; | 631 | return; |
@@ -516,13 +639,22 @@ static void __exit acpi_ipmi_exit(void) | |||
516 | * handler and free it. | 639 | * handler and free it. |
517 | */ | 640 | */ |
518 | mutex_lock(&driver_data.ipmi_lock); | 641 | mutex_lock(&driver_data.ipmi_lock); |
519 | list_for_each_entry_safe(ipmi_device, temp, | 642 | while (!list_empty(&driver_data.ipmi_devices)) { |
520 | &driver_data.ipmi_devices, head) { | 643 | ipmi_device = list_first_entry(&driver_data.ipmi_devices, |
521 | acpi_remove_ipmi_device(ipmi_device); | 644 | struct acpi_ipmi_device, |
522 | put_device(ipmi_device->smi_data.dev); | 645 | head); |
523 | kfree(ipmi_device); | 646 | __ipmi_dev_kill(ipmi_device); |
647 | mutex_unlock(&driver_data.ipmi_lock); | ||
648 | |||
649 | ipmi_flush_tx_msg(ipmi_device); | ||
650 | acpi_ipmi_dev_put(ipmi_device); | ||
651 | |||
652 | mutex_lock(&driver_data.ipmi_lock); | ||
524 | } | 653 | } |
525 | mutex_unlock(&driver_data.ipmi_lock); | 654 | mutex_unlock(&driver_data.ipmi_lock); |
655 | acpi_remove_address_space_handler(ACPI_ROOT_OBJECT, | ||
656 | ACPI_ADR_SPACE_IPMI, | ||
657 | &acpi_ipmi_space_handler); | ||
526 | } | 658 | } |
527 | 659 | ||
528 | module_init(acpi_ipmi_init); | 660 | module_init(acpi_ipmi_init); |
diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c index fb78bb9ad8f6..6745fe137b9e 100644 --- a/drivers/acpi/acpi_lpss.c +++ b/drivers/acpi/acpi_lpss.c | |||
@@ -30,6 +30,7 @@ ACPI_MODULE_NAME("acpi_lpss"); | |||
30 | /* Offsets relative to LPSS_PRIVATE_OFFSET */ | 30 | /* Offsets relative to LPSS_PRIVATE_OFFSET */ |
31 | #define LPSS_GENERAL 0x08 | 31 | #define LPSS_GENERAL 0x08 |
32 | #define LPSS_GENERAL_LTR_MODE_SW BIT(2) | 32 | #define LPSS_GENERAL_LTR_MODE_SW BIT(2) |
33 | #define LPSS_GENERAL_UART_RTS_OVRD BIT(3) | ||
33 | #define LPSS_SW_LTR 0x10 | 34 | #define LPSS_SW_LTR 0x10 |
34 | #define LPSS_AUTO_LTR 0x14 | 35 | #define LPSS_AUTO_LTR 0x14 |
35 | #define LPSS_TX_INT 0x20 | 36 | #define LPSS_TX_INT 0x20 |
@@ -68,11 +69,16 @@ struct lpss_private_data { | |||
68 | 69 | ||
69 | static void lpss_uart_setup(struct lpss_private_data *pdata) | 70 | static void lpss_uart_setup(struct lpss_private_data *pdata) |
70 | { | 71 | { |
71 | unsigned int tx_int_offset = pdata->dev_desc->prv_offset + LPSS_TX_INT; | 72 | unsigned int offset; |
72 | u32 reg; | 73 | u32 reg; |
73 | 74 | ||
74 | reg = readl(pdata->mmio_base + tx_int_offset); | 75 | offset = pdata->dev_desc->prv_offset + LPSS_TX_INT; |
75 | writel(reg | LPSS_TX_INT_MASK, pdata->mmio_base + tx_int_offset); | 76 | reg = readl(pdata->mmio_base + offset); |
77 | writel(reg | LPSS_TX_INT_MASK, pdata->mmio_base + offset); | ||
78 | |||
79 | offset = pdata->dev_desc->prv_offset + LPSS_GENERAL; | ||
80 | reg = readl(pdata->mmio_base + offset); | ||
81 | writel(reg | LPSS_GENERAL_UART_RTS_OVRD, pdata->mmio_base + offset); | ||
76 | } | 82 | } |
77 | 83 | ||
78 | static struct lpss_device_desc lpt_dev_desc = { | 84 | static struct lpss_device_desc lpt_dev_desc = { |
@@ -157,6 +163,15 @@ static const struct acpi_device_id acpi_lpss_device_ids[] = { | |||
157 | { "80860F41", (unsigned long)&byt_i2c_dev_desc }, | 163 | { "80860F41", (unsigned long)&byt_i2c_dev_desc }, |
158 | { "INT33B2", }, | 164 | { "INT33B2", }, |
159 | 165 | ||
166 | { "INT3430", (unsigned long)&lpt_dev_desc }, | ||
167 | { "INT3431", (unsigned long)&lpt_dev_desc }, | ||
168 | { "INT3432", (unsigned long)&lpt_dev_desc }, | ||
169 | { "INT3433", (unsigned long)&lpt_dev_desc }, | ||
170 | { "INT3434", (unsigned long)&lpt_uart_dev_desc }, | ||
171 | { "INT3435", (unsigned long)&lpt_uart_dev_desc }, | ||
172 | { "INT3436", (unsigned long)&lpt_sdio_dev_desc }, | ||
173 | { "INT3437", }, | ||
174 | |||
160 | { } | 175 | { } |
161 | }; | 176 | }; |
162 | 177 | ||
diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c index 999adb5499c7..551dad712ffe 100644 --- a/drivers/acpi/acpi_memhotplug.c +++ b/drivers/acpi/acpi_memhotplug.c | |||
@@ -152,8 +152,9 @@ static int acpi_memory_check_device(struct acpi_memory_device *mem_device) | |||
152 | unsigned long long current_status; | 152 | unsigned long long current_status; |
153 | 153 | ||
154 | /* Get device present/absent information from the _STA */ | 154 | /* Get device present/absent information from the _STA */ |
155 | if (ACPI_FAILURE(acpi_evaluate_integer(mem_device->device->handle, "_STA", | 155 | if (ACPI_FAILURE(acpi_evaluate_integer(mem_device->device->handle, |
156 | NULL, ¤t_status))) | 156 | METHOD_NAME__STA, NULL, |
157 | ¤t_status))) | ||
157 | return -ENODEV; | 158 | return -ENODEV; |
158 | /* | 159 | /* |
159 | * Check for device status. Device should be | 160 | * Check for device status. Device should be |
@@ -281,7 +282,7 @@ static void acpi_memory_remove_memory(struct acpi_memory_device *mem_device) | |||
281 | if (!info->enabled) | 282 | if (!info->enabled) |
282 | continue; | 283 | continue; |
283 | 284 | ||
284 | if (nid < 0) | 285 | if (nid == NUMA_NO_NODE) |
285 | nid = memory_add_physaddr_to_nid(info->start_addr); | 286 | nid = memory_add_physaddr_to_nid(info->start_addr); |
286 | 287 | ||
287 | acpi_unbind_memory_blocks(info, handle); | 288 | acpi_unbind_memory_blocks(info, handle); |
diff --git a/drivers/acpi/acpi_platform.c b/drivers/acpi/acpi_platform.c index 1bde12708f9e..dbfe49e5fd63 100644 --- a/drivers/acpi/acpi_platform.c +++ b/drivers/acpi/acpi_platform.c | |||
@@ -29,6 +29,13 @@ ACPI_MODULE_NAME("platform"); | |||
29 | static const struct acpi_device_id acpi_platform_device_ids[] = { | 29 | static const struct acpi_device_id acpi_platform_device_ids[] = { |
30 | 30 | ||
31 | { "PNP0D40" }, | 31 | { "PNP0D40" }, |
32 | { "ACPI0003" }, | ||
33 | { "VPC2004" }, | ||
34 | { "BCM4752" }, | ||
35 | |||
36 | /* Intel Smart Sound Technology */ | ||
37 | { "INT33C8" }, | ||
38 | { "80860F28" }, | ||
32 | 39 | ||
33 | { } | 40 | { } |
34 | }; | 41 | }; |
@@ -104,7 +111,7 @@ int acpi_create_platform_device(struct acpi_device *adev, | |||
104 | pdevinfo.id = -1; | 111 | pdevinfo.id = -1; |
105 | pdevinfo.res = resources; | 112 | pdevinfo.res = resources; |
106 | pdevinfo.num_res = count; | 113 | pdevinfo.num_res = count; |
107 | pdevinfo.acpi_node.handle = adev->handle; | 114 | pdevinfo.acpi_node.companion = adev; |
108 | pdev = platform_device_register_full(&pdevinfo); | 115 | pdev = platform_device_register_full(&pdevinfo); |
109 | if (IS_ERR(pdev)) { | 116 | if (IS_ERR(pdev)) { |
110 | dev_err(&adev->dev, "platform device creation failed: %ld\n", | 117 | dev_err(&adev->dev, "platform device creation failed: %ld\n", |
diff --git a/drivers/acpi/acpi_processor.c b/drivers/acpi/acpi_processor.c index f29e06efa479..3c1d6b0c09a4 100644 --- a/drivers/acpi/acpi_processor.c +++ b/drivers/acpi/acpi_processor.c | |||
@@ -140,15 +140,11 @@ static int acpi_processor_errata_piix4(struct pci_dev *dev) | |||
140 | return 0; | 140 | return 0; |
141 | } | 141 | } |
142 | 142 | ||
143 | static int acpi_processor_errata(struct acpi_processor *pr) | 143 | static int acpi_processor_errata(void) |
144 | { | 144 | { |
145 | int result = 0; | 145 | int result = 0; |
146 | struct pci_dev *dev = NULL; | 146 | struct pci_dev *dev = NULL; |
147 | 147 | ||
148 | |||
149 | if (!pr) | ||
150 | return -EINVAL; | ||
151 | |||
152 | /* | 148 | /* |
153 | * PIIX4 | 149 | * PIIX4 |
154 | */ | 150 | */ |
@@ -181,7 +177,7 @@ static int acpi_processor_hotadd_init(struct acpi_processor *pr) | |||
181 | cpu_maps_update_begin(); | 177 | cpu_maps_update_begin(); |
182 | cpu_hotplug_begin(); | 178 | cpu_hotplug_begin(); |
183 | 179 | ||
184 | ret = acpi_map_lsapic(pr->handle, &pr->id); | 180 | ret = acpi_map_lsapic(pr->handle, pr->apic_id, &pr->id); |
185 | if (ret) | 181 | if (ret) |
186 | goto out; | 182 | goto out; |
187 | 183 | ||
@@ -219,11 +215,9 @@ static int acpi_processor_get_info(struct acpi_device *device) | |||
219 | int cpu_index, device_declaration = 0; | 215 | int cpu_index, device_declaration = 0; |
220 | acpi_status status = AE_OK; | 216 | acpi_status status = AE_OK; |
221 | static int cpu0_initialized; | 217 | static int cpu0_initialized; |
218 | unsigned long long value; | ||
222 | 219 | ||
223 | if (num_online_cpus() > 1) | 220 | acpi_processor_errata(); |
224 | errata.smp = TRUE; | ||
225 | |||
226 | acpi_processor_errata(pr); | ||
227 | 221 | ||
228 | /* | 222 | /* |
229 | * Check to see if we have bus mastering arbitration control. This | 223 | * Check to see if we have bus mastering arbitration control. This |
@@ -247,18 +241,12 @@ static int acpi_processor_get_info(struct acpi_device *device) | |||
247 | return -ENODEV; | 241 | return -ENODEV; |
248 | } | 242 | } |
249 | 243 | ||
250 | /* | ||
251 | * TBD: Synch processor ID (via LAPIC/LSAPIC structures) on SMP. | ||
252 | * >>> 'acpi_get_processor_id(acpi_id, &id)' in | ||
253 | * arch/xxx/acpi.c | ||
254 | */ | ||
255 | pr->acpi_id = object.processor.proc_id; | 244 | pr->acpi_id = object.processor.proc_id; |
256 | } else { | 245 | } else { |
257 | /* | 246 | /* |
258 | * Declared with "Device" statement; match _UID. | 247 | * Declared with "Device" statement; match _UID. |
259 | * Note that we don't handle string _UIDs yet. | 248 | * Note that we don't handle string _UIDs yet. |
260 | */ | 249 | */ |
261 | unsigned long long value; | ||
262 | status = acpi_evaluate_integer(pr->handle, METHOD_NAME__UID, | 250 | status = acpi_evaluate_integer(pr->handle, METHOD_NAME__UID, |
263 | NULL, &value); | 251 | NULL, &value); |
264 | if (ACPI_FAILURE(status)) { | 252 | if (ACPI_FAILURE(status)) { |
@@ -270,7 +258,9 @@ static int acpi_processor_get_info(struct acpi_device *device) | |||
270 | device_declaration = 1; | 258 | device_declaration = 1; |
271 | pr->acpi_id = value; | 259 | pr->acpi_id = value; |
272 | } | 260 | } |
273 | cpu_index = acpi_get_cpuid(pr->handle, device_declaration, pr->acpi_id); | 261 | pr->apic_id = acpi_get_apicid(pr->handle, device_declaration, |
262 | pr->acpi_id); | ||
263 | cpu_index = acpi_map_cpuid(pr->apic_id, pr->acpi_id); | ||
274 | 264 | ||
275 | /* Handle UP system running SMP kernel, with no LAPIC in MADT */ | 265 | /* Handle UP system running SMP kernel, with no LAPIC in MADT */ |
276 | if (!cpu0_initialized && (cpu_index == -1) && | 266 | if (!cpu0_initialized && (cpu_index == -1) && |
@@ -332,9 +322,9 @@ static int acpi_processor_get_info(struct acpi_device *device) | |||
332 | * ensure we get the right value in the "physical id" field | 322 | * ensure we get the right value in the "physical id" field |
333 | * of /proc/cpuinfo | 323 | * of /proc/cpuinfo |
334 | */ | 324 | */ |
335 | status = acpi_evaluate_object(pr->handle, "_SUN", NULL, &buffer); | 325 | status = acpi_evaluate_integer(pr->handle, "_SUN", NULL, &value); |
336 | if (ACPI_SUCCESS(status)) | 326 | if (ACPI_SUCCESS(status)) |
337 | arch_fix_phys_package_id(pr->id, object.integer.value); | 327 | arch_fix_phys_package_id(pr->id, value); |
338 | 328 | ||
339 | return 0; | 329 | return 0; |
340 | } | 330 | } |
diff --git a/drivers/acpi/acpica/acdebug.h b/drivers/acpi/acpica/acdebug.h index 9feba08c29fe..a9fd0b872062 100644 --- a/drivers/acpi/acpica/acdebug.h +++ b/drivers/acpi/acpica/acdebug.h | |||
@@ -114,10 +114,12 @@ ACPI_HW_DEPENDENT_RETURN_VOID(void | |||
114 | acpi_db_generate_gpe(char *gpe_arg, | 114 | acpi_db_generate_gpe(char *gpe_arg, |
115 | char *block_arg)) | 115 | char *block_arg)) |
116 | 116 | ||
117 | ACPI_HW_DEPENDENT_RETURN_VOID(void acpi_db_generate_sci(void)) | ||
118 | |||
117 | /* | 119 | /* |
118 | * dbconvert - miscellaneous conversion routines | 120 | * dbconvert - miscellaneous conversion routines |
119 | */ | 121 | */ |
120 | acpi_status acpi_db_hex_char_to_value(int hex_char, u8 *return_value); | 122 | acpi_status acpi_db_hex_char_to_value(int hex_char, u8 *return_value); |
121 | 123 | ||
122 | acpi_status acpi_db_convert_to_package(char *string, union acpi_object *object); | 124 | acpi_status acpi_db_convert_to_package(char *string, union acpi_object *object); |
123 | 125 | ||
@@ -154,6 +156,8 @@ void acpi_db_set_scope(char *name); | |||
154 | 156 | ||
155 | void acpi_db_dump_namespace(char *start_arg, char *depth_arg); | 157 | void acpi_db_dump_namespace(char *start_arg, char *depth_arg); |
156 | 158 | ||
159 | void acpi_db_dump_namespace_paths(void); | ||
160 | |||
157 | void acpi_db_dump_namespace_by_owner(char *owner_arg, char *depth_arg); | 161 | void acpi_db_dump_namespace_by_owner(char *owner_arg, char *depth_arg); |
158 | 162 | ||
159 | acpi_status acpi_db_find_name_in_namespace(char *name_arg); | 163 | acpi_status acpi_db_find_name_in_namespace(char *name_arg); |
@@ -240,6 +244,8 @@ void acpi_db_display_history(void); | |||
240 | 244 | ||
241 | char *acpi_db_get_from_history(char *command_num_arg); | 245 | char *acpi_db_get_from_history(char *command_num_arg); |
242 | 246 | ||
247 | char *acpi_db_get_history_by_index(u32 commandd_num); | ||
248 | |||
243 | /* | 249 | /* |
244 | * dbinput - user front-end to the AML debugger | 250 | * dbinput - user front-end to the AML debugger |
245 | */ | 251 | */ |
diff --git a/drivers/acpi/acpica/acevents.h b/drivers/acpi/acpica/acevents.h index ab0e97710381..41abe552c7a3 100644 --- a/drivers/acpi/acpica/acevents.h +++ b/drivers/acpi/acpica/acevents.h | |||
@@ -71,7 +71,8 @@ acpi_status acpi_ev_init_global_lock_handler(void); | |||
71 | 71 | ||
72 | ACPI_HW_DEPENDENT_RETURN_OK(acpi_status | 72 | ACPI_HW_DEPENDENT_RETURN_OK(acpi_status |
73 | acpi_ev_acquire_global_lock(u16 timeout)) | 73 | acpi_ev_acquire_global_lock(u16 timeout)) |
74 | ACPI_HW_DEPENDENT_RETURN_OK(acpi_status acpi_ev_release_global_lock(void)) | 74 | |
75 | ACPI_HW_DEPENDENT_RETURN_OK(acpi_status acpi_ev_release_global_lock(void)) | ||
75 | acpi_status acpi_ev_remove_global_lock_handler(void); | 76 | acpi_status acpi_ev_remove_global_lock_handler(void); |
76 | 77 | ||
77 | /* | 78 | /* |
@@ -242,11 +243,11 @@ acpi_ev_initialize_region(union acpi_operand_object *region_obj, | |||
242 | */ | 243 | */ |
243 | u32 ACPI_SYSTEM_XFACE acpi_ev_gpe_xrupt_handler(void *context); | 244 | u32 ACPI_SYSTEM_XFACE acpi_ev_gpe_xrupt_handler(void *context); |
244 | 245 | ||
245 | u32 acpi_ev_install_sci_handler(void); | 246 | u32 acpi_ev_sci_dispatch(void); |
246 | 247 | ||
247 | acpi_status acpi_ev_remove_sci_handler(void); | 248 | u32 acpi_ev_install_sci_handler(void); |
248 | 249 | ||
249 | u32 acpi_ev_initialize_SCI(u32 program_SCI); | 250 | acpi_status acpi_ev_remove_all_sci_handlers(void); |
250 | 251 | ||
251 | ACPI_HW_DEPENDENT_RETURN_VOID(void acpi_ev_terminate(void)) | 252 | ACPI_HW_DEPENDENT_RETURN_VOID(void acpi_ev_terminate(void)) |
252 | #endif /* __ACEVENTS_H__ */ | 253 | #endif /* __ACEVENTS_H__ */ |
diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h index 90e846f985fa..e9f1fc7f99c7 100644 --- a/drivers/acpi/acpica/acglobal.h +++ b/drivers/acpi/acpica/acglobal.h | |||
@@ -269,6 +269,7 @@ ACPI_EXTERN acpi_table_handler acpi_gbl_table_handler; | |||
269 | ACPI_EXTERN void *acpi_gbl_table_handler_context; | 269 | ACPI_EXTERN void *acpi_gbl_table_handler_context; |
270 | ACPI_EXTERN struct acpi_walk_state *acpi_gbl_breakpoint_walk; | 270 | ACPI_EXTERN struct acpi_walk_state *acpi_gbl_breakpoint_walk; |
271 | ACPI_EXTERN acpi_interface_handler acpi_gbl_interface_handler; | 271 | ACPI_EXTERN acpi_interface_handler acpi_gbl_interface_handler; |
272 | ACPI_EXTERN struct acpi_sci_handler_info *acpi_gbl_sci_handler_list; | ||
272 | 273 | ||
273 | /* Owner ID support */ | 274 | /* Owner ID support */ |
274 | 275 | ||
@@ -405,7 +406,9 @@ extern u32 acpi_gbl_nesting_level; | |||
405 | 406 | ||
406 | /* Event counters */ | 407 | /* Event counters */ |
407 | 408 | ||
409 | ACPI_EXTERN u32 acpi_method_count; | ||
408 | ACPI_EXTERN u32 acpi_gpe_count; | 410 | ACPI_EXTERN u32 acpi_gpe_count; |
411 | ACPI_EXTERN u32 acpi_sci_count; | ||
409 | ACPI_EXTERN u32 acpi_fixed_event_count[ACPI_NUM_FIXED_EVENTS]; | 412 | ACPI_EXTERN u32 acpi_fixed_event_count[ACPI_NUM_FIXED_EVENTS]; |
410 | 413 | ||
411 | /* Support for dynamic control method tracing mechanism */ | 414 | /* Support for dynamic control method tracing mechanism */ |
@@ -445,13 +448,6 @@ ACPI_EXTERN u8 acpi_gbl_db_opt_tables; | |||
445 | ACPI_EXTERN u8 acpi_gbl_db_opt_stats; | 448 | ACPI_EXTERN u8 acpi_gbl_db_opt_stats; |
446 | ACPI_EXTERN u8 acpi_gbl_db_opt_ini_methods; | 449 | ACPI_EXTERN u8 acpi_gbl_db_opt_ini_methods; |
447 | ACPI_EXTERN u8 acpi_gbl_db_opt_no_region_support; | 450 | ACPI_EXTERN u8 acpi_gbl_db_opt_no_region_support; |
448 | |||
449 | ACPI_EXTERN char *acpi_gbl_db_args[ACPI_DEBUGGER_MAX_ARGS]; | ||
450 | ACPI_EXTERN acpi_object_type acpi_gbl_db_arg_types[ACPI_DEBUGGER_MAX_ARGS]; | ||
451 | ACPI_EXTERN char acpi_gbl_db_line_buf[ACPI_DB_LINE_BUFFER_SIZE]; | ||
452 | ACPI_EXTERN char acpi_gbl_db_parsed_buf[ACPI_DB_LINE_BUFFER_SIZE]; | ||
453 | ACPI_EXTERN char acpi_gbl_db_scope_buf[80]; | ||
454 | ACPI_EXTERN char acpi_gbl_db_debug_filename[80]; | ||
455 | ACPI_EXTERN u8 acpi_gbl_db_output_to_file; | 451 | ACPI_EXTERN u8 acpi_gbl_db_output_to_file; |
456 | ACPI_EXTERN char *acpi_gbl_db_buffer; | 452 | ACPI_EXTERN char *acpi_gbl_db_buffer; |
457 | ACPI_EXTERN char *acpi_gbl_db_filename; | 453 | ACPI_EXTERN char *acpi_gbl_db_filename; |
@@ -459,6 +455,16 @@ ACPI_EXTERN u32 acpi_gbl_db_debug_level; | |||
459 | ACPI_EXTERN u32 acpi_gbl_db_console_debug_level; | 455 | ACPI_EXTERN u32 acpi_gbl_db_console_debug_level; |
460 | ACPI_EXTERN struct acpi_namespace_node *acpi_gbl_db_scope_node; | 456 | ACPI_EXTERN struct acpi_namespace_node *acpi_gbl_db_scope_node; |
461 | 457 | ||
458 | ACPI_EXTERN char *acpi_gbl_db_args[ACPI_DEBUGGER_MAX_ARGS]; | ||
459 | ACPI_EXTERN acpi_object_type acpi_gbl_db_arg_types[ACPI_DEBUGGER_MAX_ARGS]; | ||
460 | |||
461 | /* These buffers should all be the same size */ | ||
462 | |||
463 | ACPI_EXTERN char acpi_gbl_db_line_buf[ACPI_DB_LINE_BUFFER_SIZE]; | ||
464 | ACPI_EXTERN char acpi_gbl_db_parsed_buf[ACPI_DB_LINE_BUFFER_SIZE]; | ||
465 | ACPI_EXTERN char acpi_gbl_db_scope_buf[ACPI_DB_LINE_BUFFER_SIZE]; | ||
466 | ACPI_EXTERN char acpi_gbl_db_debug_filename[ACPI_DB_LINE_BUFFER_SIZE]; | ||
467 | |||
462 | /* | 468 | /* |
463 | * Statistic globals | 469 | * Statistic globals |
464 | */ | 470 | */ |
diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index 0ed00669cd21..53ed1a8ba4f0 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h | |||
@@ -398,6 +398,14 @@ struct acpi_simple_repair_info { | |||
398 | * | 398 | * |
399 | ****************************************************************************/ | 399 | ****************************************************************************/ |
400 | 400 | ||
401 | /* Dispatch info for each host-installed SCI handler */ | ||
402 | |||
403 | struct acpi_sci_handler_info { | ||
404 | struct acpi_sci_handler_info *next; | ||
405 | acpi_sci_handler address; /* Address of handler */ | ||
406 | void *context; /* Context to be passed to handler */ | ||
407 | }; | ||
408 | |||
401 | /* Dispatch info for each GPE -- either a method or handler, cannot be both */ | 409 | /* Dispatch info for each GPE -- either a method or handler, cannot be both */ |
402 | 410 | ||
403 | struct acpi_gpe_handler_info { | 411 | struct acpi_gpe_handler_info { |
@@ -1064,7 +1072,7 @@ struct acpi_db_method_info { | |||
1064 | char *name; | 1072 | char *name; |
1065 | u32 flags; | 1073 | u32 flags; |
1066 | u32 num_loops; | 1074 | u32 num_loops; |
1067 | char pathname[128]; | 1075 | char pathname[ACPI_DB_LINE_BUFFER_SIZE]; |
1068 | char **args; | 1076 | char **args; |
1069 | acpi_object_type *types; | 1077 | acpi_object_type *types; |
1070 | 1078 | ||
@@ -1086,6 +1094,7 @@ struct acpi_integrity_info { | |||
1086 | u32 objects; | 1094 | u32 objects; |
1087 | }; | 1095 | }; |
1088 | 1096 | ||
1097 | #define ACPI_DB_DISABLE_OUTPUT 0x00 | ||
1089 | #define ACPI_DB_REDIRECTABLE_OUTPUT 0x01 | 1098 | #define ACPI_DB_REDIRECTABLE_OUTPUT 0x01 |
1090 | #define ACPI_DB_CONSOLE_OUTPUT 0x02 | 1099 | #define ACPI_DB_CONSOLE_OUTPUT 0x02 |
1091 | #define ACPI_DB_DUPLICATE_OUTPUT 0x03 | 1100 | #define ACPI_DB_DUPLICATE_OUTPUT 0x03 |
diff --git a/drivers/acpi/acpica/acmacros.h b/drivers/acpi/acpica/acmacros.h index 530a2f8c1252..2a86c65d873b 100644 --- a/drivers/acpi/acpica/acmacros.h +++ b/drivers/acpi/acpica/acmacros.h | |||
@@ -410,37 +410,6 @@ | |||
410 | #endif | 410 | #endif |
411 | 411 | ||
412 | /* | 412 | /* |
413 | * Memory allocation tracking (DEBUG ONLY) | ||
414 | */ | ||
415 | #define ACPI_MEM_PARAMETERS _COMPONENT, _acpi_module_name, __LINE__ | ||
416 | |||
417 | #ifndef ACPI_DBG_TRACK_ALLOCATIONS | ||
418 | |||
419 | /* Memory allocation */ | ||
420 | |||
421 | #ifndef ACPI_ALLOCATE | ||
422 | #define ACPI_ALLOCATE(a) acpi_ut_allocate((acpi_size) (a), ACPI_MEM_PARAMETERS) | ||
423 | #endif | ||
424 | #ifndef ACPI_ALLOCATE_ZEROED | ||
425 | #define ACPI_ALLOCATE_ZEROED(a) acpi_ut_allocate_zeroed((acpi_size) (a), ACPI_MEM_PARAMETERS) | ||
426 | #endif | ||
427 | #ifndef ACPI_FREE | ||
428 | #define ACPI_FREE(a) acpi_os_free(a) | ||
429 | #endif | ||
430 | #define ACPI_MEM_TRACKING(a) | ||
431 | |||
432 | #else | ||
433 | |||
434 | /* Memory allocation */ | ||
435 | |||
436 | #define ACPI_ALLOCATE(a) acpi_ut_allocate_and_track((acpi_size) (a), ACPI_MEM_PARAMETERS) | ||
437 | #define ACPI_ALLOCATE_ZEROED(a) acpi_ut_allocate_zeroed_and_track((acpi_size) (a), ACPI_MEM_PARAMETERS) | ||
438 | #define ACPI_FREE(a) acpi_ut_free_and_track(a, ACPI_MEM_PARAMETERS) | ||
439 | #define ACPI_MEM_TRACKING(a) a | ||
440 | |||
441 | #endif /* ACPI_DBG_TRACK_ALLOCATIONS */ | ||
442 | |||
443 | /* | ||
444 | * Macros used for ACPICA utilities only | 413 | * Macros used for ACPICA utilities only |
445 | */ | 414 | */ |
446 | 415 | ||
diff --git a/drivers/acpi/acpica/acnamesp.h b/drivers/acpi/acpica/acnamesp.h index 40b04bd5579e..e6138ac4a160 100644 --- a/drivers/acpi/acpica/acnamesp.h +++ b/drivers/acpi/acpica/acnamesp.h | |||
@@ -213,6 +213,12 @@ acpi_ns_dump_objects(acpi_object_type type, | |||
213 | u8 display_type, | 213 | u8 display_type, |
214 | u32 max_depth, | 214 | u32 max_depth, |
215 | acpi_owner_id owner_id, acpi_handle start_handle); | 215 | acpi_owner_id owner_id, acpi_handle start_handle); |
216 | |||
217 | void | ||
218 | acpi_ns_dump_object_paths(acpi_object_type type, | ||
219 | u8 display_type, | ||
220 | u32 max_depth, | ||
221 | acpi_owner_id owner_id, acpi_handle start_handle); | ||
216 | #endif /* ACPI_FUTURE_USAGE */ | 222 | #endif /* ACPI_FUTURE_USAGE */ |
217 | 223 | ||
218 | /* | 224 | /* |
diff --git a/drivers/acpi/acpica/acutils.h b/drivers/acpi/acpica/acutils.h index d5a62a6182bb..be8180c17d7e 100644 --- a/drivers/acpi/acpica/acutils.h +++ b/drivers/acpi/acpica/acutils.h | |||
@@ -628,6 +628,17 @@ u8 acpi_ut_valid_acpi_char(char character, u32 position); | |||
628 | 628 | ||
629 | void acpi_ut_repair_name(char *name); | 629 | void acpi_ut_repair_name(char *name); |
630 | 630 | ||
631 | #if defined (ACPI_DEBUGGER) || defined (ACPI_APPLICATION) | ||
632 | u8 acpi_ut_safe_strcpy(char *dest, acpi_size dest_size, char *source); | ||
633 | |||
634 | u8 acpi_ut_safe_strcat(char *dest, acpi_size dest_size, char *source); | ||
635 | |||
636 | u8 | ||
637 | acpi_ut_safe_strncat(char *dest, | ||
638 | acpi_size dest_size, | ||
639 | char *source, acpi_size max_transfer_length); | ||
640 | #endif | ||
641 | |||
631 | /* | 642 | /* |
632 | * utmutex - mutex support | 643 | * utmutex - mutex support |
633 | */ | 644 | */ |
@@ -652,12 +663,6 @@ acpi_status | |||
652 | acpi_ut_initialize_buffer(struct acpi_buffer *buffer, | 663 | acpi_ut_initialize_buffer(struct acpi_buffer *buffer, |
653 | acpi_size required_length); | 664 | acpi_size required_length); |
654 | 665 | ||
655 | void *acpi_ut_allocate(acpi_size size, | ||
656 | u32 component, const char *module, u32 line); | ||
657 | |||
658 | void *acpi_ut_allocate_zeroed(acpi_size size, | ||
659 | u32 component, const char *module, u32 line); | ||
660 | |||
661 | #ifdef ACPI_DBG_TRACK_ALLOCATIONS | 666 | #ifdef ACPI_DBG_TRACK_ALLOCATIONS |
662 | void *acpi_ut_allocate_and_track(acpi_size size, | 667 | void *acpi_ut_allocate_and_track(acpi_size size, |
663 | u32 component, const char *module, u32 line); | 668 | u32 component, const char *module, u32 line); |
diff --git a/drivers/acpi/acpica/dsargs.c b/drivers/acpi/acpica/dsargs.c index fb09b08d7080..afdc6df17abf 100644 --- a/drivers/acpi/acpica/dsargs.c +++ b/drivers/acpi/acpica/dsargs.c | |||
@@ -158,7 +158,7 @@ acpi_ds_execute_arguments(struct acpi_namespace_node *node, | |||
158 | walk_state->deferred_node = node; | 158 | walk_state->deferred_node = node; |
159 | status = acpi_ps_parse_aml(walk_state); | 159 | status = acpi_ps_parse_aml(walk_state); |
160 | 160 | ||
161 | cleanup: | 161 | cleanup: |
162 | acpi_ps_delete_parse_tree(op); | 162 | acpi_ps_delete_parse_tree(op); |
163 | return_ACPI_STATUS(status); | 163 | return_ACPI_STATUS(status); |
164 | } | 164 | } |
diff --git a/drivers/acpi/acpica/dsfield.c b/drivers/acpi/acpica/dsfield.c index d4bfe7b7f90a..2d4c07322576 100644 --- a/drivers/acpi/acpica/dsfield.c +++ b/drivers/acpi/acpica/dsfield.c | |||
@@ -259,7 +259,7 @@ acpi_ds_create_buffer_field(union acpi_parse_object *op, | |||
259 | goto cleanup; | 259 | goto cleanup; |
260 | } | 260 | } |
261 | 261 | ||
262 | cleanup: | 262 | cleanup: |
263 | 263 | ||
264 | /* Remove local reference to the object */ | 264 | /* Remove local reference to the object */ |
265 | 265 | ||
diff --git a/drivers/acpi/acpica/dsmethod.c b/drivers/acpi/acpica/dsmethod.c index a9ffd44c18fe..81a78ba84311 100644 --- a/drivers/acpi/acpica/dsmethod.c +++ b/drivers/acpi/acpica/dsmethod.c | |||
@@ -292,9 +292,10 @@ acpi_ds_begin_method_execution(struct acpi_namespace_node *method_node, | |||
292 | * reentered one more time (even if it is the same thread) | 292 | * reentered one more time (even if it is the same thread) |
293 | */ | 293 | */ |
294 | obj_desc->method.thread_count++; | 294 | obj_desc->method.thread_count++; |
295 | acpi_method_count++; | ||
295 | return_ACPI_STATUS(status); | 296 | return_ACPI_STATUS(status); |
296 | 297 | ||
297 | cleanup: | 298 | cleanup: |
298 | /* On error, must release the method mutex (if present) */ | 299 | /* On error, must release the method mutex (if present) */ |
299 | 300 | ||
300 | if (obj_desc->method.mutex) { | 301 | if (obj_desc->method.mutex) { |
@@ -424,7 +425,7 @@ acpi_ds_call_control_method(struct acpi_thread_state *thread, | |||
424 | 425 | ||
425 | return_ACPI_STATUS(status); | 426 | return_ACPI_STATUS(status); |
426 | 427 | ||
427 | cleanup: | 428 | cleanup: |
428 | 429 | ||
429 | /* On error, we must terminate the method properly */ | 430 | /* On error, we must terminate the method properly */ |
430 | 431 | ||
diff --git a/drivers/acpi/acpica/dsobject.c b/drivers/acpi/acpica/dsobject.c index 63f0d220ca3d..b1746a68dad1 100644 --- a/drivers/acpi/acpica/dsobject.c +++ b/drivers/acpi/acpica/dsobject.c | |||
@@ -240,7 +240,7 @@ acpi_ds_build_internal_object(struct acpi_walk_state *walk_state, | |||
240 | return_ACPI_STATUS(status); | 240 | return_ACPI_STATUS(status); |
241 | } | 241 | } |
242 | 242 | ||
243 | exit: | 243 | exit: |
244 | *obj_desc_ptr = obj_desc; | 244 | *obj_desc_ptr = obj_desc; |
245 | return_ACPI_STATUS(status); | 245 | return_ACPI_STATUS(status); |
246 | } | 246 | } |
diff --git a/drivers/acpi/acpica/dsopcode.c b/drivers/acpi/acpica/dsopcode.c index 1fc1ff114f26..5205edcf2c01 100644 --- a/drivers/acpi/acpica/dsopcode.c +++ b/drivers/acpi/acpica/dsopcode.c | |||
@@ -257,7 +257,7 @@ acpi_ds_init_buffer_field(u16 aml_opcode, | |||
257 | (buffer_desc->common.reference_count + | 257 | (buffer_desc->common.reference_count + |
258 | obj_desc->common.reference_count); | 258 | obj_desc->common.reference_count); |
259 | 259 | ||
260 | cleanup: | 260 | cleanup: |
261 | 261 | ||
262 | /* Always delete the operands */ | 262 | /* Always delete the operands */ |
263 | 263 | ||
diff --git a/drivers/acpi/acpica/dsutils.c b/drivers/acpi/acpica/dsutils.c index c666fc014987..ade44e49deb4 100644 --- a/drivers/acpi/acpica/dsutils.c +++ b/drivers/acpi/acpica/dsutils.c | |||
@@ -299,7 +299,7 @@ acpi_ds_is_result_used(union acpi_parse_object * op, | |||
299 | goto result_used; | 299 | goto result_used; |
300 | } | 300 | } |
301 | 301 | ||
302 | result_used: | 302 | result_used: |
303 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, | 303 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, |
304 | "Result of [%s] used by Parent [%s] Op=%p\n", | 304 | "Result of [%s] used by Parent [%s] Op=%p\n", |
305 | acpi_ps_get_opcode_name(op->common.aml_opcode), | 305 | acpi_ps_get_opcode_name(op->common.aml_opcode), |
@@ -308,7 +308,7 @@ acpi_ds_is_result_used(union acpi_parse_object * op, | |||
308 | 308 | ||
309 | return_UINT8(TRUE); | 309 | return_UINT8(TRUE); |
310 | 310 | ||
311 | result_not_used: | 311 | result_not_used: |
312 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, | 312 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, |
313 | "Result of [%s] not used by Parent [%s] Op=%p\n", | 313 | "Result of [%s] not used by Parent [%s] Op=%p\n", |
314 | acpi_ps_get_opcode_name(op->common.aml_opcode), | 314 | acpi_ps_get_opcode_name(op->common.aml_opcode), |
@@ -752,7 +752,7 @@ acpi_ds_create_operands(struct acpi_walk_state *walk_state, | |||
752 | 752 | ||
753 | return_ACPI_STATUS(status); | 753 | return_ACPI_STATUS(status); |
754 | 754 | ||
755 | cleanup: | 755 | cleanup: |
756 | /* | 756 | /* |
757 | * We must undo everything done above; meaning that we must | 757 | * We must undo everything done above; meaning that we must |
758 | * pop everything off of the operand stack and delete those | 758 | * pop everything off of the operand stack and delete those |
@@ -851,7 +851,7 @@ acpi_status acpi_ds_evaluate_name_path(struct acpi_walk_state *walk_state) | |||
851 | goto exit; | 851 | goto exit; |
852 | } | 852 | } |
853 | 853 | ||
854 | push_result: | 854 | push_result: |
855 | 855 | ||
856 | walk_state->result_obj = new_obj_desc; | 856 | walk_state->result_obj = new_obj_desc; |
857 | 857 | ||
@@ -863,7 +863,7 @@ acpi_status acpi_ds_evaluate_name_path(struct acpi_walk_state *walk_state) | |||
863 | op->common.flags |= ACPI_PARSEOP_IN_STACK; | 863 | op->common.flags |= ACPI_PARSEOP_IN_STACK; |
864 | } | 864 | } |
865 | 865 | ||
866 | exit: | 866 | exit: |
867 | 867 | ||
868 | return_ACPI_STATUS(status); | 868 | return_ACPI_STATUS(status); |
869 | } | 869 | } |
diff --git a/drivers/acpi/acpica/dswexec.c b/drivers/acpi/acpica/dswexec.c index 151d924817e1..1bbb22fd6fa0 100644 --- a/drivers/acpi/acpica/dswexec.c +++ b/drivers/acpi/acpica/dswexec.c | |||
@@ -170,7 +170,7 @@ acpi_ds_get_predicate_value(struct acpi_walk_state *walk_state, | |||
170 | 170 | ||
171 | (void)acpi_ds_do_implicit_return(local_obj_desc, walk_state, TRUE); | 171 | (void)acpi_ds_do_implicit_return(local_obj_desc, walk_state, TRUE); |
172 | 172 | ||
173 | cleanup: | 173 | cleanup: |
174 | 174 | ||
175 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Completed a predicate eval=%X Op=%p\n", | 175 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Completed a predicate eval=%X Op=%p\n", |
176 | walk_state->control_state->common.value, | 176 | walk_state->control_state->common.value, |
@@ -335,7 +335,7 @@ acpi_ds_exec_begin_op(struct acpi_walk_state *walk_state, | |||
335 | 335 | ||
336 | return_ACPI_STATUS(status); | 336 | return_ACPI_STATUS(status); |
337 | 337 | ||
338 | error_exit: | 338 | error_exit: |
339 | status = acpi_ds_method_error(status, walk_state); | 339 | status = acpi_ds_method_error(status, walk_state); |
340 | return_ACPI_STATUS(status); | 340 | return_ACPI_STATUS(status); |
341 | } | 341 | } |
@@ -722,7 +722,7 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state) | |||
722 | walk_state->result_obj = NULL; | 722 | walk_state->result_obj = NULL; |
723 | } | 723 | } |
724 | 724 | ||
725 | cleanup: | 725 | cleanup: |
726 | 726 | ||
727 | if (walk_state->result_obj) { | 727 | if (walk_state->result_obj) { |
728 | 728 | ||
diff --git a/drivers/acpi/acpica/dswload2.c b/drivers/acpi/acpica/dswload2.c index b1f8f4725c23..7f569d573027 100644 --- a/drivers/acpi/acpica/dswload2.c +++ b/drivers/acpi/acpica/dswload2.c | |||
@@ -728,7 +728,7 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state) | |||
728 | break; | 728 | break; |
729 | } | 729 | } |
730 | 730 | ||
731 | cleanup: | 731 | cleanup: |
732 | 732 | ||
733 | /* Remove the Node pushed at the very beginning */ | 733 | /* Remove the Node pushed at the very beginning */ |
734 | 734 | ||
diff --git a/drivers/acpi/acpica/evglock.c b/drivers/acpi/acpica/evglock.c index fdb0a76e40a3..4c67193a9fa7 100644 --- a/drivers/acpi/acpica/evglock.c +++ b/drivers/acpi/acpica/evglock.c | |||
@@ -173,7 +173,7 @@ static u32 acpi_ev_global_lock_handler(void *context) | |||
173 | 173 | ||
174 | acpi_gbl_global_lock_pending = FALSE; | 174 | acpi_gbl_global_lock_pending = FALSE; |
175 | 175 | ||
176 | cleanup_and_exit: | 176 | cleanup_and_exit: |
177 | 177 | ||
178 | acpi_os_release_lock(acpi_gbl_global_lock_pending_lock, flags); | 178 | acpi_os_release_lock(acpi_gbl_global_lock_pending_lock, flags); |
179 | return (ACPI_INTERRUPT_HANDLED); | 179 | return (ACPI_INTERRUPT_HANDLED); |
diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c index c8a1f7d5931f..a9cb4a1a4bb8 100644 --- a/drivers/acpi/acpica/evgpe.c +++ b/drivers/acpi/acpica/evgpe.c | |||
@@ -458,7 +458,7 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list) | |||
458 | gpe_block = gpe_block->next; | 458 | gpe_block = gpe_block->next; |
459 | } | 459 | } |
460 | 460 | ||
461 | unlock_and_exit: | 461 | unlock_and_exit: |
462 | 462 | ||
463 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); | 463 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); |
464 | return (int_status); | 464 | return (int_status); |
@@ -522,6 +522,7 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context) | |||
522 | 522 | ||
523 | status = acpi_ut_release_mutex(ACPI_MTX_EVENTS); | 523 | status = acpi_ut_release_mutex(ACPI_MTX_EVENTS); |
524 | if (ACPI_FAILURE(status)) { | 524 | if (ACPI_FAILURE(status)) { |
525 | ACPI_FREE(local_gpe_event_info); | ||
525 | return_VOID; | 526 | return_VOID; |
526 | } | 527 | } |
527 | 528 | ||
diff --git a/drivers/acpi/acpica/evgpeblk.c b/drivers/acpi/acpica/evgpeblk.c index c1aa1eda26c3..a9e76bc4ad97 100644 --- a/drivers/acpi/acpica/evgpeblk.c +++ b/drivers/acpi/acpica/evgpeblk.c | |||
@@ -111,7 +111,7 @@ acpi_ev_install_gpe_block(struct acpi_gpe_block_info *gpe_block, | |||
111 | gpe_block->xrupt_block = gpe_xrupt_block; | 111 | gpe_block->xrupt_block = gpe_xrupt_block; |
112 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); | 112 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); |
113 | 113 | ||
114 | unlock_and_exit: | 114 | unlock_and_exit: |
115 | status = acpi_ut_release_mutex(ACPI_MTX_EVENTS); | 115 | status = acpi_ut_release_mutex(ACPI_MTX_EVENTS); |
116 | return_ACPI_STATUS(status); | 116 | return_ACPI_STATUS(status); |
117 | } | 117 | } |
@@ -178,7 +178,7 @@ acpi_status acpi_ev_delete_gpe_block(struct acpi_gpe_block_info *gpe_block) | |||
178 | ACPI_FREE(gpe_block->event_info); | 178 | ACPI_FREE(gpe_block->event_info); |
179 | ACPI_FREE(gpe_block); | 179 | ACPI_FREE(gpe_block); |
180 | 180 | ||
181 | unlock_and_exit: | 181 | unlock_and_exit: |
182 | status = acpi_ut_release_mutex(ACPI_MTX_EVENTS); | 182 | status = acpi_ut_release_mutex(ACPI_MTX_EVENTS); |
183 | return_ACPI_STATUS(status); | 183 | return_ACPI_STATUS(status); |
184 | } | 184 | } |
@@ -302,7 +302,7 @@ acpi_ev_create_gpe_info_blocks(struct acpi_gpe_block_info *gpe_block) | |||
302 | 302 | ||
303 | return_ACPI_STATUS(AE_OK); | 303 | return_ACPI_STATUS(AE_OK); |
304 | 304 | ||
305 | error_exit: | 305 | error_exit: |
306 | if (gpe_register_info) { | 306 | if (gpe_register_info) { |
307 | ACPI_FREE(gpe_register_info); | 307 | ACPI_FREE(gpe_register_info); |
308 | } | 308 | } |
diff --git a/drivers/acpi/acpica/evgpeinit.c b/drivers/acpi/acpica/evgpeinit.c index 7842700346a4..a3e2f38aadf6 100644 --- a/drivers/acpi/acpica/evgpeinit.c +++ b/drivers/acpi/acpica/evgpeinit.c | |||
@@ -203,7 +203,7 @@ acpi_status acpi_ev_gpe_initialize(void) | |||
203 | goto cleanup; | 203 | goto cleanup; |
204 | } | 204 | } |
205 | 205 | ||
206 | cleanup: | 206 | cleanup: |
207 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | 207 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); |
208 | return_ACPI_STATUS(AE_OK); | 208 | return_ACPI_STATUS(AE_OK); |
209 | } | 209 | } |
diff --git a/drivers/acpi/acpica/evgpeutil.c b/drivers/acpi/acpica/evgpeutil.c index b24dbb80fab8..d3f5e1e2a2b1 100644 --- a/drivers/acpi/acpica/evgpeutil.c +++ b/drivers/acpi/acpica/evgpeutil.c | |||
@@ -101,7 +101,7 @@ acpi_ev_walk_gpe_list(acpi_gpe_callback gpe_walk_callback, void *context) | |||
101 | gpe_xrupt_info = gpe_xrupt_info->next; | 101 | gpe_xrupt_info = gpe_xrupt_info->next; |
102 | } | 102 | } |
103 | 103 | ||
104 | unlock_and_exit: | 104 | unlock_and_exit: |
105 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); | 105 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); |
106 | return_ACPI_STATUS(status); | 106 | return_ACPI_STATUS(status); |
107 | } | 107 | } |
@@ -196,7 +196,7 @@ acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info, | |||
196 | * | 196 | * |
197 | * FUNCTION: acpi_ev_get_gpe_xrupt_block | 197 | * FUNCTION: acpi_ev_get_gpe_xrupt_block |
198 | * | 198 | * |
199 | * PARAMETERS: interrupt_number - Interrupt for a GPE block | 199 | * PARAMETERS: interrupt_number - Interrupt for a GPE block |
200 | * | 200 | * |
201 | * RETURN: A GPE interrupt block | 201 | * RETURN: A GPE interrupt block |
202 | * | 202 | * |
diff --git a/drivers/acpi/acpica/evhandler.c b/drivers/acpi/acpica/evhandler.c index 068af96134b8..e3157313eb27 100644 --- a/drivers/acpi/acpica/evhandler.c +++ b/drivers/acpi/acpica/evhandler.c | |||
@@ -129,7 +129,7 @@ acpi_status acpi_ev_install_region_handlers(void) | |||
129 | } | 129 | } |
130 | } | 130 | } |
131 | 131 | ||
132 | unlock_and_exit: | 132 | unlock_and_exit: |
133 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | 133 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); |
134 | return_ACPI_STATUS(status); | 134 | return_ACPI_STATUS(status); |
135 | } | 135 | } |
@@ -531,6 +531,6 @@ acpi_ev_install_space_handler(struct acpi_namespace_node * node, | |||
531 | acpi_ev_install_handler, NULL, | 531 | acpi_ev_install_handler, NULL, |
532 | handler_obj, NULL); | 532 | handler_obj, NULL); |
533 | 533 | ||
534 | unlock_and_exit: | 534 | unlock_and_exit: |
535 | return_ACPI_STATUS(status); | 535 | return_ACPI_STATUS(status); |
536 | } | 536 | } |
diff --git a/drivers/acpi/acpica/evmisc.c b/drivers/acpi/acpica/evmisc.c index 1b111ef74903..a5687540e9a6 100644 --- a/drivers/acpi/acpica/evmisc.c +++ b/drivers/acpi/acpica/evmisc.c | |||
@@ -264,13 +264,6 @@ void acpi_ev_terminate(void) | |||
264 | 264 | ||
265 | status = acpi_ev_walk_gpe_list(acpi_hw_disable_gpe_block, NULL); | 265 | status = acpi_ev_walk_gpe_list(acpi_hw_disable_gpe_block, NULL); |
266 | 266 | ||
267 | /* Remove SCI handler */ | ||
268 | |||
269 | status = acpi_ev_remove_sci_handler(); | ||
270 | if (ACPI_FAILURE(status)) { | ||
271 | ACPI_ERROR((AE_INFO, "Could not remove SCI handler")); | ||
272 | } | ||
273 | |||
274 | status = acpi_ev_remove_global_lock_handler(); | 267 | status = acpi_ev_remove_global_lock_handler(); |
275 | if (ACPI_FAILURE(status)) { | 268 | if (ACPI_FAILURE(status)) { |
276 | ACPI_ERROR((AE_INFO, | 269 | ACPI_ERROR((AE_INFO, |
@@ -280,6 +273,13 @@ void acpi_ev_terminate(void) | |||
280 | acpi_gbl_events_initialized = FALSE; | 273 | acpi_gbl_events_initialized = FALSE; |
281 | } | 274 | } |
282 | 275 | ||
276 | /* Remove SCI handlers */ | ||
277 | |||
278 | status = acpi_ev_remove_all_sci_handlers(); | ||
279 | if (ACPI_FAILURE(status)) { | ||
280 | ACPI_ERROR((AE_INFO, "Could not remove SCI handler")); | ||
281 | } | ||
282 | |||
283 | /* Deallocate all handler objects installed within GPE info structs */ | 283 | /* Deallocate all handler objects installed within GPE info structs */ |
284 | 284 | ||
285 | status = acpi_ev_walk_gpe_list(acpi_ev_delete_gpe_handlers, NULL); | 285 | status = acpi_ev_walk_gpe_list(acpi_ev_delete_gpe_handlers, NULL); |
diff --git a/drivers/acpi/acpica/evregion.c b/drivers/acpi/acpica/evregion.c index cea14d6fc76c..144cbb9b73bc 100644 --- a/drivers/acpi/acpica/evregion.c +++ b/drivers/acpi/acpica/evregion.c | |||
@@ -217,16 +217,11 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, | |||
217 | if (!(region_obj->region.flags & AOPOBJ_SETUP_COMPLETE)) { | 217 | if (!(region_obj->region.flags & AOPOBJ_SETUP_COMPLETE)) { |
218 | region_obj->region.flags |= AOPOBJ_SETUP_COMPLETE; | 218 | region_obj->region.flags |= AOPOBJ_SETUP_COMPLETE; |
219 | 219 | ||
220 | if (region_obj2->extra.region_context) { | 220 | /* |
221 | 221 | * Save the returned context for use in all accesses to | |
222 | /* The handler for this region was already installed */ | 222 | * the handler for this particular region |
223 | 223 | */ | |
224 | ACPI_FREE(region_context); | 224 | if (!(region_obj2->extra.region_context)) { |
225 | } else { | ||
226 | /* | ||
227 | * Save the returned context for use in all accesses to | ||
228 | * this particular region | ||
229 | */ | ||
230 | region_obj2->extra.region_context = | 225 | region_obj2->extra.region_context = |
231 | region_context; | 226 | region_context; |
232 | } | 227 | } |
@@ -402,6 +397,14 @@ acpi_ev_detach_region(union acpi_operand_object *region_obj, | |||
402 | handler_obj->address_space. | 397 | handler_obj->address_space. |
403 | context, region_context); | 398 | context, region_context); |
404 | 399 | ||
400 | /* | ||
401 | * region_context should have been released by the deactivate | ||
402 | * operation. We don't need access to it anymore here. | ||
403 | */ | ||
404 | if (region_context) { | ||
405 | *region_context = NULL; | ||
406 | } | ||
407 | |||
405 | /* Init routine may fail, Just ignore errors */ | 408 | /* Init routine may fail, Just ignore errors */ |
406 | 409 | ||
407 | if (ACPI_FAILURE(status)) { | 410 | if (ACPI_FAILURE(status)) { |
@@ -570,10 +573,10 @@ acpi_ev_execute_reg_method(union acpi_operand_object *region_obj, u32 function) | |||
570 | status = acpi_ns_evaluate(info); | 573 | status = acpi_ns_evaluate(info); |
571 | acpi_ut_remove_reference(args[1]); | 574 | acpi_ut_remove_reference(args[1]); |
572 | 575 | ||
573 | cleanup2: | 576 | cleanup2: |
574 | acpi_ut_remove_reference(args[0]); | 577 | acpi_ut_remove_reference(args[0]); |
575 | 578 | ||
576 | cleanup1: | 579 | cleanup1: |
577 | ACPI_FREE(info); | 580 | ACPI_FREE(info); |
578 | return_ACPI_STATUS(status); | 581 | return_ACPI_STATUS(status); |
579 | } | 582 | } |
@@ -758,7 +761,7 @@ acpi_ev_orphan_ec_reg_method(struct acpi_namespace_node *ec_device_node) | |||
758 | 761 | ||
759 | status = acpi_evaluate_object(reg_method, NULL, &args, NULL); | 762 | status = acpi_evaluate_object(reg_method, NULL, &args, NULL); |
760 | 763 | ||
761 | exit: | 764 | exit: |
762 | /* We ignore all errors from above, don't care */ | 765 | /* We ignore all errors from above, don't care */ |
763 | 766 | ||
764 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | 767 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); |
diff --git a/drivers/acpi/acpica/evsci.c b/drivers/acpi/acpica/evsci.c index b905acf7aacd..9e9e3454d893 100644 --- a/drivers/acpi/acpica/evsci.c +++ b/drivers/acpi/acpica/evsci.c | |||
@@ -54,6 +54,50 @@ static u32 ACPI_SYSTEM_XFACE acpi_ev_sci_xrupt_handler(void *context); | |||
54 | 54 | ||
55 | /******************************************************************************* | 55 | /******************************************************************************* |
56 | * | 56 | * |
57 | * FUNCTION: acpi_ev_sci_dispatch | ||
58 | * | ||
59 | * PARAMETERS: None | ||
60 | * | ||
61 | * RETURN: Status code indicates whether interrupt was handled. | ||
62 | * | ||
63 | * DESCRIPTION: Dispatch the SCI to all host-installed SCI handlers. | ||
64 | * | ||
65 | ******************************************************************************/ | ||
66 | |||
67 | u32 acpi_ev_sci_dispatch(void) | ||
68 | { | ||
69 | struct acpi_sci_handler_info *sci_handler; | ||
70 | acpi_cpu_flags flags; | ||
71 | u32 int_status = ACPI_INTERRUPT_NOT_HANDLED; | ||
72 | |||
73 | ACPI_FUNCTION_NAME(ev_sci_dispatch); | ||
74 | |||
75 | /* Are there any host-installed SCI handlers? */ | ||
76 | |||
77 | if (!acpi_gbl_sci_handler_list) { | ||
78 | return (int_status); | ||
79 | } | ||
80 | |||
81 | flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); | ||
82 | |||
83 | /* Invoke all host-installed SCI handlers */ | ||
84 | |||
85 | sci_handler = acpi_gbl_sci_handler_list; | ||
86 | while (sci_handler) { | ||
87 | |||
88 | /* Invoke the installed handler (at interrupt level) */ | ||
89 | |||
90 | int_status |= sci_handler->address(sci_handler->context); | ||
91 | |||
92 | sci_handler = sci_handler->next; | ||
93 | } | ||
94 | |||
95 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); | ||
96 | return (int_status); | ||
97 | } | ||
98 | |||
99 | /******************************************************************************* | ||
100 | * | ||
57 | * FUNCTION: acpi_ev_sci_xrupt_handler | 101 | * FUNCTION: acpi_ev_sci_xrupt_handler |
58 | * | 102 | * |
59 | * PARAMETERS: context - Calling Context | 103 | * PARAMETERS: context - Calling Context |
@@ -89,6 +133,11 @@ static u32 ACPI_SYSTEM_XFACE acpi_ev_sci_xrupt_handler(void *context) | |||
89 | */ | 133 | */ |
90 | interrupt_handled |= acpi_ev_gpe_detect(gpe_xrupt_list); | 134 | interrupt_handled |= acpi_ev_gpe_detect(gpe_xrupt_list); |
91 | 135 | ||
136 | /* Invoke all host-installed SCI handlers */ | ||
137 | |||
138 | interrupt_handled |= acpi_ev_sci_dispatch(); | ||
139 | |||
140 | acpi_sci_count++; | ||
92 | return_UINT32(interrupt_handled); | 141 | return_UINT32(interrupt_handled); |
93 | } | 142 | } |
94 | 143 | ||
@@ -112,14 +161,13 @@ u32 ACPI_SYSTEM_XFACE acpi_ev_gpe_xrupt_handler(void *context) | |||
112 | ACPI_FUNCTION_TRACE(ev_gpe_xrupt_handler); | 161 | ACPI_FUNCTION_TRACE(ev_gpe_xrupt_handler); |
113 | 162 | ||
114 | /* | 163 | /* |
115 | * We are guaranteed by the ACPI CA initialization/shutdown code that | 164 | * We are guaranteed by the ACPICA initialization/shutdown code that |
116 | * if this interrupt handler is installed, ACPI is enabled. | 165 | * if this interrupt handler is installed, ACPI is enabled. |
117 | */ | 166 | */ |
118 | 167 | ||
119 | /* GPEs: Check for and dispatch any GPEs that have occurred */ | 168 | /* GPEs: Check for and dispatch any GPEs that have occurred */ |
120 | 169 | ||
121 | interrupt_handled |= acpi_ev_gpe_detect(gpe_xrupt_list); | 170 | interrupt_handled |= acpi_ev_gpe_detect(gpe_xrupt_list); |
122 | |||
123 | return_UINT32(interrupt_handled); | 171 | return_UINT32(interrupt_handled); |
124 | } | 172 | } |
125 | 173 | ||
@@ -150,15 +198,15 @@ u32 acpi_ev_install_sci_handler(void) | |||
150 | 198 | ||
151 | /****************************************************************************** | 199 | /****************************************************************************** |
152 | * | 200 | * |
153 | * FUNCTION: acpi_ev_remove_sci_handler | 201 | * FUNCTION: acpi_ev_remove_all_sci_handlers |
154 | * | 202 | * |
155 | * PARAMETERS: none | 203 | * PARAMETERS: none |
156 | * | 204 | * |
157 | * RETURN: E_OK if handler uninstalled OK, E_ERROR if handler was not | 205 | * RETURN: AE_OK if handler uninstalled, AE_ERROR if handler was not |
158 | * installed to begin with | 206 | * installed to begin with |
159 | * | 207 | * |
160 | * DESCRIPTION: Remove the SCI interrupt handler. No further SCIs will be | 208 | * DESCRIPTION: Remove the SCI interrupt handler. No further SCIs will be |
161 | * taken. | 209 | * taken. Remove all host-installed SCI handlers. |
162 | * | 210 | * |
163 | * Note: It doesn't seem important to disable all events or set the event | 211 | * Note: It doesn't seem important to disable all events or set the event |
164 | * enable registers to their original values. The OS should disable | 212 | * enable registers to their original values. The OS should disable |
@@ -167,11 +215,13 @@ u32 acpi_ev_install_sci_handler(void) | |||
167 | * | 215 | * |
168 | ******************************************************************************/ | 216 | ******************************************************************************/ |
169 | 217 | ||
170 | acpi_status acpi_ev_remove_sci_handler(void) | 218 | acpi_status acpi_ev_remove_all_sci_handlers(void) |
171 | { | 219 | { |
220 | struct acpi_sci_handler_info *sci_handler; | ||
221 | acpi_cpu_flags flags; | ||
172 | acpi_status status; | 222 | acpi_status status; |
173 | 223 | ||
174 | ACPI_FUNCTION_TRACE(ev_remove_sci_handler); | 224 | ACPI_FUNCTION_TRACE(ev_remove_all_sci_handlers); |
175 | 225 | ||
176 | /* Just let the OS remove the handler and disable the level */ | 226 | /* Just let the OS remove the handler and disable the level */ |
177 | 227 | ||
@@ -179,6 +229,21 @@ acpi_status acpi_ev_remove_sci_handler(void) | |||
179 | acpi_os_remove_interrupt_handler((u32) acpi_gbl_FADT.sci_interrupt, | 229 | acpi_os_remove_interrupt_handler((u32) acpi_gbl_FADT.sci_interrupt, |
180 | acpi_ev_sci_xrupt_handler); | 230 | acpi_ev_sci_xrupt_handler); |
181 | 231 | ||
232 | if (!acpi_gbl_sci_handler_list) { | ||
233 | return (status); | ||
234 | } | ||
235 | |||
236 | flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); | ||
237 | |||
238 | /* Free all host-installed SCI handlers */ | ||
239 | |||
240 | while (acpi_gbl_sci_handler_list) { | ||
241 | sci_handler = acpi_gbl_sci_handler_list; | ||
242 | acpi_gbl_sci_handler_list = sci_handler->next; | ||
243 | ACPI_FREE(sci_handler); | ||
244 | } | ||
245 | |||
246 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); | ||
182 | return_ACPI_STATUS(status); | 247 | return_ACPI_STATUS(status); |
183 | } | 248 | } |
184 | 249 | ||
diff --git a/drivers/acpi/acpica/evxface.c b/drivers/acpi/acpica/evxface.c index ca5fba99c33b..23a7fadca412 100644 --- a/drivers/acpi/acpica/evxface.c +++ b/drivers/acpi/acpica/evxface.c | |||
@@ -41,7 +41,8 @@ | |||
41 | * POSSIBILITY OF SUCH DAMAGES. | 41 | * POSSIBILITY OF SUCH DAMAGES. |
42 | */ | 42 | */ |
43 | 43 | ||
44 | #include <linux/export.h> | 44 | #define EXPORT_ACPI_INTERFACES |
45 | |||
45 | #include <acpi/acpi.h> | 46 | #include <acpi/acpi.h> |
46 | #include "accommon.h" | 47 | #include "accommon.h" |
47 | #include "acnamesp.h" | 48 | #include "acnamesp.h" |
@@ -374,7 +375,7 @@ acpi_status acpi_install_exception_handler(acpi_exception_handler handler) | |||
374 | 375 | ||
375 | acpi_gbl_exception_handler = handler; | 376 | acpi_gbl_exception_handler = handler; |
376 | 377 | ||
377 | cleanup: | 378 | cleanup: |
378 | (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); | 379 | (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); |
379 | return_ACPI_STATUS(status); | 380 | return_ACPI_STATUS(status); |
380 | } | 381 | } |
@@ -385,6 +386,144 @@ ACPI_EXPORT_SYMBOL(acpi_install_exception_handler) | |||
385 | #if (!ACPI_REDUCED_HARDWARE) | 386 | #if (!ACPI_REDUCED_HARDWARE) |
386 | /******************************************************************************* | 387 | /******************************************************************************* |
387 | * | 388 | * |
389 | * FUNCTION: acpi_install_sci_handler | ||
390 | * | ||
391 | * PARAMETERS: address - Address of the handler | ||
392 | * context - Value passed to the handler on each SCI | ||
393 | * | ||
394 | * RETURN: Status | ||
395 | * | ||
396 | * DESCRIPTION: Install a handler for a System Control Interrupt. | ||
397 | * | ||
398 | ******************************************************************************/ | ||
399 | acpi_status acpi_install_sci_handler(acpi_sci_handler address, void *context) | ||
400 | { | ||
401 | struct acpi_sci_handler_info *new_sci_handler; | ||
402 | struct acpi_sci_handler_info *sci_handler; | ||
403 | acpi_cpu_flags flags; | ||
404 | acpi_status status; | ||
405 | |||
406 | ACPI_FUNCTION_TRACE(acpi_install_sci_handler); | ||
407 | |||
408 | if (!address) { | ||
409 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
410 | } | ||
411 | |||
412 | /* Allocate and init a handler object */ | ||
413 | |||
414 | new_sci_handler = ACPI_ALLOCATE(sizeof(struct acpi_sci_handler_info)); | ||
415 | if (!new_sci_handler) { | ||
416 | return_ACPI_STATUS(AE_NO_MEMORY); | ||
417 | } | ||
418 | |||
419 | new_sci_handler->address = address; | ||
420 | new_sci_handler->context = context; | ||
421 | |||
422 | status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); | ||
423 | if (ACPI_FAILURE(status)) { | ||
424 | goto exit; | ||
425 | } | ||
426 | |||
427 | /* Lock list during installation */ | ||
428 | |||
429 | flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); | ||
430 | sci_handler = acpi_gbl_sci_handler_list; | ||
431 | |||
432 | /* Ensure handler does not already exist */ | ||
433 | |||
434 | while (sci_handler) { | ||
435 | if (address == sci_handler->address) { | ||
436 | status = AE_ALREADY_EXISTS; | ||
437 | goto unlock_and_exit; | ||
438 | } | ||
439 | |||
440 | sci_handler = sci_handler->next; | ||
441 | } | ||
442 | |||
443 | /* Install the new handler into the global list (at head) */ | ||
444 | |||
445 | new_sci_handler->next = acpi_gbl_sci_handler_list; | ||
446 | acpi_gbl_sci_handler_list = new_sci_handler; | ||
447 | |||
448 | unlock_and_exit: | ||
449 | |||
450 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); | ||
451 | (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); | ||
452 | |||
453 | exit: | ||
454 | if (ACPI_FAILURE(status)) { | ||
455 | ACPI_FREE(new_sci_handler); | ||
456 | } | ||
457 | return_ACPI_STATUS(status); | ||
458 | } | ||
459 | |||
460 | /******************************************************************************* | ||
461 | * | ||
462 | * FUNCTION: acpi_remove_sci_handler | ||
463 | * | ||
464 | * PARAMETERS: address - Address of the handler | ||
465 | * | ||
466 | * RETURN: Status | ||
467 | * | ||
468 | * DESCRIPTION: Remove a handler for a System Control Interrupt. | ||
469 | * | ||
470 | ******************************************************************************/ | ||
471 | |||
472 | acpi_status acpi_remove_sci_handler(acpi_sci_handler address) | ||
473 | { | ||
474 | struct acpi_sci_handler_info *prev_sci_handler; | ||
475 | struct acpi_sci_handler_info *next_sci_handler; | ||
476 | acpi_cpu_flags flags; | ||
477 | acpi_status status; | ||
478 | |||
479 | ACPI_FUNCTION_TRACE(acpi_remove_sci_handler); | ||
480 | |||
481 | if (!address) { | ||
482 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
483 | } | ||
484 | |||
485 | status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); | ||
486 | if (ACPI_FAILURE(status)) { | ||
487 | return_ACPI_STATUS(status); | ||
488 | } | ||
489 | |||
490 | /* Remove the SCI handler with lock */ | ||
491 | |||
492 | flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); | ||
493 | |||
494 | prev_sci_handler = NULL; | ||
495 | next_sci_handler = acpi_gbl_sci_handler_list; | ||
496 | while (next_sci_handler) { | ||
497 | if (next_sci_handler->address == address) { | ||
498 | |||
499 | /* Unlink and free the SCI handler info block */ | ||
500 | |||
501 | if (prev_sci_handler) { | ||
502 | prev_sci_handler->next = next_sci_handler->next; | ||
503 | } else { | ||
504 | acpi_gbl_sci_handler_list = | ||
505 | next_sci_handler->next; | ||
506 | } | ||
507 | |||
508 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); | ||
509 | ACPI_FREE(next_sci_handler); | ||
510 | goto unlock_and_exit; | ||
511 | } | ||
512 | |||
513 | prev_sci_handler = next_sci_handler; | ||
514 | next_sci_handler = next_sci_handler->next; | ||
515 | } | ||
516 | |||
517 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); | ||
518 | status = AE_NOT_EXIST; | ||
519 | |||
520 | unlock_and_exit: | ||
521 | (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); | ||
522 | return_ACPI_STATUS(status); | ||
523 | } | ||
524 | |||
525 | /******************************************************************************* | ||
526 | * | ||
388 | * FUNCTION: acpi_install_global_event_handler | 527 | * FUNCTION: acpi_install_global_event_handler |
389 | * | 528 | * |
390 | * PARAMETERS: handler - Pointer to the global event handler function | 529 | * PARAMETERS: handler - Pointer to the global event handler function |
@@ -398,6 +537,7 @@ ACPI_EXPORT_SYMBOL(acpi_install_exception_handler) | |||
398 | * Can be used to update event counters, etc. | 537 | * Can be used to update event counters, etc. |
399 | * | 538 | * |
400 | ******************************************************************************/ | 539 | ******************************************************************************/ |
540 | |||
401 | acpi_status | 541 | acpi_status |
402 | acpi_install_global_event_handler(acpi_gbl_event_handler handler, void *context) | 542 | acpi_install_global_event_handler(acpi_gbl_event_handler handler, void *context) |
403 | { | 543 | { |
@@ -426,7 +566,7 @@ acpi_install_global_event_handler(acpi_gbl_event_handler handler, void *context) | |||
426 | acpi_gbl_global_event_handler = handler; | 566 | acpi_gbl_global_event_handler = handler; |
427 | acpi_gbl_global_event_handler_context = context; | 567 | acpi_gbl_global_event_handler_context = context; |
428 | 568 | ||
429 | cleanup: | 569 | cleanup: |
430 | (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); | 570 | (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); |
431 | return_ACPI_STATUS(status); | 571 | return_ACPI_STATUS(status); |
432 | } | 572 | } |
@@ -498,7 +638,7 @@ acpi_install_fixed_event_handler(u32 event, | |||
498 | handler)); | 638 | handler)); |
499 | } | 639 | } |
500 | 640 | ||
501 | cleanup: | 641 | cleanup: |
502 | (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); | 642 | (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); |
503 | return_ACPI_STATUS(status); | 643 | return_ACPI_STATUS(status); |
504 | } | 644 | } |
diff --git a/drivers/acpi/acpica/evxfevnt.c b/drivers/acpi/acpica/evxfevnt.c index 7039606a0ba8..39d06af5e347 100644 --- a/drivers/acpi/acpica/evxfevnt.c +++ b/drivers/acpi/acpica/evxfevnt.c | |||
@@ -41,7 +41,8 @@ | |||
41 | * POSSIBILITY OF SUCH DAMAGES. | 41 | * POSSIBILITY OF SUCH DAMAGES. |
42 | */ | 42 | */ |
43 | 43 | ||
44 | #include <linux/export.h> | 44 | #define EXPORT_ACPI_INTERFACES |
45 | |||
45 | #include <acpi/acpi.h> | 46 | #include <acpi/acpi.h> |
46 | #include "accommon.h" | 47 | #include "accommon.h" |
47 | #include "actables.h" | 48 | #include "actables.h" |
diff --git a/drivers/acpi/acpica/evxfgpe.c b/drivers/acpi/acpica/evxfgpe.c index 7662f1a42ff6..5713da77c665 100644 --- a/drivers/acpi/acpica/evxfgpe.c +++ b/drivers/acpi/acpica/evxfgpe.c | |||
@@ -41,7 +41,8 @@ | |||
41 | * POSSIBILITY OF SUCH DAMAGES. | 41 | * POSSIBILITY OF SUCH DAMAGES. |
42 | */ | 42 | */ |
43 | 43 | ||
44 | #include <linux/export.h> | 44 | #define EXPORT_ACPI_INTERFACES |
45 | |||
45 | #include <acpi/acpi.h> | 46 | #include <acpi/acpi.h> |
46 | #include "accommon.h" | 47 | #include "accommon.h" |
47 | #include "acevents.h" | 48 | #include "acevents.h" |
@@ -471,7 +472,7 @@ acpi_get_gpe_status(acpi_handle gpe_device, | |||
471 | if (gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) | 472 | if (gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) |
472 | *event_status |= ACPI_EVENT_FLAG_HANDLE; | 473 | *event_status |= ACPI_EVENT_FLAG_HANDLE; |
473 | 474 | ||
474 | unlock_and_exit: | 475 | unlock_and_exit: |
475 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); | 476 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); |
476 | return_ACPI_STATUS(status); | 477 | return_ACPI_STATUS(status); |
477 | } | 478 | } |
@@ -624,7 +625,7 @@ acpi_install_gpe_block(acpi_handle gpe_device, | |||
624 | 625 | ||
625 | obj_desc->device.gpe_block = gpe_block; | 626 | obj_desc->device.gpe_block = gpe_block; |
626 | 627 | ||
627 | unlock_and_exit: | 628 | unlock_and_exit: |
628 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | 629 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); |
629 | return_ACPI_STATUS(status); | 630 | return_ACPI_STATUS(status); |
630 | } | 631 | } |
@@ -679,7 +680,7 @@ acpi_status acpi_remove_gpe_block(acpi_handle gpe_device) | |||
679 | obj_desc->device.gpe_block = NULL; | 680 | obj_desc->device.gpe_block = NULL; |
680 | } | 681 | } |
681 | 682 | ||
682 | unlock_and_exit: | 683 | unlock_and_exit: |
683 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | 684 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); |
684 | return_ACPI_STATUS(status); | 685 | return_ACPI_STATUS(status); |
685 | } | 686 | } |
diff --git a/drivers/acpi/acpica/evxfregn.c b/drivers/acpi/acpica/evxfregn.c index 80cecf838591..02ed75ac56cd 100644 --- a/drivers/acpi/acpica/evxfregn.c +++ b/drivers/acpi/acpica/evxfregn.c | |||
@@ -42,7 +42,8 @@ | |||
42 | * POSSIBILITY OF SUCH DAMAGES. | 42 | * POSSIBILITY OF SUCH DAMAGES. |
43 | */ | 43 | */ |
44 | 44 | ||
45 | #include <linux/export.h> | 45 | #define EXPORT_ACPI_INTERFACES |
46 | |||
46 | #include <acpi/acpi.h> | 47 | #include <acpi/acpi.h> |
47 | #include "accommon.h" | 48 | #include "accommon.h" |
48 | #include "acnamesp.h" | 49 | #include "acnamesp.h" |
@@ -147,7 +148,7 @@ acpi_install_address_space_handler(acpi_handle device, | |||
147 | 148 | ||
148 | status = acpi_ev_execute_reg_methods(node, space_id); | 149 | status = acpi_ev_execute_reg_methods(node, space_id); |
149 | 150 | ||
150 | unlock_and_exit: | 151 | unlock_and_exit: |
151 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | 152 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); |
152 | return_ACPI_STATUS(status); | 153 | return_ACPI_STATUS(status); |
153 | } | 154 | } |
@@ -286,7 +287,7 @@ acpi_remove_address_space_handler(acpi_handle device, | |||
286 | 287 | ||
287 | status = AE_NOT_EXIST; | 288 | status = AE_NOT_EXIST; |
288 | 289 | ||
289 | unlock_and_exit: | 290 | unlock_and_exit: |
290 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | 291 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); |
291 | return_ACPI_STATUS(status); | 292 | return_ACPI_STATUS(status); |
292 | } | 293 | } |
diff --git a/drivers/acpi/acpica/excreate.c b/drivers/acpi/acpica/excreate.c index 269e81d86ef4..3c2e6dcdad3e 100644 --- a/drivers/acpi/acpica/excreate.c +++ b/drivers/acpi/acpica/excreate.c | |||
@@ -193,7 +193,7 @@ acpi_status acpi_ex_create_event(struct acpi_walk_state *walk_state) | |||
193 | acpi_ns_attach_object((struct acpi_namespace_node *)walk_state-> | 193 | acpi_ns_attach_object((struct acpi_namespace_node *)walk_state-> |
194 | operands[0], obj_desc, ACPI_TYPE_EVENT); | 194 | operands[0], obj_desc, ACPI_TYPE_EVENT); |
195 | 195 | ||
196 | cleanup: | 196 | cleanup: |
197 | /* | 197 | /* |
198 | * Remove local reference to the object (on error, will cause deletion | 198 | * Remove local reference to the object (on error, will cause deletion |
199 | * of both object and semaphore if present.) | 199 | * of both object and semaphore if present.) |
@@ -248,7 +248,7 @@ acpi_status acpi_ex_create_mutex(struct acpi_walk_state *walk_state) | |||
248 | acpi_ns_attach_object(obj_desc->mutex.node, obj_desc, | 248 | acpi_ns_attach_object(obj_desc->mutex.node, obj_desc, |
249 | ACPI_TYPE_MUTEX); | 249 | ACPI_TYPE_MUTEX); |
250 | 250 | ||
251 | cleanup: | 251 | cleanup: |
252 | /* | 252 | /* |
253 | * Remove local reference to the object (on error, will cause deletion | 253 | * Remove local reference to the object (on error, will cause deletion |
254 | * of both object and semaphore if present.) | 254 | * of both object and semaphore if present.) |
@@ -347,7 +347,7 @@ acpi_ex_create_region(u8 * aml_start, | |||
347 | 347 | ||
348 | status = acpi_ns_attach_object(node, obj_desc, ACPI_TYPE_REGION); | 348 | status = acpi_ns_attach_object(node, obj_desc, ACPI_TYPE_REGION); |
349 | 349 | ||
350 | cleanup: | 350 | cleanup: |
351 | 351 | ||
352 | /* Remove local reference to the object */ | 352 | /* Remove local reference to the object */ |
353 | 353 | ||
@@ -520,7 +520,7 @@ acpi_ex_create_method(u8 * aml_start, | |||
520 | 520 | ||
521 | acpi_ut_remove_reference(obj_desc); | 521 | acpi_ut_remove_reference(obj_desc); |
522 | 522 | ||
523 | exit: | 523 | exit: |
524 | /* Remove a reference to the operand */ | 524 | /* Remove a reference to the operand */ |
525 | 525 | ||
526 | acpi_ut_remove_reference(operand[1]); | 526 | acpi_ut_remove_reference(operand[1]); |
diff --git a/drivers/acpi/acpica/exfield.c b/drivers/acpi/acpica/exfield.c index c2a65aaf29af..cfd875243421 100644 --- a/drivers/acpi/acpica/exfield.c +++ b/drivers/acpi/acpica/exfield.c | |||
@@ -197,7 +197,7 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state, | |||
197 | status = acpi_ex_extract_from_field(obj_desc, buffer, (u32) length); | 197 | status = acpi_ex_extract_from_field(obj_desc, buffer, (u32) length); |
198 | acpi_ex_release_global_lock(obj_desc->common_field.field_flags); | 198 | acpi_ex_release_global_lock(obj_desc->common_field.field_flags); |
199 | 199 | ||
200 | exit: | 200 | exit: |
201 | if (ACPI_FAILURE(status)) { | 201 | if (ACPI_FAILURE(status)) { |
202 | acpi_ut_remove_reference(buffer_desc); | 202 | acpi_ut_remove_reference(buffer_desc); |
203 | } else { | 203 | } else { |
diff --git a/drivers/acpi/acpica/exfldio.c b/drivers/acpi/acpica/exfldio.c index 7e0afe72487e..49fb742d61b9 100644 --- a/drivers/acpi/acpica/exfldio.c +++ b/drivers/acpi/acpica/exfldio.c | |||
@@ -123,12 +123,6 @@ acpi_ex_setup_region(union acpi_operand_object *obj_desc, | |||
123 | } | 123 | } |
124 | } | 124 | } |
125 | 125 | ||
126 | /* Exit if Address/Length have been disallowed by the host OS */ | ||
127 | |||
128 | if (rgn_desc->common.flags & AOPOBJ_INVALID) { | ||
129 | return_ACPI_STATUS(AE_AML_ILLEGAL_ADDRESS); | ||
130 | } | ||
131 | |||
132 | /* | 126 | /* |
133 | * Exit now for SMBus, GSBus or IPMI address space, it has a non-linear | 127 | * Exit now for SMBus, GSBus or IPMI address space, it has a non-linear |
134 | * address space and the request cannot be directly validated | 128 | * address space and the request cannot be directly validated |
@@ -1002,7 +996,7 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc, | |||
1002 | mask, merged_datum, | 996 | mask, merged_datum, |
1003 | field_offset); | 997 | field_offset); |
1004 | 998 | ||
1005 | exit: | 999 | exit: |
1006 | /* Free temporary buffer if we used one */ | 1000 | /* Free temporary buffer if we used one */ |
1007 | 1001 | ||
1008 | if (new_buffer) { | 1002 | if (new_buffer) { |
diff --git a/drivers/acpi/acpica/exmisc.c b/drivers/acpi/acpica/exmisc.c index 00bf29877574..65d93607f368 100644 --- a/drivers/acpi/acpica/exmisc.c +++ b/drivers/acpi/acpica/exmisc.c | |||
@@ -388,7 +388,7 @@ acpi_ex_do_concatenate(union acpi_operand_object *operand0, | |||
388 | 388 | ||
389 | *actual_return_desc = return_desc; | 389 | *actual_return_desc = return_desc; |
390 | 390 | ||
391 | cleanup: | 391 | cleanup: |
392 | if (local_operand1 != operand1) { | 392 | if (local_operand1 != operand1) { |
393 | acpi_ut_remove_reference(local_operand1); | 393 | acpi_ut_remove_reference(local_operand1); |
394 | } | 394 | } |
@@ -718,7 +718,7 @@ acpi_ex_do_logical_op(u16 opcode, | |||
718 | } | 718 | } |
719 | } | 719 | } |
720 | 720 | ||
721 | cleanup: | 721 | cleanup: |
722 | 722 | ||
723 | /* New object was created if implicit conversion performed - delete */ | 723 | /* New object was created if implicit conversion performed - delete */ |
724 | 724 | ||
diff --git a/drivers/acpi/acpica/exoparg1.c b/drivers/acpi/acpica/exoparg1.c index 2cdd41d8ade6..d74cea416ca0 100644 --- a/drivers/acpi/acpica/exoparg1.c +++ b/drivers/acpi/acpica/exoparg1.c | |||
@@ -115,7 +115,7 @@ acpi_status acpi_ex_opcode_0A_0T_1R(struct acpi_walk_state *walk_state) | |||
115 | break; | 115 | break; |
116 | } | 116 | } |
117 | 117 | ||
118 | cleanup: | 118 | cleanup: |
119 | 119 | ||
120 | /* Delete return object on error */ | 120 | /* Delete return object on error */ |
121 | 121 | ||
@@ -234,7 +234,7 @@ acpi_status acpi_ex_opcode_1A_1T_0R(struct acpi_walk_state *walk_state) | |||
234 | goto cleanup; | 234 | goto cleanup; |
235 | } | 235 | } |
236 | 236 | ||
237 | cleanup: | 237 | cleanup: |
238 | 238 | ||
239 | return_ACPI_STATUS(status); | 239 | return_ACPI_STATUS(status); |
240 | } | 240 | } |
@@ -551,7 +551,7 @@ acpi_status acpi_ex_opcode_1A_1T_1R(struct acpi_walk_state *walk_state) | |||
551 | status = acpi_ex_store(return_desc, operand[1], walk_state); | 551 | status = acpi_ex_store(return_desc, operand[1], walk_state); |
552 | } | 552 | } |
553 | 553 | ||
554 | cleanup: | 554 | cleanup: |
555 | 555 | ||
556 | /* Delete return object on error */ | 556 | /* Delete return object on error */ |
557 | 557 | ||
@@ -1054,7 +1054,7 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state) | |||
1054 | goto cleanup; | 1054 | goto cleanup; |
1055 | } | 1055 | } |
1056 | 1056 | ||
1057 | cleanup: | 1057 | cleanup: |
1058 | 1058 | ||
1059 | /* Delete return object on error */ | 1059 | /* Delete return object on error */ |
1060 | 1060 | ||
diff --git a/drivers/acpi/acpica/exoparg2.c b/drivers/acpi/acpica/exoparg2.c index d5088f7030c7..d6fa0fce1fc9 100644 --- a/drivers/acpi/acpica/exoparg2.c +++ b/drivers/acpi/acpica/exoparg2.c | |||
@@ -215,7 +215,7 @@ acpi_status acpi_ex_opcode_2A_2T_1R(struct acpi_walk_state *walk_state) | |||
215 | goto cleanup; | 215 | goto cleanup; |
216 | } | 216 | } |
217 | 217 | ||
218 | cleanup: | 218 | cleanup: |
219 | /* | 219 | /* |
220 | * Since the remainder is not returned indirectly, remove a reference to | 220 | * Since the remainder is not returned indirectly, remove a reference to |
221 | * it. Only the quotient is returned indirectly. | 221 | * it. Only the quotient is returned indirectly. |
@@ -445,7 +445,7 @@ acpi_status acpi_ex_opcode_2A_1T_1R(struct acpi_walk_state *walk_state) | |||
445 | break; | 445 | break; |
446 | } | 446 | } |
447 | 447 | ||
448 | store_result_to_target: | 448 | store_result_to_target: |
449 | 449 | ||
450 | if (ACPI_SUCCESS(status)) { | 450 | if (ACPI_SUCCESS(status)) { |
451 | /* | 451 | /* |
@@ -462,7 +462,7 @@ acpi_status acpi_ex_opcode_2A_1T_1R(struct acpi_walk_state *walk_state) | |||
462 | } | 462 | } |
463 | } | 463 | } |
464 | 464 | ||
465 | cleanup: | 465 | cleanup: |
466 | 466 | ||
467 | /* Delete return object on error */ | 467 | /* Delete return object on error */ |
468 | 468 | ||
@@ -553,7 +553,7 @@ acpi_status acpi_ex_opcode_2A_0T_1R(struct acpi_walk_state *walk_state) | |||
553 | goto cleanup; | 553 | goto cleanup; |
554 | } | 554 | } |
555 | 555 | ||
556 | store_logical_result: | 556 | store_logical_result: |
557 | /* | 557 | /* |
558 | * Set return value to according to logical_result. logical TRUE (all ones) | 558 | * Set return value to according to logical_result. logical TRUE (all ones) |
559 | * Default is FALSE (zero) | 559 | * Default is FALSE (zero) |
@@ -562,7 +562,7 @@ acpi_status acpi_ex_opcode_2A_0T_1R(struct acpi_walk_state *walk_state) | |||
562 | return_desc->integer.value = ACPI_UINT64_MAX; | 562 | return_desc->integer.value = ACPI_UINT64_MAX; |
563 | } | 563 | } |
564 | 564 | ||
565 | cleanup: | 565 | cleanup: |
566 | 566 | ||
567 | /* Delete return object on error */ | 567 | /* Delete return object on error */ |
568 | 568 | ||
diff --git a/drivers/acpi/acpica/exoparg3.c b/drivers/acpi/acpica/exoparg3.c index 37656f12f204..bc042adf8804 100644 --- a/drivers/acpi/acpica/exoparg3.c +++ b/drivers/acpi/acpica/exoparg3.c | |||
@@ -124,7 +124,7 @@ acpi_status acpi_ex_opcode_3A_0T_0R(struct acpi_walk_state *walk_state) | |||
124 | goto cleanup; | 124 | goto cleanup; |
125 | } | 125 | } |
126 | 126 | ||
127 | cleanup: | 127 | cleanup: |
128 | 128 | ||
129 | return_ACPI_STATUS(status); | 129 | return_ACPI_STATUS(status); |
130 | } | 130 | } |
@@ -252,7 +252,7 @@ acpi_status acpi_ex_opcode_3A_1T_1R(struct acpi_walk_state *walk_state) | |||
252 | 252 | ||
253 | status = acpi_ex_store(return_desc, operand[3], walk_state); | 253 | status = acpi_ex_store(return_desc, operand[3], walk_state); |
254 | 254 | ||
255 | cleanup: | 255 | cleanup: |
256 | 256 | ||
257 | /* Delete return object on error */ | 257 | /* Delete return object on error */ |
258 | 258 | ||
diff --git a/drivers/acpi/acpica/exoparg6.c b/drivers/acpi/acpica/exoparg6.c index 879b6cd8319c..4459e32c683d 100644 --- a/drivers/acpi/acpica/exoparg6.c +++ b/drivers/acpi/acpica/exoparg6.c | |||
@@ -314,7 +314,7 @@ acpi_status acpi_ex_opcode_6A_0T_1R(struct acpi_walk_state * walk_state) | |||
314 | goto cleanup; | 314 | goto cleanup; |
315 | } | 315 | } |
316 | 316 | ||
317 | cleanup: | 317 | cleanup: |
318 | 318 | ||
319 | /* Delete return object on error */ | 319 | /* Delete return object on error */ |
320 | 320 | ||
diff --git a/drivers/acpi/acpica/exregion.c b/drivers/acpi/acpica/exregion.c index 303429bb4d5d..9d28867e60dc 100644 --- a/drivers/acpi/acpica/exregion.c +++ b/drivers/acpi/acpica/exregion.c | |||
@@ -400,6 +400,7 @@ acpi_ex_pci_config_space_handler(u32 function, | |||
400 | switch (function) { | 400 | switch (function) { |
401 | case ACPI_READ: | 401 | case ACPI_READ: |
402 | 402 | ||
403 | *value = 0; | ||
403 | status = acpi_os_read_pci_configuration(pci_id, pci_register, | 404 | status = acpi_os_read_pci_configuration(pci_id, pci_register, |
404 | value, bit_width); | 405 | value, bit_width); |
405 | break; | 406 | break; |
diff --git a/drivers/acpi/acpica/exresolv.c b/drivers/acpi/acpica/exresolv.c index ac04278ad28f..1606524312e3 100644 --- a/drivers/acpi/acpica/exresolv.c +++ b/drivers/acpi/acpica/exresolv.c | |||
@@ -521,7 +521,7 @@ acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state, | |||
521 | */ | 521 | */ |
522 | type = obj_desc->common.type; | 522 | type = obj_desc->common.type; |
523 | 523 | ||
524 | exit: | 524 | exit: |
525 | /* Convert internal types to external types */ | 525 | /* Convert internal types to external types */ |
526 | 526 | ||
527 | switch (type) { | 527 | switch (type) { |
diff --git a/drivers/acpi/acpica/exresop.c b/drivers/acpi/acpica/exresop.c index 00e5af7129c1..be3f66973ee8 100644 --- a/drivers/acpi/acpica/exresop.c +++ b/drivers/acpi/acpica/exresop.c | |||
@@ -683,7 +683,7 @@ acpi_ex_resolve_operands(u16 opcode, | |||
683 | return_ACPI_STATUS(status); | 683 | return_ACPI_STATUS(status); |
684 | } | 684 | } |
685 | 685 | ||
686 | next_operand: | 686 | next_operand: |
687 | /* | 687 | /* |
688 | * If more operands needed, decrement stack_ptr to point | 688 | * If more operands needed, decrement stack_ptr to point |
689 | * to next operand on stack | 689 | * to next operand on stack |
diff --git a/drivers/acpi/acpica/hwregs.c b/drivers/acpi/acpica/hwregs.c index 8d2e866be15f..12e6cff54f78 100644 --- a/drivers/acpi/acpica/hwregs.c +++ b/drivers/acpi/acpica/hwregs.c | |||
@@ -560,7 +560,7 @@ acpi_status acpi_hw_register_write(u32 register_id, u32 value) | |||
560 | break; | 560 | break; |
561 | } | 561 | } |
562 | 562 | ||
563 | exit: | 563 | exit: |
564 | return_ACPI_STATUS(status); | 564 | return_ACPI_STATUS(status); |
565 | } | 565 | } |
566 | 566 | ||
diff --git a/drivers/acpi/acpica/hwtimer.c b/drivers/acpi/acpica/hwtimer.c index 2d7d22ebc782..3c498dc1636e 100644 --- a/drivers/acpi/acpica/hwtimer.c +++ b/drivers/acpi/acpica/hwtimer.c | |||
@@ -41,7 +41,8 @@ | |||
41 | * POSSIBILITY OF SUCH DAMAGES. | 41 | * POSSIBILITY OF SUCH DAMAGES. |
42 | */ | 42 | */ |
43 | 43 | ||
44 | #include <linux/export.h> | 44 | #define EXPORT_ACPI_INTERFACES |
45 | |||
45 | #include <acpi/acpi.h> | 46 | #include <acpi/acpi.h> |
46 | #include "accommon.h" | 47 | #include "accommon.h" |
47 | 48 | ||
diff --git a/drivers/acpi/acpica/hwxface.c b/drivers/acpi/acpica/hwxface.c index 5ee7a814cd92..b4b47db2dee2 100644 --- a/drivers/acpi/acpica/hwxface.c +++ b/drivers/acpi/acpica/hwxface.c | |||
@@ -41,7 +41,8 @@ | |||
41 | * POSSIBILITY OF SUCH DAMAGES. | 41 | * POSSIBILITY OF SUCH DAMAGES. |
42 | */ | 42 | */ |
43 | 43 | ||
44 | #include <linux/export.h> | 44 | #define EXPORT_ACPI_INTERFACES |
45 | |||
45 | #include <acpi/acpi.h> | 46 | #include <acpi/acpi.h> |
46 | #include "accommon.h" | 47 | #include "accommon.h" |
47 | #include "acnamesp.h" | 48 | #include "acnamesp.h" |
@@ -83,11 +84,17 @@ acpi_status acpi_reset(void) | |||
83 | * For I/O space, write directly to the OSL. This bypasses the port | 84 | * For I/O space, write directly to the OSL. This bypasses the port |
84 | * validation mechanism, which may block a valid write to the reset | 85 | * validation mechanism, which may block a valid write to the reset |
85 | * register. | 86 | * register. |
86 | * Spec section 4.7.3.6 requires register width to be 8. | 87 | * |
88 | * NOTE: | ||
89 | * The ACPI spec requires the reset register width to be 8, so we | ||
90 | * hardcode it here and ignore the FADT value. This maintains | ||
91 | * compatibility with other ACPI implementations that have allowed | ||
92 | * BIOS code with bad register width values to go unnoticed. | ||
87 | */ | 93 | */ |
88 | status = | 94 | status = |
89 | acpi_os_write_port((acpi_io_address) reset_reg->address, | 95 | acpi_os_write_port((acpi_io_address) reset_reg->address, |
90 | acpi_gbl_FADT.reset_value, 8); | 96 | acpi_gbl_FADT.reset_value, |
97 | ACPI_RESET_REGISTER_WIDTH); | ||
91 | } else { | 98 | } else { |
92 | /* Write the reset value to the reset register */ | 99 | /* Write the reset value to the reset register */ |
93 | 100 | ||
@@ -119,7 +126,8 @@ ACPI_EXPORT_SYMBOL(acpi_reset) | |||
119 | ******************************************************************************/ | 126 | ******************************************************************************/ |
120 | acpi_status acpi_read(u64 *return_value, struct acpi_generic_address *reg) | 127 | acpi_status acpi_read(u64 *return_value, struct acpi_generic_address *reg) |
121 | { | 128 | { |
122 | u32 value; | 129 | u32 value_lo; |
130 | u32 value_hi; | ||
123 | u32 width; | 131 | u32 width; |
124 | u64 address; | 132 | u64 address; |
125 | acpi_status status; | 133 | acpi_status status; |
@@ -137,13 +145,8 @@ acpi_status acpi_read(u64 *return_value, struct acpi_generic_address *reg) | |||
137 | return (status); | 145 | return (status); |
138 | } | 146 | } |
139 | 147 | ||
140 | /* Initialize entire 64-bit return value to zero */ | ||
141 | |||
142 | *return_value = 0; | ||
143 | value = 0; | ||
144 | |||
145 | /* | 148 | /* |
146 | * Two address spaces supported: Memory or IO. PCI_Config is | 149 | * Two address spaces supported: Memory or I/O. PCI_Config is |
147 | * not supported here because the GAS structure is insufficient | 150 | * not supported here because the GAS structure is insufficient |
148 | */ | 151 | */ |
149 | if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { | 152 | if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { |
@@ -155,29 +158,35 @@ acpi_status acpi_read(u64 *return_value, struct acpi_generic_address *reg) | |||
155 | } | 158 | } |
156 | } else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */ | 159 | } else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */ |
157 | 160 | ||
161 | value_lo = 0; | ||
162 | value_hi = 0; | ||
163 | |||
158 | width = reg->bit_width; | 164 | width = reg->bit_width; |
159 | if (width == 64) { | 165 | if (width == 64) { |
160 | width = 32; /* Break into two 32-bit transfers */ | 166 | width = 32; /* Break into two 32-bit transfers */ |
161 | } | 167 | } |
162 | 168 | ||
163 | status = acpi_hw_read_port((acpi_io_address) | 169 | status = acpi_hw_read_port((acpi_io_address) |
164 | address, &value, width); | 170 | address, &value_lo, width); |
165 | if (ACPI_FAILURE(status)) { | 171 | if (ACPI_FAILURE(status)) { |
166 | return (status); | 172 | return (status); |
167 | } | 173 | } |
168 | *return_value = value; | ||
169 | 174 | ||
170 | if (reg->bit_width == 64) { | 175 | if (reg->bit_width == 64) { |
171 | 176 | ||
172 | /* Read the top 32 bits */ | 177 | /* Read the top 32 bits */ |
173 | 178 | ||
174 | status = acpi_hw_read_port((acpi_io_address) | 179 | status = acpi_hw_read_port((acpi_io_address) |
175 | (address + 4), &value, 32); | 180 | (address + 4), &value_hi, |
181 | 32); | ||
176 | if (ACPI_FAILURE(status)) { | 182 | if (ACPI_FAILURE(status)) { |
177 | return (status); | 183 | return (status); |
178 | } | 184 | } |
179 | *return_value |= ((u64)value << 32); | ||
180 | } | 185 | } |
186 | |||
187 | /* Set the return value only if status is AE_OK */ | ||
188 | |||
189 | *return_value = (value_lo | ((u64)value_hi << 32)); | ||
181 | } | 190 | } |
182 | 191 | ||
183 | ACPI_DEBUG_PRINT((ACPI_DB_IO, | 192 | ACPI_DEBUG_PRINT((ACPI_DB_IO, |
@@ -186,7 +195,7 @@ acpi_status acpi_read(u64 *return_value, struct acpi_generic_address *reg) | |||
186 | ACPI_FORMAT_UINT64(address), | 195 | ACPI_FORMAT_UINT64(address), |
187 | acpi_ut_get_region_name(reg->space_id))); | 196 | acpi_ut_get_region_name(reg->space_id))); |
188 | 197 | ||
189 | return (status); | 198 | return (AE_OK); |
190 | } | 199 | } |
191 | 200 | ||
192 | ACPI_EXPORT_SYMBOL(acpi_read) | 201 | ACPI_EXPORT_SYMBOL(acpi_read) |
@@ -561,10 +570,10 @@ acpi_get_sleep_type_data(u8 sleep_state, u8 *sleep_type_a, u8 *sleep_type_b) | |||
561 | break; | 570 | break; |
562 | } | 571 | } |
563 | 572 | ||
564 | cleanup1: | 573 | cleanup1: |
565 | acpi_ut_remove_reference(info->return_object); | 574 | acpi_ut_remove_reference(info->return_object); |
566 | 575 | ||
567 | cleanup: | 576 | cleanup: |
568 | if (ACPI_FAILURE(status)) { | 577 | if (ACPI_FAILURE(status)) { |
569 | ACPI_EXCEPTION((AE_INFO, status, | 578 | ACPI_EXCEPTION((AE_INFO, status, |
570 | "While evaluating Sleep State [%s]", | 579 | "While evaluating Sleep State [%s]", |
diff --git a/drivers/acpi/acpica/hwxfsleep.c b/drivers/acpi/acpica/hwxfsleep.c index f2e669db8b65..15dddc10fc9b 100644 --- a/drivers/acpi/acpica/hwxfsleep.c +++ b/drivers/acpi/acpica/hwxfsleep.c | |||
@@ -41,7 +41,8 @@ | |||
41 | * POSSIBILITY OF SUCH DAMAGES. | 41 | * POSSIBILITY OF SUCH DAMAGES. |
42 | */ | 42 | */ |
43 | 43 | ||
44 | #include <linux/export.h> | 44 | #define EXPORT_ACPI_INTERFACES |
45 | |||
45 | #include <acpi/acpi.h> | 46 | #include <acpi/acpi.h> |
46 | #include "accommon.h" | 47 | #include "accommon.h" |
47 | 48 | ||
@@ -166,7 +167,7 @@ ACPI_EXPORT_SYMBOL(acpi_set_firmware_waking_vector64) | |||
166 | * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED | 167 | * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED |
167 | * | 168 | * |
168 | ******************************************************************************/ | 169 | ******************************************************************************/ |
169 | acpi_status asmlinkage acpi_enter_sleep_state_s4bios(void) | 170 | acpi_status acpi_enter_sleep_state_s4bios(void) |
170 | { | 171 | { |
171 | u32 in_value; | 172 | u32 in_value; |
172 | acpi_status status; | 173 | acpi_status status; |
@@ -360,7 +361,7 @@ ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_prep) | |||
360 | * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED | 361 | * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED |
361 | * | 362 | * |
362 | ******************************************************************************/ | 363 | ******************************************************************************/ |
363 | acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state) | 364 | acpi_status acpi_enter_sleep_state(u8 sleep_state) |
364 | { | 365 | { |
365 | acpi_status status; | 366 | acpi_status status; |
366 | 367 | ||
diff --git a/drivers/acpi/acpica/nsaccess.c b/drivers/acpi/acpica/nsaccess.c index c5316e5bd4ab..14f65f6345b9 100644 --- a/drivers/acpi/acpica/nsaccess.c +++ b/drivers/acpi/acpica/nsaccess.c | |||
@@ -240,7 +240,7 @@ acpi_status acpi_ns_root_initialize(void) | |||
240 | } | 240 | } |
241 | } | 241 | } |
242 | 242 | ||
243 | unlock_and_exit: | 243 | unlock_and_exit: |
244 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | 244 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); |
245 | 245 | ||
246 | /* Save a handle to "_GPE", it is always present */ | 246 | /* Save a handle to "_GPE", it is always present */ |
@@ -424,8 +424,9 @@ acpi_ns_lookup(union acpi_generic_state *scope_info, | |||
424 | /* Current scope has no parent scope */ | 424 | /* Current scope has no parent scope */ |
425 | 425 | ||
426 | ACPI_ERROR((AE_INFO, | 426 | ACPI_ERROR((AE_INFO, |
427 | "ACPI path has too many parent prefixes (^) " | 427 | "%s: Path has too many parent prefixes (^) " |
428 | "- reached beyond root node")); | 428 | "- reached beyond root node", |
429 | pathname)); | ||
429 | return_ACPI_STATUS(AE_NOT_FOUND); | 430 | return_ACPI_STATUS(AE_NOT_FOUND); |
430 | } | 431 | } |
431 | } | 432 | } |
diff --git a/drivers/acpi/acpica/nsdump.c b/drivers/acpi/acpica/nsdump.c index 7418c77fde8c..48b9c6f12643 100644 --- a/drivers/acpi/acpica/nsdump.c +++ b/drivers/acpi/acpica/nsdump.c | |||
@@ -59,6 +59,17 @@ acpi_ns_dump_one_device(acpi_handle obj_handle, | |||
59 | #endif | 59 | #endif |
60 | 60 | ||
61 | #if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER) | 61 | #if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER) |
62 | |||
63 | #ifdef ACPI_FUTURE_USAGE | ||
64 | static acpi_status | ||
65 | acpi_ns_dump_one_object_path(acpi_handle obj_handle, | ||
66 | u32 level, void *context, void **return_value); | ||
67 | |||
68 | static acpi_status | ||
69 | acpi_ns_get_max_depth(acpi_handle obj_handle, | ||
70 | u32 level, void *context, void **return_value); | ||
71 | #endif /* ACPI_FUTURE_USAGE */ | ||
72 | |||
62 | /******************************************************************************* | 73 | /******************************************************************************* |
63 | * | 74 | * |
64 | * FUNCTION: acpi_ns_print_pathname | 75 | * FUNCTION: acpi_ns_print_pathname |
@@ -609,7 +620,7 @@ acpi_ns_dump_one_object(acpi_handle obj_handle, | |||
609 | obj_type = ACPI_TYPE_INVALID; /* Terminate loop after next pass */ | 620 | obj_type = ACPI_TYPE_INVALID; /* Terminate loop after next pass */ |
610 | } | 621 | } |
611 | 622 | ||
612 | cleanup: | 623 | cleanup: |
613 | acpi_os_printf("\n"); | 624 | acpi_os_printf("\n"); |
614 | return (AE_OK); | 625 | return (AE_OK); |
615 | } | 626 | } |
@@ -671,6 +682,136 @@ acpi_ns_dump_objects(acpi_object_type type, | |||
671 | } | 682 | } |
672 | #endif /* ACPI_FUTURE_USAGE */ | 683 | #endif /* ACPI_FUTURE_USAGE */ |
673 | 684 | ||
685 | #ifdef ACPI_FUTURE_USAGE | ||
686 | /******************************************************************************* | ||
687 | * | ||
688 | * FUNCTION: acpi_ns_dump_one_object_path, acpi_ns_get_max_depth | ||
689 | * | ||
690 | * PARAMETERS: obj_handle - Node to be dumped | ||
691 | * level - Nesting level of the handle | ||
692 | * context - Passed into walk_namespace | ||
693 | * return_value - Not used | ||
694 | * | ||
695 | * RETURN: Status | ||
696 | * | ||
697 | * DESCRIPTION: Dump the full pathname to a namespace object. acp_ns_get_max_depth | ||
698 | * computes the maximum nesting depth in the namespace tree, in | ||
699 | * order to simplify formatting in acpi_ns_dump_one_object_path. | ||
700 | * These procedures are user_functions called by acpi_ns_walk_namespace. | ||
701 | * | ||
702 | ******************************************************************************/ | ||
703 | |||
704 | static acpi_status | ||
705 | acpi_ns_dump_one_object_path(acpi_handle obj_handle, | ||
706 | u32 level, void *context, void **return_value) | ||
707 | { | ||
708 | u32 max_level = *((u32 *)context); | ||
709 | char *pathname; | ||
710 | struct acpi_namespace_node *node; | ||
711 | int path_indent; | ||
712 | |||
713 | if (!obj_handle) { | ||
714 | return (AE_OK); | ||
715 | } | ||
716 | |||
717 | node = acpi_ns_validate_handle(obj_handle); | ||
718 | if (!node) { | ||
719 | |||
720 | /* Ignore bad node during namespace walk */ | ||
721 | |||
722 | return (AE_OK); | ||
723 | } | ||
724 | |||
725 | pathname = acpi_ns_get_external_pathname(node); | ||
726 | |||
727 | path_indent = 1; | ||
728 | if (level <= max_level) { | ||
729 | path_indent = max_level - level + 1; | ||
730 | } | ||
731 | |||
732 | acpi_os_printf("%2d%*s%-12s%*s", | ||
733 | level, level, " ", acpi_ut_get_type_name(node->type), | ||
734 | path_indent, " "); | ||
735 | |||
736 | acpi_os_printf("%s\n", &pathname[1]); | ||
737 | ACPI_FREE(pathname); | ||
738 | return (AE_OK); | ||
739 | } | ||
740 | |||
741 | static acpi_status | ||
742 | acpi_ns_get_max_depth(acpi_handle obj_handle, | ||
743 | u32 level, void *context, void **return_value) | ||
744 | { | ||
745 | u32 *max_level = (u32 *)context; | ||
746 | |||
747 | if (level > *max_level) { | ||
748 | *max_level = level; | ||
749 | } | ||
750 | return (AE_OK); | ||
751 | } | ||
752 | |||
753 | /******************************************************************************* | ||
754 | * | ||
755 | * FUNCTION: acpi_ns_dump_object_paths | ||
756 | * | ||
757 | * PARAMETERS: type - Object type to be dumped | ||
758 | * display_type - 0 or ACPI_DISPLAY_SUMMARY | ||
759 | * max_depth - Maximum depth of dump. Use ACPI_UINT32_MAX | ||
760 | * for an effectively unlimited depth. | ||
761 | * owner_id - Dump only objects owned by this ID. Use | ||
762 | * ACPI_UINT32_MAX to match all owners. | ||
763 | * start_handle - Where in namespace to start/end search | ||
764 | * | ||
765 | * RETURN: None | ||
766 | * | ||
767 | * DESCRIPTION: Dump full object pathnames within the loaded namespace. Uses | ||
768 | * acpi_ns_walk_namespace in conjunction with acpi_ns_dump_one_object_path. | ||
769 | * | ||
770 | ******************************************************************************/ | ||
771 | |||
772 | void | ||
773 | acpi_ns_dump_object_paths(acpi_object_type type, | ||
774 | u8 display_type, | ||
775 | u32 max_depth, | ||
776 | acpi_owner_id owner_id, acpi_handle start_handle) | ||
777 | { | ||
778 | acpi_status status; | ||
779 | u32 max_level = 0; | ||
780 | |||
781 | ACPI_FUNCTION_ENTRY(); | ||
782 | |||
783 | /* | ||
784 | * Just lock the entire namespace for the duration of the dump. | ||
785 | * We don't want any changes to the namespace during this time, | ||
786 | * especially the temporary nodes since we are going to display | ||
787 | * them also. | ||
788 | */ | ||
789 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | ||
790 | if (ACPI_FAILURE(status)) { | ||
791 | acpi_os_printf("Could not acquire namespace mutex\n"); | ||
792 | return; | ||
793 | } | ||
794 | |||
795 | /* Get the max depth of the namespace tree, for formatting later */ | ||
796 | |||
797 | (void)acpi_ns_walk_namespace(type, start_handle, max_depth, | ||
798 | ACPI_NS_WALK_NO_UNLOCK | | ||
799 | ACPI_NS_WALK_TEMP_NODES, | ||
800 | acpi_ns_get_max_depth, NULL, | ||
801 | (void *)&max_level, NULL); | ||
802 | |||
803 | /* Now dump the entire namespace */ | ||
804 | |||
805 | (void)acpi_ns_walk_namespace(type, start_handle, max_depth, | ||
806 | ACPI_NS_WALK_NO_UNLOCK | | ||
807 | ACPI_NS_WALK_TEMP_NODES, | ||
808 | acpi_ns_dump_one_object_path, NULL, | ||
809 | (void *)&max_level, NULL); | ||
810 | |||
811 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | ||
812 | } | ||
813 | #endif /* ACPI_FUTURE_USAGE */ | ||
814 | |||
674 | /******************************************************************************* | 815 | /******************************************************************************* |
675 | * | 816 | * |
676 | * FUNCTION: acpi_ns_dump_entry | 817 | * FUNCTION: acpi_ns_dump_entry |
diff --git a/drivers/acpi/acpica/nsdumpdv.c b/drivers/acpi/acpica/nsdumpdv.c index 409ae80824d1..283762511b73 100644 --- a/drivers/acpi/acpica/nsdumpdv.c +++ b/drivers/acpi/acpica/nsdumpdv.c | |||
@@ -69,6 +69,7 @@ static acpi_status | |||
69 | acpi_ns_dump_one_device(acpi_handle obj_handle, | 69 | acpi_ns_dump_one_device(acpi_handle obj_handle, |
70 | u32 level, void *context, void **return_value) | 70 | u32 level, void *context, void **return_value) |
71 | { | 71 | { |
72 | struct acpi_buffer buffer; | ||
72 | struct acpi_device_info *info; | 73 | struct acpi_device_info *info; |
73 | acpi_status status; | 74 | acpi_status status; |
74 | u32 i; | 75 | u32 i; |
@@ -78,15 +79,17 @@ acpi_ns_dump_one_device(acpi_handle obj_handle, | |||
78 | status = | 79 | status = |
79 | acpi_ns_dump_one_object(obj_handle, level, context, return_value); | 80 | acpi_ns_dump_one_object(obj_handle, level, context, return_value); |
80 | 81 | ||
81 | status = acpi_get_object_info(obj_handle, &info); | 82 | buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER; |
83 | status = acpi_get_object_info(obj_handle, &buffer); | ||
82 | if (ACPI_SUCCESS(status)) { | 84 | if (ACPI_SUCCESS(status)) { |
85 | info = buffer.pointer; | ||
83 | for (i = 0; i < level; i++) { | 86 | for (i = 0; i < level; i++) { |
84 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_TABLES, " ")); | 87 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_TABLES, " ")); |
85 | } | 88 | } |
86 | 89 | ||
87 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_TABLES, | 90 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_TABLES, |
88 | " HID: %s, ADR: %8.8X%8.8X, Status: %X\n", | 91 | " HID: %s, ADR: %8.8X%8.8X, Status: %X\n", |
89 | info->hardware_id.string, | 92 | info->hardware_id.value, |
90 | ACPI_FORMAT_UINT64(info->address), | 93 | ACPI_FORMAT_UINT64(info->address), |
91 | info->current_status)); | 94 | info->current_status)); |
92 | ACPI_FREE(info); | 95 | ACPI_FREE(info); |
diff --git a/drivers/acpi/acpica/nseval.c b/drivers/acpi/acpica/nseval.c index 18108bc2e51c..963ceef063f8 100644 --- a/drivers/acpi/acpica/nseval.c +++ b/drivers/acpi/acpica/nseval.c | |||
@@ -314,7 +314,7 @@ acpi_status acpi_ns_evaluate(struct acpi_evaluate_info *info) | |||
314 | "*** Completed evaluation of object %s ***\n", | 314 | "*** Completed evaluation of object %s ***\n", |
315 | info->relative_pathname)); | 315 | info->relative_pathname)); |
316 | 316 | ||
317 | cleanup: | 317 | cleanup: |
318 | /* | 318 | /* |
319 | * Namespace was unlocked by the handling acpi_ns* function, so we | 319 | * Namespace was unlocked by the handling acpi_ns* function, so we |
320 | * just free the pathname and return | 320 | * just free the pathname and return |
@@ -486,7 +486,7 @@ acpi_ns_exec_module_code(union acpi_operand_object *method_obj, | |||
486 | parent_node->type = (u8)type; | 486 | parent_node->type = (u8)type; |
487 | } | 487 | } |
488 | 488 | ||
489 | exit: | 489 | exit: |
490 | if (parent_obj) { | 490 | if (parent_obj) { |
491 | acpi_ut_remove_reference(parent_obj); | 491 | acpi_ut_remove_reference(parent_obj); |
492 | } | 492 | } |
diff --git a/drivers/acpi/acpica/nsinit.c b/drivers/acpi/acpica/nsinit.c index dd2ceae3f717..3a0423af968c 100644 --- a/drivers/acpi/acpica/nsinit.c +++ b/drivers/acpi/acpica/nsinit.c | |||
@@ -213,7 +213,7 @@ acpi_status acpi_ns_initialize_devices(void) | |||
213 | 213 | ||
214 | return_ACPI_STATUS(status); | 214 | return_ACPI_STATUS(status); |
215 | 215 | ||
216 | error_exit: | 216 | error_exit: |
217 | ACPI_EXCEPTION((AE_INFO, status, "During device initialization")); | 217 | ACPI_EXCEPTION((AE_INFO, status, "During device initialization")); |
218 | return_ACPI_STATUS(status); | 218 | return_ACPI_STATUS(status); |
219 | } | 219 | } |
diff --git a/drivers/acpi/acpica/nsload.c b/drivers/acpi/acpica/nsload.c index 0a7badc3179f..89ec645e7730 100644 --- a/drivers/acpi/acpica/nsload.c +++ b/drivers/acpi/acpica/nsload.c | |||
@@ -114,7 +114,7 @@ acpi_ns_load_table(u32 table_index, struct acpi_namespace_node *node) | |||
114 | (void)acpi_tb_release_owner_id(table_index); | 114 | (void)acpi_tb_release_owner_id(table_index); |
115 | } | 115 | } |
116 | 116 | ||
117 | unlock: | 117 | unlock: |
118 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | 118 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); |
119 | 119 | ||
120 | if (ACPI_FAILURE(status)) { | 120 | if (ACPI_FAILURE(status)) { |
diff --git a/drivers/acpi/acpica/nsparse.c b/drivers/acpi/acpica/nsparse.c index 35dde8151c0d..177857340271 100644 --- a/drivers/acpi/acpica/nsparse.c +++ b/drivers/acpi/acpica/nsparse.c | |||
@@ -140,7 +140,7 @@ acpi_ns_one_complete_parse(u32 pass_number, | |||
140 | pass_number)); | 140 | pass_number)); |
141 | status = acpi_ps_parse_aml(walk_state); | 141 | status = acpi_ps_parse_aml(walk_state); |
142 | 142 | ||
143 | cleanup: | 143 | cleanup: |
144 | acpi_ps_delete_parse_tree(parse_root); | 144 | acpi_ps_delete_parse_tree(parse_root); |
145 | return_ACPI_STATUS(status); | 145 | return_ACPI_STATUS(status); |
146 | } | 146 | } |
diff --git a/drivers/acpi/acpica/nspredef.c b/drivers/acpi/acpica/nspredef.c index 098e7666cbc9..d2855d9857c4 100644 --- a/drivers/acpi/acpica/nspredef.c +++ b/drivers/acpi/acpica/nspredef.c | |||
@@ -271,7 +271,7 @@ acpi_ns_check_object_type(struct acpi_evaluate_info *info, | |||
271 | return (AE_OK); /* Successful repair */ | 271 | return (AE_OK); /* Successful repair */ |
272 | } | 272 | } |
273 | 273 | ||
274 | type_error_exit: | 274 | type_error_exit: |
275 | 275 | ||
276 | /* Create a string with all expected types for this predefined object */ | 276 | /* Create a string with all expected types for this predefined object */ |
277 | 277 | ||
diff --git a/drivers/acpi/acpica/nsprepkg.c b/drivers/acpi/acpica/nsprepkg.c index 6d55cef7916c..3d5391f9bcb5 100644 --- a/drivers/acpi/acpica/nsprepkg.c +++ b/drivers/acpi/acpica/nsprepkg.c | |||
@@ -330,7 +330,7 @@ acpi_ns_check_package(struct acpi_evaluate_info *info, | |||
330 | 330 | ||
331 | return (status); | 331 | return (status); |
332 | 332 | ||
333 | package_too_small: | 333 | package_too_small: |
334 | 334 | ||
335 | /* Error exit for the case with an incorrect package count */ | 335 | /* Error exit for the case with an incorrect package count */ |
336 | 336 | ||
@@ -555,7 +555,7 @@ acpi_ns_check_package_list(struct acpi_evaluate_info *info, | |||
555 | 555 | ||
556 | return (AE_OK); | 556 | return (AE_OK); |
557 | 557 | ||
558 | package_too_small: | 558 | package_too_small: |
559 | 559 | ||
560 | /* The sub-package count was smaller than required */ | 560 | /* The sub-package count was smaller than required */ |
561 | 561 | ||
diff --git a/drivers/acpi/acpica/nsrepair.c b/drivers/acpi/acpica/nsrepair.c index f8e71ea60319..a05afff50eb9 100644 --- a/drivers/acpi/acpica/nsrepair.c +++ b/drivers/acpi/acpica/nsrepair.c | |||
@@ -263,7 +263,7 @@ acpi_ns_simple_repair(struct acpi_evaluate_info *info, | |||
263 | 263 | ||
264 | return (AE_AML_OPERAND_TYPE); | 264 | return (AE_AML_OPERAND_TYPE); |
265 | 265 | ||
266 | object_repaired: | 266 | object_repaired: |
267 | 267 | ||
268 | /* Object was successfully repaired */ | 268 | /* Object was successfully repaired */ |
269 | 269 | ||
diff --git a/drivers/acpi/acpica/nsrepair2.c b/drivers/acpi/acpica/nsrepair2.c index c84603ee83ae..6a25d320b169 100644 --- a/drivers/acpi/acpica/nsrepair2.c +++ b/drivers/acpi/acpica/nsrepair2.c | |||
@@ -478,7 +478,7 @@ acpi_ns_repair_CST(struct acpi_evaluate_info *info, | |||
478 | removing = TRUE; | 478 | removing = TRUE; |
479 | } | 479 | } |
480 | 480 | ||
481 | remove_element: | 481 | remove_element: |
482 | if (removing) { | 482 | if (removing) { |
483 | acpi_ns_remove_element(return_object, i + 1); | 483 | acpi_ns_remove_element(return_object, i + 1); |
484 | outer_element_count--; | 484 | outer_element_count--; |
diff --git a/drivers/acpi/acpica/nssearch.c b/drivers/acpi/acpica/nssearch.c index 5d43efc53a61..47420faef073 100644 --- a/drivers/acpi/acpica/nssearch.c +++ b/drivers/acpi/acpica/nssearch.c | |||
@@ -381,7 +381,8 @@ acpi_ns_search_and_enter(u32 target_name, | |||
381 | 381 | ||
382 | /* Node is an object defined by an External() statement */ | 382 | /* Node is an object defined by an External() statement */ |
383 | 383 | ||
384 | if (flags & ACPI_NS_EXTERNAL) { | 384 | if (flags & ACPI_NS_EXTERNAL || |
385 | (walk_state && walk_state->opcode == AML_SCOPE_OP)) { | ||
385 | new_node->flags |= ANOBJ_IS_EXTERNAL; | 386 | new_node->flags |= ANOBJ_IS_EXTERNAL; |
386 | } | 387 | } |
387 | #endif | 388 | #endif |
diff --git a/drivers/acpi/acpica/nsutils.c b/drivers/acpi/acpica/nsutils.c index 08c0b5beec88..cc2fea94c5f0 100644 --- a/drivers/acpi/acpica/nsutils.c +++ b/drivers/acpi/acpica/nsutils.c | |||
@@ -722,7 +722,7 @@ acpi_ns_get_node(struct acpi_namespace_node *prefix_node, | |||
722 | 722 | ||
723 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | 723 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); |
724 | 724 | ||
725 | cleanup: | 725 | cleanup: |
726 | ACPI_FREE(internal_path); | 726 | ACPI_FREE(internal_path); |
727 | return_ACPI_STATUS(status); | 727 | return_ACPI_STATUS(status); |
728 | } | 728 | } |
diff --git a/drivers/acpi/acpica/nsxfeval.c b/drivers/acpi/acpica/nsxfeval.c index b38b4b07f86e..e973e311f856 100644 --- a/drivers/acpi/acpica/nsxfeval.c +++ b/drivers/acpi/acpica/nsxfeval.c | |||
@@ -42,7 +42,8 @@ | |||
42 | * POSSIBILITY OF SUCH DAMAGES. | 42 | * POSSIBILITY OF SUCH DAMAGES. |
43 | */ | 43 | */ |
44 | 44 | ||
45 | #include <linux/export.h> | 45 | #define EXPORT_ACPI_INTERFACES |
46 | |||
46 | #include <acpi/acpi.h> | 47 | #include <acpi/acpi.h> |
47 | #include "accommon.h" | 48 | #include "accommon.h" |
48 | #include "acnamesp.h" | 49 | #include "acnamesp.h" |
@@ -138,7 +139,7 @@ acpi_evaluate_object_typed(acpi_handle handle, | |||
138 | 139 | ||
139 | /* Caller used ACPI_ALLOCATE_BUFFER, free the return buffer */ | 140 | /* Caller used ACPI_ALLOCATE_BUFFER, free the return buffer */ |
140 | 141 | ||
141 | ACPI_FREE(return_buffer->pointer); | 142 | ACPI_FREE_BUFFER(*return_buffer); |
142 | return_buffer->pointer = NULL; | 143 | return_buffer->pointer = NULL; |
143 | } | 144 | } |
144 | 145 | ||
@@ -441,7 +442,7 @@ acpi_evaluate_object(acpi_handle handle, | |||
441 | acpi_ex_exit_interpreter(); | 442 | acpi_ex_exit_interpreter(); |
442 | } | 443 | } |
443 | 444 | ||
444 | cleanup: | 445 | cleanup: |
445 | 446 | ||
446 | /* Free the input parameter list (if we created one) */ | 447 | /* Free the input parameter list (if we created one) */ |
447 | 448 | ||
@@ -605,14 +606,22 @@ acpi_walk_namespace(acpi_object_type type, | |||
605 | goto unlock_and_exit; | 606 | goto unlock_and_exit; |
606 | } | 607 | } |
607 | 608 | ||
609 | /* Now we can validate the starting node */ | ||
610 | |||
611 | if (!acpi_ns_validate_handle(start_object)) { | ||
612 | status = AE_BAD_PARAMETER; | ||
613 | goto unlock_and_exit2; | ||
614 | } | ||
615 | |||
608 | status = acpi_ns_walk_namespace(type, start_object, max_depth, | 616 | status = acpi_ns_walk_namespace(type, start_object, max_depth, |
609 | ACPI_NS_WALK_UNLOCK, | 617 | ACPI_NS_WALK_UNLOCK, |
610 | descending_callback, ascending_callback, | 618 | descending_callback, ascending_callback, |
611 | context, return_value); | 619 | context, return_value); |
612 | 620 | ||
621 | unlock_and_exit2: | ||
613 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | 622 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); |
614 | 623 | ||
615 | unlock_and_exit: | 624 | unlock_and_exit: |
616 | (void)acpi_ut_release_read_lock(&acpi_gbl_namespace_rw_lock); | 625 | (void)acpi_ut_release_read_lock(&acpi_gbl_namespace_rw_lock); |
617 | return_ACPI_STATUS(status); | 626 | return_ACPI_STATUS(status); |
618 | } | 627 | } |
@@ -856,7 +865,7 @@ acpi_attach_data(acpi_handle obj_handle, | |||
856 | 865 | ||
857 | status = acpi_ns_attach_data(node, handler, data); | 866 | status = acpi_ns_attach_data(node, handler, data); |
858 | 867 | ||
859 | unlock_and_exit: | 868 | unlock_and_exit: |
860 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | 869 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); |
861 | return (status); | 870 | return (status); |
862 | } | 871 | } |
@@ -902,7 +911,7 @@ acpi_detach_data(acpi_handle obj_handle, acpi_object_handler handler) | |||
902 | 911 | ||
903 | status = acpi_ns_detach_data(node, handler); | 912 | status = acpi_ns_detach_data(node, handler); |
904 | 913 | ||
905 | unlock_and_exit: | 914 | unlock_and_exit: |
906 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | 915 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); |
907 | return (status); | 916 | return (status); |
908 | } | 917 | } |
@@ -949,7 +958,7 @@ acpi_get_data(acpi_handle obj_handle, acpi_object_handler handler, void **data) | |||
949 | 958 | ||
950 | status = acpi_ns_get_attached_data(node, handler, data); | 959 | status = acpi_ns_get_attached_data(node, handler, data); |
951 | 960 | ||
952 | unlock_and_exit: | 961 | unlock_and_exit: |
953 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | 962 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); |
954 | return (status); | 963 | return (status); |
955 | } | 964 | } |
diff --git a/drivers/acpi/acpica/nsxfname.c b/drivers/acpi/acpica/nsxfname.c index 83c164434580..3a4bd3ff49a3 100644 --- a/drivers/acpi/acpica/nsxfname.c +++ b/drivers/acpi/acpica/nsxfname.c | |||
@@ -42,7 +42,8 @@ | |||
42 | * POSSIBILITY OF SUCH DAMAGES. | 42 | * POSSIBILITY OF SUCH DAMAGES. |
43 | */ | 43 | */ |
44 | 44 | ||
45 | #include <linux/export.h> | 45 | #define EXPORT_ACPI_INTERFACES |
46 | |||
46 | #include <acpi/acpi.h> | 47 | #include <acpi/acpi.h> |
47 | #include "accommon.h" | 48 | #include "accommon.h" |
48 | #include "acnamesp.h" | 49 | #include "acnamesp.h" |
@@ -208,7 +209,7 @@ acpi_get_name(acpi_handle handle, u32 name_type, struct acpi_buffer * buffer) | |||
208 | ((char *)buffer->pointer)[ACPI_NAME_SIZE] = 0; | 209 | ((char *)buffer->pointer)[ACPI_NAME_SIZE] = 0; |
209 | status = AE_OK; | 210 | status = AE_OK; |
210 | 211 | ||
211 | unlock_and_exit: | 212 | unlock_and_exit: |
212 | 213 | ||
213 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | 214 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); |
214 | return (status); | 215 | return (status); |
@@ -496,7 +497,7 @@ acpi_get_object_info(acpi_handle handle, | |||
496 | *return_buffer = info; | 497 | *return_buffer = info; |
497 | status = AE_OK; | 498 | status = AE_OK; |
498 | 499 | ||
499 | cleanup: | 500 | cleanup: |
500 | if (hid) { | 501 | if (hid) { |
501 | ACPI_FREE(hid); | 502 | ACPI_FREE(hid); |
502 | } | 503 | } |
diff --git a/drivers/acpi/acpica/nsxfobj.c b/drivers/acpi/acpica/nsxfobj.c index c0853ef294e4..0e6d79e462d4 100644 --- a/drivers/acpi/acpica/nsxfobj.c +++ b/drivers/acpi/acpica/nsxfobj.c | |||
@@ -42,7 +42,8 @@ | |||
42 | * POSSIBILITY OF SUCH DAMAGES. | 42 | * POSSIBILITY OF SUCH DAMAGES. |
43 | */ | 43 | */ |
44 | 44 | ||
45 | #include <linux/export.h> | 45 | #define EXPORT_ACPI_INTERFACES |
46 | |||
46 | #include <acpi/acpi.h> | 47 | #include <acpi/acpi.h> |
47 | #include "accommon.h" | 48 | #include "accommon.h" |
48 | #include "acnamesp.h" | 49 | #include "acnamesp.h" |
@@ -200,7 +201,7 @@ acpi_status acpi_get_parent(acpi_handle handle, acpi_handle * ret_handle) | |||
200 | status = AE_NULL_ENTRY; | 201 | status = AE_NULL_ENTRY; |
201 | } | 202 | } |
202 | 203 | ||
203 | unlock_and_exit: | 204 | unlock_and_exit: |
204 | 205 | ||
205 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | 206 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); |
206 | return (status); | 207 | return (status); |
@@ -280,7 +281,7 @@ acpi_get_next_object(acpi_object_type type, | |||
280 | *ret_handle = ACPI_CAST_PTR(acpi_handle, node); | 281 | *ret_handle = ACPI_CAST_PTR(acpi_handle, node); |
281 | } | 282 | } |
282 | 283 | ||
283 | unlock_and_exit: | 284 | unlock_and_exit: |
284 | 285 | ||
285 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | 286 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); |
286 | return (status); | 287 | return (status); |
diff --git a/drivers/acpi/acpica/psparse.c b/drivers/acpi/acpica/psparse.c index 86198a9139b5..79d9a28dedef 100644 --- a/drivers/acpi/acpica/psparse.c +++ b/drivers/acpi/acpica/psparse.c | |||
@@ -297,7 +297,7 @@ acpi_ps_complete_this_op(struct acpi_walk_state * walk_state, | |||
297 | } | 297 | } |
298 | } | 298 | } |
299 | 299 | ||
300 | cleanup: | 300 | cleanup: |
301 | 301 | ||
302 | /* Now we can actually delete the subtree rooted at Op */ | 302 | /* Now we can actually delete the subtree rooted at Op */ |
303 | 303 | ||
diff --git a/drivers/acpi/acpica/psxface.c b/drivers/acpi/acpica/psxface.c index 11b99ab20bb3..fcb7a840e996 100644 --- a/drivers/acpi/acpica/psxface.c +++ b/drivers/acpi/acpica/psxface.c | |||
@@ -142,7 +142,7 @@ static void acpi_ps_start_trace(struct acpi_evaluate_info *info) | |||
142 | acpi_dbg_layer = acpi_gbl_trace_dbg_layer; | 142 | acpi_dbg_layer = acpi_gbl_trace_dbg_layer; |
143 | } | 143 | } |
144 | 144 | ||
145 | exit: | 145 | exit: |
146 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | 146 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); |
147 | } | 147 | } |
148 | 148 | ||
@@ -185,7 +185,7 @@ static void acpi_ps_stop_trace(struct acpi_evaluate_info *info) | |||
185 | acpi_dbg_level = acpi_gbl_original_dbg_level; | 185 | acpi_dbg_level = acpi_gbl_original_dbg_level; |
186 | acpi_dbg_layer = acpi_gbl_original_dbg_layer; | 186 | acpi_dbg_layer = acpi_gbl_original_dbg_layer; |
187 | 187 | ||
188 | exit: | 188 | exit: |
189 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | 189 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); |
190 | } | 190 | } |
191 | 191 | ||
@@ -323,7 +323,7 @@ acpi_status acpi_ps_execute_method(struct acpi_evaluate_info *info) | |||
323 | 323 | ||
324 | /* walk_state was deleted by parse_aml */ | 324 | /* walk_state was deleted by parse_aml */ |
325 | 325 | ||
326 | cleanup: | 326 | cleanup: |
327 | acpi_ps_delete_parse_tree(op); | 327 | acpi_ps_delete_parse_tree(op); |
328 | 328 | ||
329 | /* End optional tracing */ | 329 | /* End optional tracing */ |
diff --git a/drivers/acpi/acpica/rsmisc.c b/drivers/acpi/acpica/rsmisc.c index 80d12994e0d0..c99cec9cefde 100644 --- a/drivers/acpi/acpica/rsmisc.c +++ b/drivers/acpi/acpica/rsmisc.c | |||
@@ -440,7 +440,7 @@ acpi_rs_convert_aml_to_resource(struct acpi_resource *resource, | |||
440 | info++; | 440 | info++; |
441 | } | 441 | } |
442 | 442 | ||
443 | exit: | 443 | exit: |
444 | if (!flags_mode) { | 444 | if (!flags_mode) { |
445 | 445 | ||
446 | /* Round the resource struct length up to the next boundary (32 or 64) */ | 446 | /* Round the resource struct length up to the next boundary (32 or 64) */ |
@@ -783,7 +783,7 @@ acpi_rs_convert_resource_to_aml(struct acpi_resource *resource, | |||
783 | info++; | 783 | info++; |
784 | } | 784 | } |
785 | 785 | ||
786 | exit: | 786 | exit: |
787 | return_ACPI_STATUS(AE_OK); | 787 | return_ACPI_STATUS(AE_OK); |
788 | } | 788 | } |
789 | 789 | ||
diff --git a/drivers/acpi/acpica/rsutils.c b/drivers/acpi/acpica/rsutils.c index 480b6b40c5ea..aef303d56d86 100644 --- a/drivers/acpi/acpica/rsutils.c +++ b/drivers/acpi/acpica/rsutils.c | |||
@@ -784,7 +784,7 @@ acpi_rs_set_srs_method_data(struct acpi_namespace_node *node, | |||
784 | 784 | ||
785 | acpi_ut_remove_reference(args[0]); | 785 | acpi_ut_remove_reference(args[0]); |
786 | 786 | ||
787 | cleanup: | 787 | cleanup: |
788 | ACPI_FREE(info); | 788 | ACPI_FREE(info); |
789 | return_ACPI_STATUS(status); | 789 | return_ACPI_STATUS(status); |
790 | } | 790 | } |
diff --git a/drivers/acpi/acpica/rsxface.c b/drivers/acpi/acpica/rsxface.c index 94e3517554f9..01e476988aae 100644 --- a/drivers/acpi/acpica/rsxface.c +++ b/drivers/acpi/acpica/rsxface.c | |||
@@ -41,7 +41,8 @@ | |||
41 | * POSSIBILITY OF SUCH DAMAGES. | 41 | * POSSIBILITY OF SUCH DAMAGES. |
42 | */ | 42 | */ |
43 | 43 | ||
44 | #include <linux/export.h> | 44 | #define EXPORT_ACPI_INTERFACES |
45 | |||
45 | #include <acpi/acpi.h> | 46 | #include <acpi/acpi.h> |
46 | #include "accommon.h" | 47 | #include "accommon.h" |
47 | #include "acresrc.h" | 48 | #include "acresrc.h" |
diff --git a/drivers/acpi/acpica/tbinstal.c b/drivers/acpi/acpica/tbinstal.c index 42a13c0d7015..634357d51fe9 100644 --- a/drivers/acpi/acpica/tbinstal.c +++ b/drivers/acpi/acpica/tbinstal.c | |||
@@ -80,16 +80,10 @@ acpi_status acpi_tb_verify_table(struct acpi_table_desc *table_desc) | |||
80 | } | 80 | } |
81 | } | 81 | } |
82 | 82 | ||
83 | /* FACS is the odd table, has no standard ACPI header and no checksum */ | 83 | /* Always calculate checksum, ignore bad checksum if requested */ |
84 | 84 | ||
85 | if (!ACPI_COMPARE_NAME(&table_desc->signature, ACPI_SIG_FACS)) { | 85 | status = |
86 | 86 | acpi_tb_verify_checksum(table_desc->pointer, table_desc->length); | |
87 | /* Always calculate checksum, ignore bad checksum if requested */ | ||
88 | |||
89 | status = | ||
90 | acpi_tb_verify_checksum(table_desc->pointer, | ||
91 | table_desc->length); | ||
92 | } | ||
93 | 87 | ||
94 | return_ACPI_STATUS(status); | 88 | return_ACPI_STATUS(status); |
95 | } | 89 | } |
@@ -237,10 +231,10 @@ acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index) | |||
237 | goto release; | 231 | goto release; |
238 | } | 232 | } |
239 | 233 | ||
240 | print_header: | 234 | print_header: |
241 | acpi_tb_print_table_header(table_desc->address, table_desc->pointer); | 235 | acpi_tb_print_table_header(table_desc->address, table_desc->pointer); |
242 | 236 | ||
243 | release: | 237 | release: |
244 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | 238 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); |
245 | return_ACPI_STATUS(status); | 239 | return_ACPI_STATUS(status); |
246 | } | 240 | } |
@@ -312,7 +306,7 @@ struct acpi_table_header *acpi_tb_table_override(struct acpi_table_header | |||
312 | 306 | ||
313 | return (NULL); /* There was no override */ | 307 | return (NULL); /* There was no override */ |
314 | 308 | ||
315 | finish_override: | 309 | finish_override: |
316 | 310 | ||
317 | ACPI_INFO((AE_INFO, | 311 | ACPI_INFO((AE_INFO, |
318 | "%4.4s %p %s table override, new table: %p", | 312 | "%4.4s %p %s table override, new table: %p", |
diff --git a/drivers/acpi/acpica/tbprint.c b/drivers/acpi/acpica/tbprint.c index dc963f823d2c..6866e767ba90 100644 --- a/drivers/acpi/acpica/tbprint.c +++ b/drivers/acpi/acpica/tbprint.c | |||
@@ -135,10 +135,10 @@ acpi_tb_print_table_header(acpi_physical_address address, | |||
135 | 135 | ||
136 | /* FACS only has signature and length fields */ | 136 | /* FACS only has signature and length fields */ |
137 | 137 | ||
138 | ACPI_INFO((AE_INFO, "%4.4s %p %05X", | 138 | ACPI_INFO((AE_INFO, "%4.4s %p %06X", |
139 | header->signature, ACPI_CAST_PTR(void, address), | 139 | header->signature, ACPI_CAST_PTR(void, address), |
140 | header->length)); | 140 | header->length)); |
141 | } else if (ACPI_COMPARE_NAME(header->signature, ACPI_SIG_RSDP)) { | 141 | } else if (ACPI_VALIDATE_RSDP_SIG(header->signature)) { |
142 | 142 | ||
143 | /* RSDP has no common fields */ | 143 | /* RSDP has no common fields */ |
144 | 144 | ||
@@ -147,7 +147,7 @@ acpi_tb_print_table_header(acpi_physical_address address, | |||
147 | header)->oem_id, ACPI_OEM_ID_SIZE); | 147 | header)->oem_id, ACPI_OEM_ID_SIZE); |
148 | acpi_tb_fix_string(local_header.oem_id, ACPI_OEM_ID_SIZE); | 148 | acpi_tb_fix_string(local_header.oem_id, ACPI_OEM_ID_SIZE); |
149 | 149 | ||
150 | ACPI_INFO((AE_INFO, "RSDP %p %05X (v%.2d %6.6s)", | 150 | ACPI_INFO((AE_INFO, "RSDP %p %06X (v%.2d %6.6s)", |
151 | ACPI_CAST_PTR(void, address), | 151 | ACPI_CAST_PTR(void, address), |
152 | (ACPI_CAST_PTR(struct acpi_table_rsdp, header)-> | 152 | (ACPI_CAST_PTR(struct acpi_table_rsdp, header)-> |
153 | revision > | 153 | revision > |
@@ -162,7 +162,7 @@ acpi_tb_print_table_header(acpi_physical_address address, | |||
162 | acpi_tb_cleanup_table_header(&local_header, header); | 162 | acpi_tb_cleanup_table_header(&local_header, header); |
163 | 163 | ||
164 | ACPI_INFO((AE_INFO, | 164 | ACPI_INFO((AE_INFO, |
165 | "%4.4s %p %05X (v%.2d %6.6s %8.8s %08X %4.4s %08X)", | 165 | "%4.4s %p %06X (v%.2d %6.6s %8.8s %08X %4.4s %08X)", |
166 | local_header.signature, ACPI_CAST_PTR(void, address), | 166 | local_header.signature, ACPI_CAST_PTR(void, address), |
167 | local_header.length, local_header.revision, | 167 | local_header.length, local_header.revision, |
168 | local_header.oem_id, local_header.oem_table_id, | 168 | local_header.oem_id, local_header.oem_table_id, |
@@ -190,6 +190,16 @@ acpi_status acpi_tb_verify_checksum(struct acpi_table_header *table, u32 length) | |||
190 | { | 190 | { |
191 | u8 checksum; | 191 | u8 checksum; |
192 | 192 | ||
193 | /* | ||
194 | * FACS/S3PT: | ||
195 | * They are the odd tables, have no standard ACPI header and no checksum | ||
196 | */ | ||
197 | |||
198 | if (ACPI_COMPARE_NAME(table->signature, ACPI_SIG_S3PT) || | ||
199 | ACPI_COMPARE_NAME(table->signature, ACPI_SIG_FACS)) { | ||
200 | return (AE_OK); | ||
201 | } | ||
202 | |||
193 | /* Compute the checksum on the table */ | 203 | /* Compute the checksum on the table */ |
194 | 204 | ||
195 | checksum = acpi_tb_checksum(ACPI_CAST_PTR(u8, table), length); | 205 | checksum = acpi_tb_checksum(ACPI_CAST_PTR(u8, table), length); |
diff --git a/drivers/acpi/acpica/tbutils.c b/drivers/acpi/acpica/tbutils.c index bffdfc7b8322..3d6bb83aa7e7 100644 --- a/drivers/acpi/acpica/tbutils.c +++ b/drivers/acpi/acpica/tbutils.c | |||
@@ -350,7 +350,7 @@ acpi_tb_install_table(acpi_physical_address address, | |||
350 | acpi_tb_delete_table(table_desc); | 350 | acpi_tb_delete_table(table_desc); |
351 | } | 351 | } |
352 | 352 | ||
353 | unmap_and_exit: | 353 | unmap_and_exit: |
354 | 354 | ||
355 | /* Always unmap the table header that we mapped above */ | 355 | /* Always unmap the table header that we mapped above */ |
356 | 356 | ||
@@ -430,8 +430,7 @@ acpi_tb_get_root_table_entry(u8 *table_entry, u32 table_entry_size) | |||
430 | * | 430 | * |
431 | ******************************************************************************/ | 431 | ******************************************************************************/ |
432 | 432 | ||
433 | acpi_status __init | 433 | acpi_status __init acpi_tb_parse_root_table(acpi_physical_address rsdp_address) |
434 | acpi_tb_parse_root_table(acpi_physical_address rsdp_address) | ||
435 | { | 434 | { |
436 | struct acpi_table_rsdp *rsdp; | 435 | struct acpi_table_rsdp *rsdp; |
437 | u32 table_entry_size; | 436 | u32 table_entry_size; |
diff --git a/drivers/acpi/acpica/tbxface.c b/drivers/acpi/acpica/tbxface.c index ad11162482ff..db826eaadd1c 100644 --- a/drivers/acpi/acpica/tbxface.c +++ b/drivers/acpi/acpica/tbxface.c | |||
@@ -41,7 +41,8 @@ | |||
41 | * POSSIBILITY OF SUCH DAMAGES. | 41 | * POSSIBILITY OF SUCH DAMAGES. |
42 | */ | 42 | */ |
43 | 43 | ||
44 | #include <linux/export.h> | 44 | #define EXPORT_ACPI_INTERFACES |
45 | |||
45 | #include <acpi/acpi.h> | 46 | #include <acpi/acpi.h> |
46 | #include "accommon.h" | 47 | #include "accommon.h" |
47 | #include "actables.h" | 48 | #include "actables.h" |
@@ -147,6 +148,8 @@ acpi_initialize_tables(struct acpi_table_desc * initial_table_array, | |||
147 | return_ACPI_STATUS(status); | 148 | return_ACPI_STATUS(status); |
148 | } | 149 | } |
149 | 150 | ||
151 | ACPI_EXPORT_SYMBOL_INIT(acpi_initialize_tables) | ||
152 | |||
150 | /******************************************************************************* | 153 | /******************************************************************************* |
151 | * | 154 | * |
152 | * FUNCTION: acpi_reallocate_root_table | 155 | * FUNCTION: acpi_reallocate_root_table |
@@ -161,7 +164,7 @@ acpi_initialize_tables(struct acpi_table_desc * initial_table_array, | |||
161 | * kernel. | 164 | * kernel. |
162 | * | 165 | * |
163 | ******************************************************************************/ | 166 | ******************************************************************************/ |
164 | acpi_status acpi_reallocate_root_table(void) | 167 | acpi_status __init acpi_reallocate_root_table(void) |
165 | { | 168 | { |
166 | acpi_status status; | 169 | acpi_status status; |
167 | 170 | ||
@@ -181,6 +184,8 @@ acpi_status acpi_reallocate_root_table(void) | |||
181 | return_ACPI_STATUS(status); | 184 | return_ACPI_STATUS(status); |
182 | } | 185 | } |
183 | 186 | ||
187 | ACPI_EXPORT_SYMBOL_INIT(acpi_reallocate_root_table) | ||
188 | |||
184 | /******************************************************************************* | 189 | /******************************************************************************* |
185 | * | 190 | * |
186 | * FUNCTION: acpi_get_table_header | 191 | * FUNCTION: acpi_get_table_header |
@@ -356,6 +361,7 @@ acpi_get_table_with_size(char *signature, | |||
356 | 361 | ||
357 | return (AE_NOT_FOUND); | 362 | return (AE_NOT_FOUND); |
358 | } | 363 | } |
364 | |||
359 | ACPI_EXPORT_SYMBOL(acpi_get_table_with_size) | 365 | ACPI_EXPORT_SYMBOL(acpi_get_table_with_size) |
360 | 366 | ||
361 | acpi_status | 367 | acpi_status |
@@ -367,6 +373,7 @@ acpi_get_table(char *signature, | |||
367 | return acpi_get_table_with_size(signature, | 373 | return acpi_get_table_with_size(signature, |
368 | instance, out_table, &tbl_size); | 374 | instance, out_table, &tbl_size); |
369 | } | 375 | } |
376 | |||
370 | ACPI_EXPORT_SYMBOL(acpi_get_table) | 377 | ACPI_EXPORT_SYMBOL(acpi_get_table) |
371 | 378 | ||
372 | /******************************************************************************* | 379 | /******************************************************************************* |
@@ -424,7 +431,6 @@ acpi_get_table_by_index(u32 table_index, struct acpi_table_header **table) | |||
424 | 431 | ||
425 | ACPI_EXPORT_SYMBOL(acpi_get_table_by_index) | 432 | ACPI_EXPORT_SYMBOL(acpi_get_table_by_index) |
426 | 433 | ||
427 | |||
428 | /******************************************************************************* | 434 | /******************************************************************************* |
429 | * | 435 | * |
430 | * FUNCTION: acpi_install_table_handler | 436 | * FUNCTION: acpi_install_table_handler |
@@ -465,7 +471,7 @@ acpi_install_table_handler(acpi_table_handler handler, void *context) | |||
465 | acpi_gbl_table_handler = handler; | 471 | acpi_gbl_table_handler = handler; |
466 | acpi_gbl_table_handler_context = context; | 472 | acpi_gbl_table_handler_context = context; |
467 | 473 | ||
468 | cleanup: | 474 | cleanup: |
469 | (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); | 475 | (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); |
470 | return_ACPI_STATUS(status); | 476 | return_ACPI_STATUS(status); |
471 | } | 477 | } |
@@ -506,7 +512,7 @@ acpi_status acpi_remove_table_handler(acpi_table_handler handler) | |||
506 | 512 | ||
507 | acpi_gbl_table_handler = NULL; | 513 | acpi_gbl_table_handler = NULL; |
508 | 514 | ||
509 | cleanup: | 515 | cleanup: |
510 | (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); | 516 | (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); |
511 | return_ACPI_STATUS(status); | 517 | return_ACPI_STATUS(status); |
512 | } | 518 | } |
diff --git a/drivers/acpi/acpica/tbxfload.c b/drivers/acpi/acpica/tbxfload.c index 0ba9e328d5d7..60b5a871833c 100644 --- a/drivers/acpi/acpica/tbxfload.c +++ b/drivers/acpi/acpica/tbxfload.c | |||
@@ -41,7 +41,8 @@ | |||
41 | * POSSIBILITY OF SUCH DAMAGES. | 41 | * POSSIBILITY OF SUCH DAMAGES. |
42 | */ | 42 | */ |
43 | 43 | ||
44 | #include <linux/export.h> | 44 | #define EXPORT_ACPI_INTERFACES |
45 | |||
45 | #include <acpi/acpi.h> | 46 | #include <acpi/acpi.h> |
46 | #include "accommon.h" | 47 | #include "accommon.h" |
47 | #include "acnamesp.h" | 48 | #include "acnamesp.h" |
@@ -65,7 +66,7 @@ static acpi_status acpi_tb_load_namespace(void); | |||
65 | * | 66 | * |
66 | ******************************************************************************/ | 67 | ******************************************************************************/ |
67 | 68 | ||
68 | acpi_status acpi_load_tables(void) | 69 | acpi_status __init acpi_load_tables(void) |
69 | { | 70 | { |
70 | acpi_status status; | 71 | acpi_status status; |
71 | 72 | ||
@@ -82,7 +83,7 @@ acpi_status acpi_load_tables(void) | |||
82 | return_ACPI_STATUS(status); | 83 | return_ACPI_STATUS(status); |
83 | } | 84 | } |
84 | 85 | ||
85 | ACPI_EXPORT_SYMBOL(acpi_load_tables) | 86 | ACPI_EXPORT_SYMBOL_INIT(acpi_load_tables) |
86 | 87 | ||
87 | /******************************************************************************* | 88 | /******************************************************************************* |
88 | * | 89 | * |
@@ -200,7 +201,7 @@ static acpi_status acpi_tb_load_namespace(void) | |||
200 | 201 | ||
201 | ACPI_INFO((AE_INFO, "All ACPI Tables successfully acquired")); | 202 | ACPI_INFO((AE_INFO, "All ACPI Tables successfully acquired")); |
202 | 203 | ||
203 | unlock_and_exit: | 204 | unlock_and_exit: |
204 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); | 205 | (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); |
205 | return_ACPI_STATUS(status); | 206 | return_ACPI_STATUS(status); |
206 | } | 207 | } |
@@ -268,7 +269,7 @@ acpi_status acpi_load_table(struct acpi_table_header *table) | |||
268 | acpi_gbl_table_handler_context); | 269 | acpi_gbl_table_handler_context); |
269 | } | 270 | } |
270 | 271 | ||
271 | unlock_and_exit: | 272 | unlock_and_exit: |
272 | (void)acpi_ut_release_mutex(ACPI_MTX_INTERPRETER); | 273 | (void)acpi_ut_release_mutex(ACPI_MTX_INTERPRETER); |
273 | return_ACPI_STATUS(status); | 274 | return_ACPI_STATUS(status); |
274 | } | 275 | } |
diff --git a/drivers/acpi/acpica/tbxfroot.c b/drivers/acpi/acpica/tbxfroot.c index 948c95e80d44..e4e1468877c3 100644 --- a/drivers/acpi/acpica/tbxfroot.c +++ b/drivers/acpi/acpica/tbxfroot.c | |||
@@ -68,8 +68,7 @@ acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp) | |||
68 | * Note: Sometimes there exists more than one RSDP in memory; the valid | 68 | * Note: Sometimes there exists more than one RSDP in memory; the valid |
69 | * RSDP has a valid checksum, all others have an invalid checksum. | 69 | * RSDP has a valid checksum, all others have an invalid checksum. |
70 | */ | 70 | */ |
71 | if (ACPI_STRNCMP((char *)rsdp->signature, ACPI_SIG_RSDP, | 71 | if (!ACPI_VALIDATE_RSDP_SIG(rsdp->signature)) { |
72 | sizeof(ACPI_SIG_RSDP) - 1) != 0) { | ||
73 | 72 | ||
74 | /* Nope, BAD Signature */ | 73 | /* Nope, BAD Signature */ |
75 | 74 | ||
@@ -112,7 +111,7 @@ acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp) | |||
112 | * | 111 | * |
113 | ******************************************************************************/ | 112 | ******************************************************************************/ |
114 | 113 | ||
115 | acpi_status acpi_find_root_pointer(acpi_size *table_address) | 114 | acpi_status __init acpi_find_root_pointer(acpi_size *table_address) |
116 | { | 115 | { |
117 | u8 *table_ptr; | 116 | u8 *table_ptr; |
118 | u8 *mem_rover; | 117 | u8 *mem_rover; |
diff --git a/drivers/acpi/acpica/utalloc.c b/drivers/acpi/acpica/utalloc.c index e0ffb580f4b0..814267f52715 100644 --- a/drivers/acpi/acpica/utalloc.c +++ b/drivers/acpi/acpica/utalloc.c | |||
@@ -48,6 +48,39 @@ | |||
48 | #define _COMPONENT ACPI_UTILITIES | 48 | #define _COMPONENT ACPI_UTILITIES |
49 | ACPI_MODULE_NAME("utalloc") | 49 | ACPI_MODULE_NAME("utalloc") |
50 | 50 | ||
51 | #if !defined (USE_NATIVE_ALLOCATE_ZEROED) | ||
52 | /******************************************************************************* | ||
53 | * | ||
54 | * FUNCTION: acpi_os_allocate_zeroed | ||
55 | * | ||
56 | * PARAMETERS: size - Size of the allocation | ||
57 | * | ||
58 | * RETURN: Address of the allocated memory on success, NULL on failure. | ||
59 | * | ||
60 | * DESCRIPTION: Subsystem equivalent of calloc. Allocate and zero memory. | ||
61 | * This is the default implementation. Can be overridden via the | ||
62 | * USE_NATIVE_ALLOCATE_ZEROED flag. | ||
63 | * | ||
64 | ******************************************************************************/ | ||
65 | void *acpi_os_allocate_zeroed(acpi_size size) | ||
66 | { | ||
67 | void *allocation; | ||
68 | |||
69 | ACPI_FUNCTION_ENTRY(); | ||
70 | |||
71 | allocation = acpi_os_allocate(size); | ||
72 | if (allocation) { | ||
73 | |||
74 | /* Clear the memory block */ | ||
75 | |||
76 | ACPI_MEMSET(allocation, 0, size); | ||
77 | } | ||
78 | |||
79 | return (allocation); | ||
80 | } | ||
81 | |||
82 | #endif /* !USE_NATIVE_ALLOCATE_ZEROED */ | ||
83 | |||
51 | /******************************************************************************* | 84 | /******************************************************************************* |
52 | * | 85 | * |
53 | * FUNCTION: acpi_ut_create_caches | 86 | * FUNCTION: acpi_ut_create_caches |
@@ -59,6 +92,7 @@ ACPI_MODULE_NAME("utalloc") | |||
59 | * DESCRIPTION: Create all local caches | 92 | * DESCRIPTION: Create all local caches |
60 | * | 93 | * |
61 | ******************************************************************************/ | 94 | ******************************************************************************/ |
95 | |||
62 | acpi_status acpi_ut_create_caches(void) | 96 | acpi_status acpi_ut_create_caches(void) |
63 | { | 97 | { |
64 | acpi_status status; | 98 | acpi_status status; |
@@ -175,10 +209,10 @@ acpi_status acpi_ut_delete_caches(void) | |||
175 | 209 | ||
176 | /* Free memory lists */ | 210 | /* Free memory lists */ |
177 | 211 | ||
178 | ACPI_FREE(acpi_gbl_global_list); | 212 | acpi_os_free(acpi_gbl_global_list); |
179 | acpi_gbl_global_list = NULL; | 213 | acpi_gbl_global_list = NULL; |
180 | 214 | ||
181 | ACPI_FREE(acpi_gbl_ns_node_list); | 215 | acpi_os_free(acpi_gbl_ns_node_list); |
182 | acpi_gbl_ns_node_list = NULL; | 216 | acpi_gbl_ns_node_list = NULL; |
183 | #endif | 217 | #endif |
184 | 218 | ||
@@ -302,82 +336,3 @@ acpi_ut_initialize_buffer(struct acpi_buffer * buffer, | |||
302 | ACPI_MEMSET(buffer->pointer, 0, required_length); | 336 | ACPI_MEMSET(buffer->pointer, 0, required_length); |
303 | return (AE_OK); | 337 | return (AE_OK); |
304 | } | 338 | } |
305 | |||
306 | #ifdef NOT_USED_BY_LINUX | ||
307 | /******************************************************************************* | ||
308 | * | ||
309 | * FUNCTION: acpi_ut_allocate | ||
310 | * | ||
311 | * PARAMETERS: size - Size of the allocation | ||
312 | * component - Component type of caller | ||
313 | * module - Source file name of caller | ||
314 | * line - Line number of caller | ||
315 | * | ||
316 | * RETURN: Address of the allocated memory on success, NULL on failure. | ||
317 | * | ||
318 | * DESCRIPTION: Subsystem equivalent of malloc. | ||
319 | * | ||
320 | ******************************************************************************/ | ||
321 | |||
322 | void *acpi_ut_allocate(acpi_size size, | ||
323 | u32 component, const char *module, u32 line) | ||
324 | { | ||
325 | void *allocation; | ||
326 | |||
327 | ACPI_FUNCTION_TRACE_U32(ut_allocate, size); | ||
328 | |||
329 | /* Check for an inadvertent size of zero bytes */ | ||
330 | |||
331 | if (!size) { | ||
332 | ACPI_WARNING((module, line, | ||
333 | "Attempt to allocate zero bytes, allocating 1 byte")); | ||
334 | size = 1; | ||
335 | } | ||
336 | |||
337 | allocation = acpi_os_allocate(size); | ||
338 | if (!allocation) { | ||
339 | |||
340 | /* Report allocation error */ | ||
341 | |||
342 | ACPI_WARNING((module, line, | ||
343 | "Could not allocate size %u", (u32) size)); | ||
344 | |||
345 | return_PTR(NULL); | ||
346 | } | ||
347 | |||
348 | return_PTR(allocation); | ||
349 | } | ||
350 | |||
351 | /******************************************************************************* | ||
352 | * | ||
353 | * FUNCTION: acpi_ut_allocate_zeroed | ||
354 | * | ||
355 | * PARAMETERS: size - Size of the allocation | ||
356 | * component - Component type of caller | ||
357 | * module - Source file name of caller | ||
358 | * line - Line number of caller | ||
359 | * | ||
360 | * RETURN: Address of the allocated memory on success, NULL on failure. | ||
361 | * | ||
362 | * DESCRIPTION: Subsystem equivalent of calloc. Allocate and zero memory. | ||
363 | * | ||
364 | ******************************************************************************/ | ||
365 | |||
366 | void *acpi_ut_allocate_zeroed(acpi_size size, | ||
367 | u32 component, const char *module, u32 line) | ||
368 | { | ||
369 | void *allocation; | ||
370 | |||
371 | ACPI_FUNCTION_ENTRY(); | ||
372 | |||
373 | allocation = acpi_ut_allocate(size, component, module, line); | ||
374 | if (allocation) { | ||
375 | |||
376 | /* Clear the memory block */ | ||
377 | |||
378 | ACPI_MEMSET(allocation, 0, size); | ||
379 | } | ||
380 | |||
381 | return (allocation); | ||
382 | } | ||
383 | #endif | ||
diff --git a/drivers/acpi/acpica/utcache.c b/drivers/acpi/acpica/utcache.c index a877a9647fd9..366bfec4b770 100644 --- a/drivers/acpi/acpica/utcache.c +++ b/drivers/acpi/acpica/utcache.c | |||
@@ -65,7 +65,7 @@ ACPI_MODULE_NAME("utcache") | |||
65 | acpi_status | 65 | acpi_status |
66 | acpi_os_create_cache(char *cache_name, | 66 | acpi_os_create_cache(char *cache_name, |
67 | u16 object_size, | 67 | u16 object_size, |
68 | u16 max_depth, struct acpi_memory_list ** return_cache) | 68 | u16 max_depth, struct acpi_memory_list **return_cache) |
69 | { | 69 | { |
70 | struct acpi_memory_list *cache; | 70 | struct acpi_memory_list *cache; |
71 | 71 | ||
diff --git a/drivers/acpi/acpica/utcopy.c b/drivers/acpi/acpica/utcopy.c index 1731c27c36a6..edff4e653d9a 100644 --- a/drivers/acpi/acpica/utcopy.c +++ b/drivers/acpi/acpica/utcopy.c | |||
@@ -552,7 +552,7 @@ acpi_ut_copy_esimple_to_isimple(union acpi_object *external_object, | |||
552 | *ret_internal_object = internal_object; | 552 | *ret_internal_object = internal_object; |
553 | return_ACPI_STATUS(AE_OK); | 553 | return_ACPI_STATUS(AE_OK); |
554 | 554 | ||
555 | error_exit: | 555 | error_exit: |
556 | acpi_ut_remove_reference(internal_object); | 556 | acpi_ut_remove_reference(internal_object); |
557 | return_ACPI_STATUS(AE_NO_MEMORY); | 557 | return_ACPI_STATUS(AE_NO_MEMORY); |
558 | } | 558 | } |
@@ -899,7 +899,7 @@ acpi_ut_copy_ielement_to_ielement(u8 object_type, | |||
899 | 899 | ||
900 | return (status); | 900 | return (status); |
901 | 901 | ||
902 | error_exit: | 902 | error_exit: |
903 | acpi_ut_remove_reference(target_object); | 903 | acpi_ut_remove_reference(target_object); |
904 | return (status); | 904 | return (status); |
905 | } | 905 | } |
diff --git a/drivers/acpi/acpica/utdebug.c b/drivers/acpi/acpica/utdebug.c index 5796e11a0671..1a67b3944b3b 100644 --- a/drivers/acpi/acpica/utdebug.c +++ b/drivers/acpi/acpica/utdebug.c | |||
@@ -41,7 +41,8 @@ | |||
41 | * POSSIBILITY OF SUCH DAMAGES. | 41 | * POSSIBILITY OF SUCH DAMAGES. |
42 | */ | 42 | */ |
43 | 43 | ||
44 | #include <linux/export.h> | 44 | #define EXPORT_ACPI_INTERFACES |
45 | |||
45 | #include <acpi/acpi.h> | 46 | #include <acpi/acpi.h> |
46 | #include "accommon.h" | 47 | #include "accommon.h" |
47 | 48 | ||
@@ -190,7 +191,7 @@ acpi_debug_print(u32 requested_debug_level, | |||
190 | * Display the module name, current line number, thread ID (if requested), | 191 | * Display the module name, current line number, thread ID (if requested), |
191 | * current procedure nesting level, and the current procedure name | 192 | * current procedure nesting level, and the current procedure name |
192 | */ | 193 | */ |
193 | acpi_os_printf("%8s-%04ld ", module_name, line_number); | 194 | acpi_os_printf("%9s-%04ld ", module_name, line_number); |
194 | 195 | ||
195 | if (ACPI_LV_THREADS & acpi_dbg_level) { | 196 | if (ACPI_LV_THREADS & acpi_dbg_level) { |
196 | acpi_os_printf("[%u] ", (u32)thread_id); | 197 | acpi_os_printf("[%u] ", (u32)thread_id); |
diff --git a/drivers/acpi/acpica/utdecode.c b/drivers/acpi/acpica/utdecode.c index 11e2e02e1618..b3f31dd89a45 100644 --- a/drivers/acpi/acpica/utdecode.c +++ b/drivers/acpi/acpica/utdecode.c | |||
@@ -41,7 +41,6 @@ | |||
41 | * POSSIBILITY OF SUCH DAMAGES. | 41 | * POSSIBILITY OF SUCH DAMAGES. |
42 | */ | 42 | */ |
43 | 43 | ||
44 | #include <linux/export.h> | ||
45 | #include <acpi/acpi.h> | 44 | #include <acpi/acpi.h> |
46 | #include "accommon.h" | 45 | #include "accommon.h" |
47 | #include "acnamesp.h" | 46 | #include "acnamesp.h" |
diff --git a/drivers/acpi/acpica/utdelete.c b/drivers/acpi/acpica/utdelete.c index d6b33f29d327..c07d2227ea42 100644 --- a/drivers/acpi/acpica/utdelete.c +++ b/drivers/acpi/acpica/utdelete.c | |||
@@ -649,7 +649,7 @@ acpi_ut_update_object_reference(union acpi_operand_object *object, u16 action) | |||
649 | 649 | ||
650 | return (AE_OK); | 650 | return (AE_OK); |
651 | 651 | ||
652 | error_exit: | 652 | error_exit: |
653 | 653 | ||
654 | ACPI_EXCEPTION((AE_INFO, status, | 654 | ACPI_EXCEPTION((AE_INFO, status, |
655 | "Could not update object reference count")); | 655 | "Could not update object reference count")); |
diff --git a/drivers/acpi/acpica/uteval.c b/drivers/acpi/acpica/uteval.c index 4fd68971019b..16fb90506db7 100644 --- a/drivers/acpi/acpica/uteval.c +++ b/drivers/acpi/acpica/uteval.c | |||
@@ -181,7 +181,7 @@ acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node, | |||
181 | 181 | ||
182 | *return_desc = info->return_object; | 182 | *return_desc = info->return_object; |
183 | 183 | ||
184 | cleanup: | 184 | cleanup: |
185 | ACPI_FREE(info); | 185 | ACPI_FREE(info); |
186 | return_ACPI_STATUS(status); | 186 | return_ACPI_STATUS(status); |
187 | } | 187 | } |
diff --git a/drivers/acpi/acpica/utexcep.c b/drivers/acpi/acpica/utexcep.c index ff6d9e8aa842..3cf7b597edb9 100644 --- a/drivers/acpi/acpica/utexcep.c +++ b/drivers/acpi/acpica/utexcep.c | |||
@@ -41,8 +41,9 @@ | |||
41 | * POSSIBILITY OF SUCH DAMAGES. | 41 | * POSSIBILITY OF SUCH DAMAGES. |
42 | */ | 42 | */ |
43 | 43 | ||
44 | #define EXPORT_ACPI_INTERFACES | ||
45 | |||
44 | #define ACPI_DEFINE_EXCEPTION_TABLE | 46 | #define ACPI_DEFINE_EXCEPTION_TABLE |
45 | #include <linux/export.h> | ||
46 | #include <acpi/acpi.h> | 47 | #include <acpi/acpi.h> |
47 | #include "accommon.h" | 48 | #include "accommon.h" |
48 | 49 | ||
diff --git a/drivers/acpi/acpica/utglobal.c b/drivers/acpi/acpica/utglobal.c index d6f26bf8a062..81f9a9584451 100644 --- a/drivers/acpi/acpica/utglobal.c +++ b/drivers/acpi/acpica/utglobal.c | |||
@@ -41,9 +41,9 @@ | |||
41 | * POSSIBILITY OF SUCH DAMAGES. | 41 | * POSSIBILITY OF SUCH DAMAGES. |
42 | */ | 42 | */ |
43 | 43 | ||
44 | #define EXPORT_ACPI_INTERFACES | ||
44 | #define DEFINE_ACPI_GLOBALS | 45 | #define DEFINE_ACPI_GLOBALS |
45 | 46 | ||
46 | #include <linux/export.h> | ||
47 | #include <acpi/acpi.h> | 47 | #include <acpi/acpi.h> |
48 | #include "accommon.h" | 48 | #include "accommon.h" |
49 | 49 | ||
@@ -289,9 +289,19 @@ acpi_status acpi_ut_init_globals(void) | |||
289 | 289 | ||
290 | acpi_gbl_owner_id_mask[ACPI_NUM_OWNERID_MASKS - 1] = 0x80000000; | 290 | acpi_gbl_owner_id_mask[ACPI_NUM_OWNERID_MASKS - 1] = 0x80000000; |
291 | 291 | ||
292 | /* Event counters */ | ||
293 | |||
294 | acpi_method_count = 0; | ||
295 | acpi_sci_count = 0; | ||
296 | acpi_gpe_count = 0; | ||
297 | |||
298 | for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) { | ||
299 | acpi_fixed_event_count[i] = 0; | ||
300 | } | ||
301 | |||
292 | #if (!ACPI_REDUCED_HARDWARE) | 302 | #if (!ACPI_REDUCED_HARDWARE) |
293 | 303 | ||
294 | /* GPE support */ | 304 | /* GPE/SCI support */ |
295 | 305 | ||
296 | acpi_gbl_all_gpes_initialized = FALSE; | 306 | acpi_gbl_all_gpes_initialized = FALSE; |
297 | acpi_gbl_gpe_xrupt_list_head = NULL; | 307 | acpi_gbl_gpe_xrupt_list_head = NULL; |
@@ -300,6 +310,7 @@ acpi_status acpi_ut_init_globals(void) | |||
300 | acpi_current_gpe_count = 0; | 310 | acpi_current_gpe_count = 0; |
301 | 311 | ||
302 | acpi_gbl_global_event_handler = NULL; | 312 | acpi_gbl_global_event_handler = NULL; |
313 | acpi_gbl_sci_handler_list = NULL; | ||
303 | 314 | ||
304 | #endif /* !ACPI_REDUCED_HARDWARE */ | 315 | #endif /* !ACPI_REDUCED_HARDWARE */ |
305 | 316 | ||
@@ -377,6 +388,11 @@ acpi_status acpi_ut_init_globals(void) | |||
377 | /* Public globals */ | 388 | /* Public globals */ |
378 | 389 | ||
379 | ACPI_EXPORT_SYMBOL(acpi_gbl_FADT) | 390 | ACPI_EXPORT_SYMBOL(acpi_gbl_FADT) |
391 | |||
380 | ACPI_EXPORT_SYMBOL(acpi_dbg_level) | 392 | ACPI_EXPORT_SYMBOL(acpi_dbg_level) |
393 | |||
381 | ACPI_EXPORT_SYMBOL(acpi_dbg_layer) | 394 | ACPI_EXPORT_SYMBOL(acpi_dbg_layer) |
395 | |||
396 | ACPI_EXPORT_SYMBOL(acpi_gpe_count) | ||
397 | |||
382 | ACPI_EXPORT_SYMBOL(acpi_current_gpe_count) | 398 | ACPI_EXPORT_SYMBOL(acpi_current_gpe_count) |
diff --git a/drivers/acpi/acpica/utids.c b/drivers/acpi/acpica/utids.c index fa69071db418..bfca7b4b6731 100644 --- a/drivers/acpi/acpica/utids.c +++ b/drivers/acpi/acpica/utids.c | |||
@@ -184,7 +184,7 @@ acpi_ut_execute_SUB(struct acpi_namespace_node *device_node, | |||
184 | sub->length = length; | 184 | sub->length = length; |
185 | *return_id = sub; | 185 | *return_id = sub; |
186 | 186 | ||
187 | cleanup: | 187 | cleanup: |
188 | 188 | ||
189 | /* On exit, we must delete the return object */ | 189 | /* On exit, we must delete the return object */ |
190 | 190 | ||
diff --git a/drivers/acpi/acpica/utobject.c b/drivers/acpi/acpica/utobject.c index aa61f66ee861..13e045025c33 100644 --- a/drivers/acpi/acpica/utobject.c +++ b/drivers/acpi/acpica/utobject.c | |||
@@ -180,7 +180,7 @@ union acpi_operand_object *acpi_ut_create_package_object(u32 count) | |||
180 | package_elements = ACPI_ALLOCATE_ZEROED(((acpi_size) count + | 180 | package_elements = ACPI_ALLOCATE_ZEROED(((acpi_size) count + |
181 | 1) * sizeof(void *)); | 181 | 1) * sizeof(void *)); |
182 | if (!package_elements) { | 182 | if (!package_elements) { |
183 | acpi_ut_remove_reference(package_desc); | 183 | ACPI_FREE(package_desc); |
184 | return_PTR(NULL); | 184 | return_PTR(NULL); |
185 | } | 185 | } |
186 | 186 | ||
@@ -396,7 +396,6 @@ void *acpi_ut_allocate_object_desc_dbg(const char *module_name, | |||
396 | 396 | ||
397 | /* Mark the descriptor type */ | 397 | /* Mark the descriptor type */ |
398 | 398 | ||
399 | memset(object, 0, sizeof(union acpi_operand_object)); | ||
400 | ACPI_SET_DESCRIPTOR_TYPE(object, ACPI_DESC_TYPE_OPERAND); | 399 | ACPI_SET_DESCRIPTOR_TYPE(object, ACPI_DESC_TYPE_OPERAND); |
401 | 400 | ||
402 | ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, "%p Size %X\n", | 401 | ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, "%p Size %X\n", |
@@ -461,25 +460,28 @@ acpi_ut_get_simple_object_size(union acpi_operand_object *internal_object, | |||
461 | 460 | ||
462 | ACPI_FUNCTION_TRACE_PTR(ut_get_simple_object_size, internal_object); | 461 | ACPI_FUNCTION_TRACE_PTR(ut_get_simple_object_size, internal_object); |
463 | 462 | ||
463 | /* Start with the length of the (external) Acpi object */ | ||
464 | |||
465 | length = sizeof(union acpi_object); | ||
466 | |||
467 | /* A NULL object is allowed, can be a legal uninitialized package element */ | ||
468 | |||
469 | if (!internal_object) { | ||
464 | /* | 470 | /* |
465 | * Handle a null object (Could be a uninitialized package | 471 | * Object is NULL, just return the length of union acpi_object |
466 | * element -- which is legal) | 472 | * (A NULL union acpi_object is an object of all zeroes.) |
467 | */ | 473 | */ |
468 | if (!internal_object) { | 474 | *obj_length = ACPI_ROUND_UP_TO_NATIVE_WORD(length); |
469 | *obj_length = sizeof(union acpi_object); | ||
470 | return_ACPI_STATUS(AE_OK); | 475 | return_ACPI_STATUS(AE_OK); |
471 | } | 476 | } |
472 | 477 | ||
473 | /* Start with the length of the Acpi object */ | 478 | /* A Namespace Node should never appear here */ |
474 | |||
475 | length = sizeof(union acpi_object); | ||
476 | 479 | ||
477 | if (ACPI_GET_DESCRIPTOR_TYPE(internal_object) == ACPI_DESC_TYPE_NAMED) { | 480 | if (ACPI_GET_DESCRIPTOR_TYPE(internal_object) == ACPI_DESC_TYPE_NAMED) { |
478 | 481 | ||
479 | /* Object is a named object (reference), just return the length */ | 482 | /* A namespace node should never get here */ |
480 | 483 | ||
481 | *obj_length = ACPI_ROUND_UP_TO_NATIVE_WORD(length); | 484 | return_ACPI_STATUS(AE_AML_INTERNAL); |
482 | return_ACPI_STATUS(status); | ||
483 | } | 485 | } |
484 | 486 | ||
485 | /* | 487 | /* |
diff --git a/drivers/acpi/acpica/utownerid.c b/drivers/acpi/acpica/utownerid.c index 835340b26d37..eb3aca761369 100644 --- a/drivers/acpi/acpica/utownerid.c +++ b/drivers/acpi/acpica/utownerid.c | |||
@@ -148,7 +148,7 @@ acpi_status acpi_ut_allocate_owner_id(acpi_owner_id * owner_id) | |||
148 | ACPI_ERROR((AE_INFO, | 148 | ACPI_ERROR((AE_INFO, |
149 | "Could not allocate new OwnerId (255 max), AE_OWNER_ID_LIMIT")); | 149 | "Could not allocate new OwnerId (255 max), AE_OWNER_ID_LIMIT")); |
150 | 150 | ||
151 | exit: | 151 | exit: |
152 | (void)acpi_ut_release_mutex(ACPI_MTX_CACHES); | 152 | (void)acpi_ut_release_mutex(ACPI_MTX_CACHES); |
153 | return_ACPI_STATUS(status); | 153 | return_ACPI_STATUS(status); |
154 | } | 154 | } |
diff --git a/drivers/acpi/acpica/utresrc.c b/drivers/acpi/acpica/utresrc.c index cb7fa491decf..2c2accb9e534 100644 --- a/drivers/acpi/acpica/utresrc.c +++ b/drivers/acpi/acpica/utresrc.c | |||
@@ -643,7 +643,7 @@ acpi_ut_validate_resource(struct acpi_walk_state *walk_state, | |||
643 | 643 | ||
644 | return (AE_OK); | 644 | return (AE_OK); |
645 | 645 | ||
646 | invalid_resource: | 646 | invalid_resource: |
647 | 647 | ||
648 | if (walk_state) { | 648 | if (walk_state) { |
649 | ACPI_ERROR((AE_INFO, | 649 | ACPI_ERROR((AE_INFO, |
@@ -652,7 +652,7 @@ acpi_ut_validate_resource(struct acpi_walk_state *walk_state, | |||
652 | } | 652 | } |
653 | return (AE_AML_INVALID_RESOURCE_TYPE); | 653 | return (AE_AML_INVALID_RESOURCE_TYPE); |
654 | 654 | ||
655 | bad_resource_length: | 655 | bad_resource_length: |
656 | 656 | ||
657 | if (walk_state) { | 657 | if (walk_state) { |
658 | ACPI_ERROR((AE_INFO, | 658 | ACPI_ERROR((AE_INFO, |
diff --git a/drivers/acpi/acpica/utstate.c b/drivers/acpi/acpica/utstate.c index a6b729d4c1dc..03c4c2febd84 100644 --- a/drivers/acpi/acpica/utstate.c +++ b/drivers/acpi/acpica/utstate.c | |||
@@ -161,7 +161,6 @@ union acpi_generic_state *acpi_ut_create_generic_state(void) | |||
161 | if (state) { | 161 | if (state) { |
162 | 162 | ||
163 | /* Initialize */ | 163 | /* Initialize */ |
164 | memset(state, 0, sizeof(union acpi_generic_state)); | ||
165 | state->common.descriptor_type = ACPI_DESC_TYPE_STATE; | 164 | state->common.descriptor_type = ACPI_DESC_TYPE_STATE; |
166 | } | 165 | } |
167 | 166 | ||
diff --git a/drivers/acpi/acpica/utstring.c b/drivers/acpi/acpica/utstring.c index cb1e9cc32d5f..45c0eb26b33d 100644 --- a/drivers/acpi/acpica/utstring.c +++ b/drivers/acpi/acpica/utstring.c | |||
@@ -310,7 +310,7 @@ acpi_status acpi_ut_strtoul64(char *string, u32 base, u64 *ret_integer) | |||
310 | 310 | ||
311 | /* All done, normal exit */ | 311 | /* All done, normal exit */ |
312 | 312 | ||
313 | all_done: | 313 | all_done: |
314 | 314 | ||
315 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Converted value: %8.8X%8.8X\n", | 315 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Converted value: %8.8X%8.8X\n", |
316 | ACPI_FORMAT_UINT64(return_value))); | 316 | ACPI_FORMAT_UINT64(return_value))); |
@@ -318,7 +318,7 @@ acpi_status acpi_ut_strtoul64(char *string, u32 base, u64 *ret_integer) | |||
318 | *ret_integer = return_value; | 318 | *ret_integer = return_value; |
319 | return_ACPI_STATUS(AE_OK); | 319 | return_ACPI_STATUS(AE_OK); |
320 | 320 | ||
321 | error_exit: | 321 | error_exit: |
322 | /* Base was set/validated above */ | 322 | /* Base was set/validated above */ |
323 | 323 | ||
324 | if (base == 10) { | 324 | if (base == 10) { |
@@ -584,3 +584,65 @@ void ut_convert_backslashes(char *pathname) | |||
584 | } | 584 | } |
585 | } | 585 | } |
586 | #endif | 586 | #endif |
587 | |||
588 | #if defined (ACPI_DEBUGGER) || defined (ACPI_APPLICATION) | ||
589 | /******************************************************************************* | ||
590 | * | ||
591 | * FUNCTION: acpi_ut_safe_strcpy, acpi_ut_safe_strcat, acpi_ut_safe_strncat | ||
592 | * | ||
593 | * PARAMETERS: Adds a "DestSize" parameter to each of the standard string | ||
594 | * functions. This is the size of the Destination buffer. | ||
595 | * | ||
596 | * RETURN: TRUE if the operation would overflow the destination buffer. | ||
597 | * | ||
598 | * DESCRIPTION: Safe versions of standard Clib string functions. Ensure that | ||
599 | * the result of the operation will not overflow the output string | ||
600 | * buffer. | ||
601 | * | ||
602 | * NOTE: These functions are typically only helpful for processing | ||
603 | * user input and command lines. For most ACPICA code, the | ||
604 | * required buffer length is precisely calculated before buffer | ||
605 | * allocation, so the use of these functions is unnecessary. | ||
606 | * | ||
607 | ******************************************************************************/ | ||
608 | |||
609 | u8 acpi_ut_safe_strcpy(char *dest, acpi_size dest_size, char *source) | ||
610 | { | ||
611 | |||
612 | if (ACPI_STRLEN(source) >= dest_size) { | ||
613 | return (TRUE); | ||
614 | } | ||
615 | |||
616 | ACPI_STRCPY(dest, source); | ||
617 | return (FALSE); | ||
618 | } | ||
619 | |||
620 | u8 acpi_ut_safe_strcat(char *dest, acpi_size dest_size, char *source) | ||
621 | { | ||
622 | |||
623 | if ((ACPI_STRLEN(dest) + ACPI_STRLEN(source)) >= dest_size) { | ||
624 | return (TRUE); | ||
625 | } | ||
626 | |||
627 | ACPI_STRCAT(dest, source); | ||
628 | return (FALSE); | ||
629 | } | ||
630 | |||
631 | u8 | ||
632 | acpi_ut_safe_strncat(char *dest, | ||
633 | acpi_size dest_size, | ||
634 | char *source, acpi_size max_transfer_length) | ||
635 | { | ||
636 | acpi_size actual_transfer_length; | ||
637 | |||
638 | actual_transfer_length = | ||
639 | ACPI_MIN(max_transfer_length, ACPI_STRLEN(source)); | ||
640 | |||
641 | if ((ACPI_STRLEN(dest) + actual_transfer_length) >= dest_size) { | ||
642 | return (TRUE); | ||
643 | } | ||
644 | |||
645 | ACPI_STRNCAT(dest, source, max_transfer_length); | ||
646 | return (FALSE); | ||
647 | } | ||
648 | #endif | ||
diff --git a/drivers/acpi/acpica/uttrack.c b/drivers/acpi/acpica/uttrack.c index 160f13f4aab5..c0027773cccb 100644 --- a/drivers/acpi/acpica/uttrack.c +++ b/drivers/acpi/acpica/uttrack.c | |||
@@ -130,10 +130,23 @@ void *acpi_ut_allocate_and_track(acpi_size size, | |||
130 | struct acpi_debug_mem_block *allocation; | 130 | struct acpi_debug_mem_block *allocation; |
131 | acpi_status status; | 131 | acpi_status status; |
132 | 132 | ||
133 | /* Check for an inadvertent size of zero bytes */ | ||
134 | |||
135 | if (!size) { | ||
136 | ACPI_WARNING((module, line, | ||
137 | "Attempt to allocate zero bytes, allocating 1 byte")); | ||
138 | size = 1; | ||
139 | } | ||
140 | |||
133 | allocation = | 141 | allocation = |
134 | acpi_ut_allocate(size + sizeof(struct acpi_debug_mem_header), | 142 | acpi_os_allocate(size + sizeof(struct acpi_debug_mem_header)); |
135 | component, module, line); | ||
136 | if (!allocation) { | 143 | if (!allocation) { |
144 | |||
145 | /* Report allocation error */ | ||
146 | |||
147 | ACPI_WARNING((module, line, | ||
148 | "Could not allocate size %u", (u32)size)); | ||
149 | |||
137 | return (NULL); | 150 | return (NULL); |
138 | } | 151 | } |
139 | 152 | ||
@@ -179,9 +192,17 @@ void *acpi_ut_allocate_zeroed_and_track(acpi_size size, | |||
179 | struct acpi_debug_mem_block *allocation; | 192 | struct acpi_debug_mem_block *allocation; |
180 | acpi_status status; | 193 | acpi_status status; |
181 | 194 | ||
195 | /* Check for an inadvertent size of zero bytes */ | ||
196 | |||
197 | if (!size) { | ||
198 | ACPI_WARNING((module, line, | ||
199 | "Attempt to allocate zero bytes, allocating 1 byte")); | ||
200 | size = 1; | ||
201 | } | ||
202 | |||
182 | allocation = | 203 | allocation = |
183 | acpi_ut_allocate_zeroed(size + sizeof(struct acpi_debug_mem_header), | 204 | acpi_os_allocate_zeroed(size + |
184 | component, module, line); | 205 | sizeof(struct acpi_debug_mem_header)); |
185 | if (!allocation) { | 206 | if (!allocation) { |
186 | 207 | ||
187 | /* Report allocation error */ | 208 | /* Report allocation error */ |
@@ -409,7 +430,7 @@ acpi_ut_track_allocation(struct acpi_debug_mem_block *allocation, | |||
409 | element->next = allocation; | 430 | element->next = allocation; |
410 | } | 431 | } |
411 | 432 | ||
412 | unlock_and_exit: | 433 | unlock_and_exit: |
413 | status = acpi_ut_release_mutex(ACPI_MTX_MEMORY); | 434 | status = acpi_ut_release_mutex(ACPI_MTX_MEMORY); |
414 | return_ACPI_STATUS(status); | 435 | return_ACPI_STATUS(status); |
415 | } | 436 | } |
diff --git a/drivers/acpi/acpica/utxface.c b/drivers/acpi/acpica/utxface.c index 03a211e6e26a..be322c83643a 100644 --- a/drivers/acpi/acpica/utxface.c +++ b/drivers/acpi/acpica/utxface.c | |||
@@ -41,7 +41,8 @@ | |||
41 | * POSSIBILITY OF SUCH DAMAGES. | 41 | * POSSIBILITY OF SUCH DAMAGES. |
42 | */ | 42 | */ |
43 | 43 | ||
44 | #include <linux/export.h> | 44 | #define EXPORT_ACPI_INTERFACES |
45 | |||
45 | #include <acpi/acpi.h> | 46 | #include <acpi/acpi.h> |
46 | #include "accommon.h" | 47 | #include "accommon.h" |
47 | #include "acdebug.h" | 48 | #include "acdebug.h" |
@@ -60,7 +61,7 @@ ACPI_MODULE_NAME("utxface") | |||
60 | * DESCRIPTION: Shutdown the ACPICA subsystem and release all resources. | 61 | * DESCRIPTION: Shutdown the ACPICA subsystem and release all resources. |
61 | * | 62 | * |
62 | ******************************************************************************/ | 63 | ******************************************************************************/ |
63 | acpi_status acpi_terminate(void) | 64 | acpi_status __init acpi_terminate(void) |
64 | { | 65 | { |
65 | acpi_status status; | 66 | acpi_status status; |
66 | 67 | ||
@@ -104,7 +105,7 @@ acpi_status acpi_terminate(void) | |||
104 | return_ACPI_STATUS(status); | 105 | return_ACPI_STATUS(status); |
105 | } | 106 | } |
106 | 107 | ||
107 | ACPI_EXPORT_SYMBOL(acpi_terminate) | 108 | ACPI_EXPORT_SYMBOL_INIT(acpi_terminate) |
108 | 109 | ||
109 | #ifndef ACPI_ASL_COMPILER | 110 | #ifndef ACPI_ASL_COMPILER |
110 | #ifdef ACPI_FUTURE_USAGE | 111 | #ifdef ACPI_FUTURE_USAGE |
@@ -207,6 +208,44 @@ acpi_status acpi_get_system_info(struct acpi_buffer * out_buffer) | |||
207 | 208 | ||
208 | ACPI_EXPORT_SYMBOL(acpi_get_system_info) | 209 | ACPI_EXPORT_SYMBOL(acpi_get_system_info) |
209 | 210 | ||
211 | /******************************************************************************* | ||
212 | * | ||
213 | * FUNCTION: acpi_get_statistics | ||
214 | * | ||
215 | * PARAMETERS: stats - Where the statistics are returned | ||
216 | * | ||
217 | * RETURN: status - the status of the call | ||
218 | * | ||
219 | * DESCRIPTION: Get the contents of the various system counters | ||
220 | * | ||
221 | ******************************************************************************/ | ||
222 | acpi_status acpi_get_statistics(struct acpi_statistics *stats) | ||
223 | { | ||
224 | ACPI_FUNCTION_TRACE(acpi_get_statistics); | ||
225 | |||
226 | /* Parameter validation */ | ||
227 | |||
228 | if (!stats) { | ||
229 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
230 | } | ||
231 | |||
232 | /* Various interrupt-based event counters */ | ||
233 | |||
234 | stats->sci_count = acpi_sci_count; | ||
235 | stats->gpe_count = acpi_gpe_count; | ||
236 | |||
237 | ACPI_MEMCPY(stats->fixed_event_count, acpi_fixed_event_count, | ||
238 | sizeof(acpi_fixed_event_count)); | ||
239 | |||
240 | /* Other counters */ | ||
241 | |||
242 | stats->method_count = acpi_method_count; | ||
243 | |||
244 | return_ACPI_STATUS(AE_OK); | ||
245 | } | ||
246 | |||
247 | ACPI_EXPORT_SYMBOL(acpi_get_statistics) | ||
248 | |||
210 | /***************************************************************************** | 249 | /***************************************************************************** |
211 | * | 250 | * |
212 | * FUNCTION: acpi_install_initialization_handler | 251 | * FUNCTION: acpi_install_initialization_handler |
diff --git a/drivers/acpi/acpica/utxferror.c b/drivers/acpi/acpica/utxferror.c index e966a2e47b76..f7edb88f6054 100644 --- a/drivers/acpi/acpica/utxferror.c +++ b/drivers/acpi/acpica/utxferror.c | |||
@@ -41,7 +41,8 @@ | |||
41 | * POSSIBILITY OF SUCH DAMAGES. | 41 | * POSSIBILITY OF SUCH DAMAGES. |
42 | */ | 42 | */ |
43 | 43 | ||
44 | #include <linux/export.h> | 44 | #define EXPORT_ACPI_INTERFACES |
45 | |||
45 | #include <acpi/acpi.h> | 46 | #include <acpi/acpi.h> |
46 | #include "accommon.h" | 47 | #include "accommon.h" |
47 | 48 | ||
diff --git a/drivers/acpi/acpica/utxfinit.c b/drivers/acpi/acpica/utxfinit.c index 41ebaaf8bb1a..75efea0539c1 100644 --- a/drivers/acpi/acpica/utxfinit.c +++ b/drivers/acpi/acpica/utxfinit.c | |||
@@ -41,7 +41,8 @@ | |||
41 | * POSSIBILITY OF SUCH DAMAGES. | 41 | * POSSIBILITY OF SUCH DAMAGES. |
42 | */ | 42 | */ |
43 | 43 | ||
44 | #include <linux/export.h> | 44 | #define EXPORT_ACPI_INTERFACES |
45 | |||
45 | #include <acpi/acpi.h> | 46 | #include <acpi/acpi.h> |
46 | #include "accommon.h" | 47 | #include "accommon.h" |
47 | #include "acevents.h" | 48 | #include "acevents.h" |
@@ -64,7 +65,7 @@ ACPI_MODULE_NAME("utxfinit") | |||
64 | * called, so any early initialization belongs here. | 65 | * called, so any early initialization belongs here. |
65 | * | 66 | * |
66 | ******************************************************************************/ | 67 | ******************************************************************************/ |
67 | acpi_status acpi_initialize_subsystem(void) | 68 | acpi_status __init acpi_initialize_subsystem(void) |
68 | { | 69 | { |
69 | acpi_status status; | 70 | acpi_status status; |
70 | 71 | ||
@@ -124,7 +125,8 @@ acpi_status acpi_initialize_subsystem(void) | |||
124 | ACPI_DEBUGGER_EXEC(status = acpi_db_initialize()); | 125 | ACPI_DEBUGGER_EXEC(status = acpi_db_initialize()); |
125 | return_ACPI_STATUS(status); | 126 | return_ACPI_STATUS(status); |
126 | } | 127 | } |
127 | ACPI_EXPORT_SYMBOL(acpi_initialize_subsystem) | 128 | |
129 | ACPI_EXPORT_SYMBOL_INIT(acpi_initialize_subsystem) | ||
128 | 130 | ||
129 | /******************************************************************************* | 131 | /******************************************************************************* |
130 | * | 132 | * |
@@ -138,7 +140,7 @@ ACPI_EXPORT_SYMBOL(acpi_initialize_subsystem) | |||
138 | * Puts system into ACPI mode if it isn't already. | 140 | * Puts system into ACPI mode if it isn't already. |
139 | * | 141 | * |
140 | ******************************************************************************/ | 142 | ******************************************************************************/ |
141 | acpi_status acpi_enable_subsystem(u32 flags) | 143 | acpi_status __init acpi_enable_subsystem(u32 flags) |
142 | { | 144 | { |
143 | acpi_status status = AE_OK; | 145 | acpi_status status = AE_OK; |
144 | 146 | ||
@@ -228,7 +230,8 @@ acpi_status acpi_enable_subsystem(u32 flags) | |||
228 | 230 | ||
229 | return_ACPI_STATUS(status); | 231 | return_ACPI_STATUS(status); |
230 | } | 232 | } |
231 | ACPI_EXPORT_SYMBOL(acpi_enable_subsystem) | 233 | |
234 | ACPI_EXPORT_SYMBOL_INIT(acpi_enable_subsystem) | ||
232 | 235 | ||
233 | /******************************************************************************* | 236 | /******************************************************************************* |
234 | * | 237 | * |
@@ -242,7 +245,7 @@ ACPI_EXPORT_SYMBOL(acpi_enable_subsystem) | |||
242 | * objects and executing AML code for Regions, buffers, etc. | 245 | * objects and executing AML code for Regions, buffers, etc. |
243 | * | 246 | * |
244 | ******************************************************************************/ | 247 | ******************************************************************************/ |
245 | acpi_status acpi_initialize_objects(u32 flags) | 248 | acpi_status __init acpi_initialize_objects(u32 flags) |
246 | { | 249 | { |
247 | acpi_status status = AE_OK; | 250 | acpi_status status = AE_OK; |
248 | 251 | ||
@@ -314,4 +317,5 @@ acpi_status acpi_initialize_objects(u32 flags) | |||
314 | acpi_gbl_startup_flags |= ACPI_INITIALIZED_OK; | 317 | acpi_gbl_startup_flags |= ACPI_INITIALIZED_OK; |
315 | return_ACPI_STATUS(status); | 318 | return_ACPI_STATUS(status); |
316 | } | 319 | } |
317 | ACPI_EXPORT_SYMBOL(acpi_initialize_objects) | 320 | |
321 | ACPI_EXPORT_SYMBOL_INIT(acpi_initialize_objects) | ||
diff --git a/drivers/acpi/apei/Kconfig b/drivers/acpi/apei/Kconfig index f0c1ce95a0ec..786294bb682c 100644 --- a/drivers/acpi/apei/Kconfig +++ b/drivers/acpi/apei/Kconfig | |||
@@ -2,6 +2,8 @@ config ACPI_APEI | |||
2 | bool "ACPI Platform Error Interface (APEI)" | 2 | bool "ACPI Platform Error Interface (APEI)" |
3 | select MISC_FILESYSTEMS | 3 | select MISC_FILESYSTEMS |
4 | select PSTORE | 4 | select PSTORE |
5 | select EFI | ||
6 | select UEFI_CPER | ||
5 | depends on X86 | 7 | depends on X86 |
6 | help | 8 | help |
7 | APEI allows to report errors (for example from the chipset) | 9 | APEI allows to report errors (for example from the chipset) |
diff --git a/drivers/acpi/apei/Makefile b/drivers/acpi/apei/Makefile index d1d1bc0a4ee1..5d575a955940 100644 --- a/drivers/acpi/apei/Makefile +++ b/drivers/acpi/apei/Makefile | |||
@@ -3,4 +3,4 @@ obj-$(CONFIG_ACPI_APEI_GHES) += ghes.o | |||
3 | obj-$(CONFIG_ACPI_APEI_EINJ) += einj.o | 3 | obj-$(CONFIG_ACPI_APEI_EINJ) += einj.o |
4 | obj-$(CONFIG_ACPI_APEI_ERST_DEBUG) += erst-dbg.o | 4 | obj-$(CONFIG_ACPI_APEI_ERST_DEBUG) += erst-dbg.o |
5 | 5 | ||
6 | apei-y := apei-base.o hest.o cper.o erst.o | 6 | apei-y := apei-base.o hest.o erst.o |
diff --git a/drivers/acpi/apei/apei-base.c b/drivers/acpi/apei/apei-base.c index 46f80e2c92f7..6d2c49b86b7f 100644 --- a/drivers/acpi/apei/apei-base.c +++ b/drivers/acpi/apei/apei-base.c | |||
@@ -758,9 +758,9 @@ int apei_osc_setup(void) | |||
758 | .cap.pointer = capbuf, | 758 | .cap.pointer = capbuf, |
759 | }; | 759 | }; |
760 | 760 | ||
761 | capbuf[OSC_QUERY_TYPE] = OSC_QUERY_ENABLE; | 761 | capbuf[OSC_QUERY_DWORD] = OSC_QUERY_ENABLE; |
762 | capbuf[OSC_SUPPORT_TYPE] = 1; | 762 | capbuf[OSC_SUPPORT_DWORD] = 1; |
763 | capbuf[OSC_CONTROL_TYPE] = 0; | 763 | capbuf[OSC_CONTROL_DWORD] = 0; |
764 | 764 | ||
765 | if (ACPI_FAILURE(acpi_get_handle(NULL, "\\_SB", &handle)) | 765 | if (ACPI_FAILURE(acpi_get_handle(NULL, "\\_SB", &handle)) |
766 | || ACPI_FAILURE(acpi_run_osc(handle, &context))) | 766 | || ACPI_FAILURE(acpi_run_osc(handle, &context))) |
diff --git a/drivers/acpi/apei/apei-internal.h b/drivers/acpi/apei/apei-internal.h index f220d642136e..21ba34a73883 100644 --- a/drivers/acpi/apei/apei-internal.h +++ b/drivers/acpi/apei/apei-internal.h | |||
@@ -122,11 +122,11 @@ struct dentry; | |||
122 | struct dentry *apei_get_debugfs_dir(void); | 122 | struct dentry *apei_get_debugfs_dir(void); |
123 | 123 | ||
124 | #define apei_estatus_for_each_section(estatus, section) \ | 124 | #define apei_estatus_for_each_section(estatus, section) \ |
125 | for (section = (struct acpi_hest_generic_data *)(estatus + 1); \ | 125 | for (section = (struct acpi_generic_data *)(estatus + 1); \ |
126 | (void *)section - (void *)estatus < estatus->data_length; \ | 126 | (void *)section - (void *)estatus < estatus->data_length; \ |
127 | section = (void *)(section+1) + section->error_data_length) | 127 | section = (void *)(section+1) + section->error_data_length) |
128 | 128 | ||
129 | static inline u32 apei_estatus_len(struct acpi_hest_generic_status *estatus) | 129 | static inline u32 cper_estatus_len(struct acpi_generic_status *estatus) |
130 | { | 130 | { |
131 | if (estatus->raw_data_length) | 131 | if (estatus->raw_data_length) |
132 | return estatus->raw_data_offset + \ | 132 | return estatus->raw_data_offset + \ |
@@ -135,10 +135,10 @@ static inline u32 apei_estatus_len(struct acpi_hest_generic_status *estatus) | |||
135 | return sizeof(*estatus) + estatus->data_length; | 135 | return sizeof(*estatus) + estatus->data_length; |
136 | } | 136 | } |
137 | 137 | ||
138 | void apei_estatus_print(const char *pfx, | 138 | void cper_estatus_print(const char *pfx, |
139 | const struct acpi_hest_generic_status *estatus); | 139 | const struct acpi_generic_status *estatus); |
140 | int apei_estatus_check_header(const struct acpi_hest_generic_status *estatus); | 140 | int cper_estatus_check_header(const struct acpi_generic_status *estatus); |
141 | int apei_estatus_check(const struct acpi_hest_generic_status *estatus); | 141 | int cper_estatus_check(const struct acpi_generic_status *estatus); |
142 | 142 | ||
143 | int apei_osc_setup(void); | 143 | int apei_osc_setup(void); |
144 | #endif | 144 | #endif |
diff --git a/drivers/acpi/apei/cper.c b/drivers/acpi/apei/cper.c deleted file mode 100644 index 33dc6a004802..000000000000 --- a/drivers/acpi/apei/cper.c +++ /dev/null | |||
@@ -1,402 +0,0 @@ | |||
1 | /* | ||
2 | * UEFI Common Platform Error Record (CPER) support | ||
3 | * | ||
4 | * Copyright (C) 2010, Intel Corp. | ||
5 | * Author: Huang Ying <ying.huang@intel.com> | ||
6 | * | ||
7 | * CPER is the format used to describe platform hardware error by | ||
8 | * various APEI tables, such as ERST, BERT and HEST etc. | ||
9 | * | ||
10 | * For more information about CPER, please refer to Appendix N of UEFI | ||
11 | * Specification version 2.3. | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or | ||
14 | * modify it under the terms of the GNU General Public License version | ||
15 | * 2 as published by the Free Software Foundation. | ||
16 | * | ||
17 | * This program is distributed in the hope that it will be useful, | ||
18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
20 | * GNU General Public License for more details. | ||
21 | * | ||
22 | * You should have received a copy of the GNU General Public License | ||
23 | * along with this program; if not, write to the Free Software | ||
24 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
25 | */ | ||
26 | |||
27 | #include <linux/kernel.h> | ||
28 | #include <linux/module.h> | ||
29 | #include <linux/time.h> | ||
30 | #include <linux/cper.h> | ||
31 | #include <linux/acpi.h> | ||
32 | #include <linux/pci.h> | ||
33 | #include <linux/aer.h> | ||
34 | |||
35 | /* | ||
36 | * CPER record ID need to be unique even after reboot, because record | ||
37 | * ID is used as index for ERST storage, while CPER records from | ||
38 | * multiple boot may co-exist in ERST. | ||
39 | */ | ||
40 | u64 cper_next_record_id(void) | ||
41 | { | ||
42 | static atomic64_t seq; | ||
43 | |||
44 | if (!atomic64_read(&seq)) | ||
45 | atomic64_set(&seq, ((u64)get_seconds()) << 32); | ||
46 | |||
47 | return atomic64_inc_return(&seq); | ||
48 | } | ||
49 | EXPORT_SYMBOL_GPL(cper_next_record_id); | ||
50 | |||
51 | static const char *cper_severity_strs[] = { | ||
52 | "recoverable", | ||
53 | "fatal", | ||
54 | "corrected", | ||
55 | "info", | ||
56 | }; | ||
57 | |||
58 | static const char *cper_severity_str(unsigned int severity) | ||
59 | { | ||
60 | return severity < ARRAY_SIZE(cper_severity_strs) ? | ||
61 | cper_severity_strs[severity] : "unknown"; | ||
62 | } | ||
63 | |||
64 | /* | ||
65 | * cper_print_bits - print strings for set bits | ||
66 | * @pfx: prefix for each line, including log level and prefix string | ||
67 | * @bits: bit mask | ||
68 | * @strs: string array, indexed by bit position | ||
69 | * @strs_size: size of the string array: @strs | ||
70 | * | ||
71 | * For each set bit in @bits, print the corresponding string in @strs. | ||
72 | * If the output length is longer than 80, multiple line will be | ||
73 | * printed, with @pfx is printed at the beginning of each line. | ||
74 | */ | ||
75 | void cper_print_bits(const char *pfx, unsigned int bits, | ||
76 | const char *strs[], unsigned int strs_size) | ||
77 | { | ||
78 | int i, len = 0; | ||
79 | const char *str; | ||
80 | char buf[84]; | ||
81 | |||
82 | for (i = 0; i < strs_size; i++) { | ||
83 | if (!(bits & (1U << i))) | ||
84 | continue; | ||
85 | str = strs[i]; | ||
86 | if (!str) | ||
87 | continue; | ||
88 | if (len && len + strlen(str) + 2 > 80) { | ||
89 | printk("%s\n", buf); | ||
90 | len = 0; | ||
91 | } | ||
92 | if (!len) | ||
93 | len = snprintf(buf, sizeof(buf), "%s%s", pfx, str); | ||
94 | else | ||
95 | len += snprintf(buf+len, sizeof(buf)-len, ", %s", str); | ||
96 | } | ||
97 | if (len) | ||
98 | printk("%s\n", buf); | ||
99 | } | ||
100 | |||
101 | static const char *cper_proc_type_strs[] = { | ||
102 | "IA32/X64", | ||
103 | "IA64", | ||
104 | }; | ||
105 | |||
106 | static const char *cper_proc_isa_strs[] = { | ||
107 | "IA32", | ||
108 | "IA64", | ||
109 | "X64", | ||
110 | }; | ||
111 | |||
112 | static const char *cper_proc_error_type_strs[] = { | ||
113 | "cache error", | ||
114 | "TLB error", | ||
115 | "bus error", | ||
116 | "micro-architectural error", | ||
117 | }; | ||
118 | |||
119 | static const char *cper_proc_op_strs[] = { | ||
120 | "unknown or generic", | ||
121 | "data read", | ||
122 | "data write", | ||
123 | "instruction execution", | ||
124 | }; | ||
125 | |||
126 | static const char *cper_proc_flag_strs[] = { | ||
127 | "restartable", | ||
128 | "precise IP", | ||
129 | "overflow", | ||
130 | "corrected", | ||
131 | }; | ||
132 | |||
133 | static void cper_print_proc_generic(const char *pfx, | ||
134 | const struct cper_sec_proc_generic *proc) | ||
135 | { | ||
136 | if (proc->validation_bits & CPER_PROC_VALID_TYPE) | ||
137 | printk("%s""processor_type: %d, %s\n", pfx, proc->proc_type, | ||
138 | proc->proc_type < ARRAY_SIZE(cper_proc_type_strs) ? | ||
139 | cper_proc_type_strs[proc->proc_type] : "unknown"); | ||
140 | if (proc->validation_bits & CPER_PROC_VALID_ISA) | ||
141 | printk("%s""processor_isa: %d, %s\n", pfx, proc->proc_isa, | ||
142 | proc->proc_isa < ARRAY_SIZE(cper_proc_isa_strs) ? | ||
143 | cper_proc_isa_strs[proc->proc_isa] : "unknown"); | ||
144 | if (proc->validation_bits & CPER_PROC_VALID_ERROR_TYPE) { | ||
145 | printk("%s""error_type: 0x%02x\n", pfx, proc->proc_error_type); | ||
146 | cper_print_bits(pfx, proc->proc_error_type, | ||
147 | cper_proc_error_type_strs, | ||
148 | ARRAY_SIZE(cper_proc_error_type_strs)); | ||
149 | } | ||
150 | if (proc->validation_bits & CPER_PROC_VALID_OPERATION) | ||
151 | printk("%s""operation: %d, %s\n", pfx, proc->operation, | ||
152 | proc->operation < ARRAY_SIZE(cper_proc_op_strs) ? | ||
153 | cper_proc_op_strs[proc->operation] : "unknown"); | ||
154 | if (proc->validation_bits & CPER_PROC_VALID_FLAGS) { | ||
155 | printk("%s""flags: 0x%02x\n", pfx, proc->flags); | ||
156 | cper_print_bits(pfx, proc->flags, cper_proc_flag_strs, | ||
157 | ARRAY_SIZE(cper_proc_flag_strs)); | ||
158 | } | ||
159 | if (proc->validation_bits & CPER_PROC_VALID_LEVEL) | ||
160 | printk("%s""level: %d\n", pfx, proc->level); | ||
161 | if (proc->validation_bits & CPER_PROC_VALID_VERSION) | ||
162 | printk("%s""version_info: 0x%016llx\n", pfx, proc->cpu_version); | ||
163 | if (proc->validation_bits & CPER_PROC_VALID_ID) | ||
164 | printk("%s""processor_id: 0x%016llx\n", pfx, proc->proc_id); | ||
165 | if (proc->validation_bits & CPER_PROC_VALID_TARGET_ADDRESS) | ||
166 | printk("%s""target_address: 0x%016llx\n", | ||
167 | pfx, proc->target_addr); | ||
168 | if (proc->validation_bits & CPER_PROC_VALID_REQUESTOR_ID) | ||
169 | printk("%s""requestor_id: 0x%016llx\n", | ||
170 | pfx, proc->requestor_id); | ||
171 | if (proc->validation_bits & CPER_PROC_VALID_RESPONDER_ID) | ||
172 | printk("%s""responder_id: 0x%016llx\n", | ||
173 | pfx, proc->responder_id); | ||
174 | if (proc->validation_bits & CPER_PROC_VALID_IP) | ||
175 | printk("%s""IP: 0x%016llx\n", pfx, proc->ip); | ||
176 | } | ||
177 | |||
178 | static const char *cper_mem_err_type_strs[] = { | ||
179 | "unknown", | ||
180 | "no error", | ||
181 | "single-bit ECC", | ||
182 | "multi-bit ECC", | ||
183 | "single-symbol chipkill ECC", | ||
184 | "multi-symbol chipkill ECC", | ||
185 | "master abort", | ||
186 | "target abort", | ||
187 | "parity error", | ||
188 | "watchdog timeout", | ||
189 | "invalid address", | ||
190 | "mirror Broken", | ||
191 | "memory sparing", | ||
192 | "scrub corrected error", | ||
193 | "scrub uncorrected error", | ||
194 | }; | ||
195 | |||
196 | static void cper_print_mem(const char *pfx, const struct cper_sec_mem_err *mem) | ||
197 | { | ||
198 | if (mem->validation_bits & CPER_MEM_VALID_ERROR_STATUS) | ||
199 | printk("%s""error_status: 0x%016llx\n", pfx, mem->error_status); | ||
200 | if (mem->validation_bits & CPER_MEM_VALID_PHYSICAL_ADDRESS) | ||
201 | printk("%s""physical_address: 0x%016llx\n", | ||
202 | pfx, mem->physical_addr); | ||
203 | if (mem->validation_bits & CPER_MEM_VALID_PHYSICAL_ADDRESS_MASK) | ||
204 | printk("%s""physical_address_mask: 0x%016llx\n", | ||
205 | pfx, mem->physical_addr_mask); | ||
206 | if (mem->validation_bits & CPER_MEM_VALID_NODE) | ||
207 | printk("%s""node: %d\n", pfx, mem->node); | ||
208 | if (mem->validation_bits & CPER_MEM_VALID_CARD) | ||
209 | printk("%s""card: %d\n", pfx, mem->card); | ||
210 | if (mem->validation_bits & CPER_MEM_VALID_MODULE) | ||
211 | printk("%s""module: %d\n", pfx, mem->module); | ||
212 | if (mem->validation_bits & CPER_MEM_VALID_BANK) | ||
213 | printk("%s""bank: %d\n", pfx, mem->bank); | ||
214 | if (mem->validation_bits & CPER_MEM_VALID_DEVICE) | ||
215 | printk("%s""device: %d\n", pfx, mem->device); | ||
216 | if (mem->validation_bits & CPER_MEM_VALID_ROW) | ||
217 | printk("%s""row: %d\n", pfx, mem->row); | ||
218 | if (mem->validation_bits & CPER_MEM_VALID_COLUMN) | ||
219 | printk("%s""column: %d\n", pfx, mem->column); | ||
220 | if (mem->validation_bits & CPER_MEM_VALID_BIT_POSITION) | ||
221 | printk("%s""bit_position: %d\n", pfx, mem->bit_pos); | ||
222 | if (mem->validation_bits & CPER_MEM_VALID_REQUESTOR_ID) | ||
223 | printk("%s""requestor_id: 0x%016llx\n", pfx, mem->requestor_id); | ||
224 | if (mem->validation_bits & CPER_MEM_VALID_RESPONDER_ID) | ||
225 | printk("%s""responder_id: 0x%016llx\n", pfx, mem->responder_id); | ||
226 | if (mem->validation_bits & CPER_MEM_VALID_TARGET_ID) | ||
227 | printk("%s""target_id: 0x%016llx\n", pfx, mem->target_id); | ||
228 | if (mem->validation_bits & CPER_MEM_VALID_ERROR_TYPE) { | ||
229 | u8 etype = mem->error_type; | ||
230 | printk("%s""error_type: %d, %s\n", pfx, etype, | ||
231 | etype < ARRAY_SIZE(cper_mem_err_type_strs) ? | ||
232 | cper_mem_err_type_strs[etype] : "unknown"); | ||
233 | } | ||
234 | } | ||
235 | |||
236 | static const char *cper_pcie_port_type_strs[] = { | ||
237 | "PCIe end point", | ||
238 | "legacy PCI end point", | ||
239 | "unknown", | ||
240 | "unknown", | ||
241 | "root port", | ||
242 | "upstream switch port", | ||
243 | "downstream switch port", | ||
244 | "PCIe to PCI/PCI-X bridge", | ||
245 | "PCI/PCI-X to PCIe bridge", | ||
246 | "root complex integrated endpoint device", | ||
247 | "root complex event collector", | ||
248 | }; | ||
249 | |||
250 | static void cper_print_pcie(const char *pfx, const struct cper_sec_pcie *pcie, | ||
251 | const struct acpi_hest_generic_data *gdata) | ||
252 | { | ||
253 | if (pcie->validation_bits & CPER_PCIE_VALID_PORT_TYPE) | ||
254 | printk("%s""port_type: %d, %s\n", pfx, pcie->port_type, | ||
255 | pcie->port_type < ARRAY_SIZE(cper_pcie_port_type_strs) ? | ||
256 | cper_pcie_port_type_strs[pcie->port_type] : "unknown"); | ||
257 | if (pcie->validation_bits & CPER_PCIE_VALID_VERSION) | ||
258 | printk("%s""version: %d.%d\n", pfx, | ||
259 | pcie->version.major, pcie->version.minor); | ||
260 | if (pcie->validation_bits & CPER_PCIE_VALID_COMMAND_STATUS) | ||
261 | printk("%s""command: 0x%04x, status: 0x%04x\n", pfx, | ||
262 | pcie->command, pcie->status); | ||
263 | if (pcie->validation_bits & CPER_PCIE_VALID_DEVICE_ID) { | ||
264 | const __u8 *p; | ||
265 | printk("%s""device_id: %04x:%02x:%02x.%x\n", pfx, | ||
266 | pcie->device_id.segment, pcie->device_id.bus, | ||
267 | pcie->device_id.device, pcie->device_id.function); | ||
268 | printk("%s""slot: %d\n", pfx, | ||
269 | pcie->device_id.slot >> CPER_PCIE_SLOT_SHIFT); | ||
270 | printk("%s""secondary_bus: 0x%02x\n", pfx, | ||
271 | pcie->device_id.secondary_bus); | ||
272 | printk("%s""vendor_id: 0x%04x, device_id: 0x%04x\n", pfx, | ||
273 | pcie->device_id.vendor_id, pcie->device_id.device_id); | ||
274 | p = pcie->device_id.class_code; | ||
275 | printk("%s""class_code: %02x%02x%02x\n", pfx, p[0], p[1], p[2]); | ||
276 | } | ||
277 | if (pcie->validation_bits & CPER_PCIE_VALID_SERIAL_NUMBER) | ||
278 | printk("%s""serial number: 0x%04x, 0x%04x\n", pfx, | ||
279 | pcie->serial_number.lower, pcie->serial_number.upper); | ||
280 | if (pcie->validation_bits & CPER_PCIE_VALID_BRIDGE_CONTROL_STATUS) | ||
281 | printk( | ||
282 | "%s""bridge: secondary_status: 0x%04x, control: 0x%04x\n", | ||
283 | pfx, pcie->bridge.secondary_status, pcie->bridge.control); | ||
284 | } | ||
285 | |||
286 | static const char *apei_estatus_section_flag_strs[] = { | ||
287 | "primary", | ||
288 | "containment warning", | ||
289 | "reset", | ||
290 | "threshold exceeded", | ||
291 | "resource not accessible", | ||
292 | "latent error", | ||
293 | }; | ||
294 | |||
295 | static void apei_estatus_print_section( | ||
296 | const char *pfx, const struct acpi_hest_generic_data *gdata, int sec_no) | ||
297 | { | ||
298 | uuid_le *sec_type = (uuid_le *)gdata->section_type; | ||
299 | __u16 severity; | ||
300 | |||
301 | severity = gdata->error_severity; | ||
302 | printk("%s""section: %d, severity: %d, %s\n", pfx, sec_no, severity, | ||
303 | cper_severity_str(severity)); | ||
304 | printk("%s""flags: 0x%02x\n", pfx, gdata->flags); | ||
305 | cper_print_bits(pfx, gdata->flags, apei_estatus_section_flag_strs, | ||
306 | ARRAY_SIZE(apei_estatus_section_flag_strs)); | ||
307 | if (gdata->validation_bits & CPER_SEC_VALID_FRU_ID) | ||
308 | printk("%s""fru_id: %pUl\n", pfx, (uuid_le *)gdata->fru_id); | ||
309 | if (gdata->validation_bits & CPER_SEC_VALID_FRU_TEXT) | ||
310 | printk("%s""fru_text: %.20s\n", pfx, gdata->fru_text); | ||
311 | |||
312 | if (!uuid_le_cmp(*sec_type, CPER_SEC_PROC_GENERIC)) { | ||
313 | struct cper_sec_proc_generic *proc_err = (void *)(gdata + 1); | ||
314 | printk("%s""section_type: general processor error\n", pfx); | ||
315 | if (gdata->error_data_length >= sizeof(*proc_err)) | ||
316 | cper_print_proc_generic(pfx, proc_err); | ||
317 | else | ||
318 | goto err_section_too_small; | ||
319 | } else if (!uuid_le_cmp(*sec_type, CPER_SEC_PLATFORM_MEM)) { | ||
320 | struct cper_sec_mem_err *mem_err = (void *)(gdata + 1); | ||
321 | printk("%s""section_type: memory error\n", pfx); | ||
322 | if (gdata->error_data_length >= sizeof(*mem_err)) | ||
323 | cper_print_mem(pfx, mem_err); | ||
324 | else | ||
325 | goto err_section_too_small; | ||
326 | } else if (!uuid_le_cmp(*sec_type, CPER_SEC_PCIE)) { | ||
327 | struct cper_sec_pcie *pcie = (void *)(gdata + 1); | ||
328 | printk("%s""section_type: PCIe error\n", pfx); | ||
329 | if (gdata->error_data_length >= sizeof(*pcie)) | ||
330 | cper_print_pcie(pfx, pcie, gdata); | ||
331 | else | ||
332 | goto err_section_too_small; | ||
333 | } else | ||
334 | printk("%s""section type: unknown, %pUl\n", pfx, sec_type); | ||
335 | |||
336 | return; | ||
337 | |||
338 | err_section_too_small: | ||
339 | pr_err(FW_WARN "error section length is too small\n"); | ||
340 | } | ||
341 | |||
342 | void apei_estatus_print(const char *pfx, | ||
343 | const struct acpi_hest_generic_status *estatus) | ||
344 | { | ||
345 | struct acpi_hest_generic_data *gdata; | ||
346 | unsigned int data_len, gedata_len; | ||
347 | int sec_no = 0; | ||
348 | __u16 severity; | ||
349 | |||
350 | printk("%s""APEI generic hardware error status\n", pfx); | ||
351 | severity = estatus->error_severity; | ||
352 | printk("%s""severity: %d, %s\n", pfx, severity, | ||
353 | cper_severity_str(severity)); | ||
354 | data_len = estatus->data_length; | ||
355 | gdata = (struct acpi_hest_generic_data *)(estatus + 1); | ||
356 | while (data_len > sizeof(*gdata)) { | ||
357 | gedata_len = gdata->error_data_length; | ||
358 | apei_estatus_print_section(pfx, gdata, sec_no); | ||
359 | data_len -= gedata_len + sizeof(*gdata); | ||
360 | gdata = (void *)(gdata + 1) + gedata_len; | ||
361 | sec_no++; | ||
362 | } | ||
363 | } | ||
364 | EXPORT_SYMBOL_GPL(apei_estatus_print); | ||
365 | |||
366 | int apei_estatus_check_header(const struct acpi_hest_generic_status *estatus) | ||
367 | { | ||
368 | if (estatus->data_length && | ||
369 | estatus->data_length < sizeof(struct acpi_hest_generic_data)) | ||
370 | return -EINVAL; | ||
371 | if (estatus->raw_data_length && | ||
372 | estatus->raw_data_offset < sizeof(*estatus) + estatus->data_length) | ||
373 | return -EINVAL; | ||
374 | |||
375 | return 0; | ||
376 | } | ||
377 | EXPORT_SYMBOL_GPL(apei_estatus_check_header); | ||
378 | |||
379 | int apei_estatus_check(const struct acpi_hest_generic_status *estatus) | ||
380 | { | ||
381 | struct acpi_hest_generic_data *gdata; | ||
382 | unsigned int data_len, gedata_len; | ||
383 | int rc; | ||
384 | |||
385 | rc = apei_estatus_check_header(estatus); | ||
386 | if (rc) | ||
387 | return rc; | ||
388 | data_len = estatus->data_length; | ||
389 | gdata = (struct acpi_hest_generic_data *)(estatus + 1); | ||
390 | while (data_len >= sizeof(*gdata)) { | ||
391 | gedata_len = gdata->error_data_length; | ||
392 | if (gedata_len > data_len - sizeof(*gdata)) | ||
393 | return -EINVAL; | ||
394 | data_len -= gedata_len + sizeof(*gdata); | ||
395 | gdata = (void *)(gdata + 1) + gedata_len; | ||
396 | } | ||
397 | if (data_len) | ||
398 | return -EINVAL; | ||
399 | |||
400 | return 0; | ||
401 | } | ||
402 | EXPORT_SYMBOL_GPL(apei_estatus_check); | ||
diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index 8ec37bbdd699..a30bc313787b 100644 --- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c | |||
@@ -75,13 +75,13 @@ | |||
75 | #define GHES_ESTATUS_CACHE_LEN(estatus_len) \ | 75 | #define GHES_ESTATUS_CACHE_LEN(estatus_len) \ |
76 | (sizeof(struct ghes_estatus_cache) + (estatus_len)) | 76 | (sizeof(struct ghes_estatus_cache) + (estatus_len)) |
77 | #define GHES_ESTATUS_FROM_CACHE(estatus_cache) \ | 77 | #define GHES_ESTATUS_FROM_CACHE(estatus_cache) \ |
78 | ((struct acpi_hest_generic_status *) \ | 78 | ((struct acpi_generic_status *) \ |
79 | ((struct ghes_estatus_cache *)(estatus_cache) + 1)) | 79 | ((struct ghes_estatus_cache *)(estatus_cache) + 1)) |
80 | 80 | ||
81 | #define GHES_ESTATUS_NODE_LEN(estatus_len) \ | 81 | #define GHES_ESTATUS_NODE_LEN(estatus_len) \ |
82 | (sizeof(struct ghes_estatus_node) + (estatus_len)) | 82 | (sizeof(struct ghes_estatus_node) + (estatus_len)) |
83 | #define GHES_ESTATUS_FROM_NODE(estatus_node) \ | 83 | #define GHES_ESTATUS_FROM_NODE(estatus_node) \ |
84 | ((struct acpi_hest_generic_status *) \ | 84 | ((struct acpi_generic_status *) \ |
85 | ((struct ghes_estatus_node *)(estatus_node) + 1)) | 85 | ((struct ghes_estatus_node *)(estatus_node) + 1)) |
86 | 86 | ||
87 | bool ghes_disable; | 87 | bool ghes_disable; |
@@ -378,17 +378,17 @@ static int ghes_read_estatus(struct ghes *ghes, int silent) | |||
378 | ghes->flags |= GHES_TO_CLEAR; | 378 | ghes->flags |= GHES_TO_CLEAR; |
379 | 379 | ||
380 | rc = -EIO; | 380 | rc = -EIO; |
381 | len = apei_estatus_len(ghes->estatus); | 381 | len = cper_estatus_len(ghes->estatus); |
382 | if (len < sizeof(*ghes->estatus)) | 382 | if (len < sizeof(*ghes->estatus)) |
383 | goto err_read_block; | 383 | goto err_read_block; |
384 | if (len > ghes->generic->error_block_length) | 384 | if (len > ghes->generic->error_block_length) |
385 | goto err_read_block; | 385 | goto err_read_block; |
386 | if (apei_estatus_check_header(ghes->estatus)) | 386 | if (cper_estatus_check_header(ghes->estatus)) |
387 | goto err_read_block; | 387 | goto err_read_block; |
388 | ghes_copy_tofrom_phys(ghes->estatus + 1, | 388 | ghes_copy_tofrom_phys(ghes->estatus + 1, |
389 | buf_paddr + sizeof(*ghes->estatus), | 389 | buf_paddr + sizeof(*ghes->estatus), |
390 | len - sizeof(*ghes->estatus), 1); | 390 | len - sizeof(*ghes->estatus), 1); |
391 | if (apei_estatus_check(ghes->estatus)) | 391 | if (cper_estatus_check(ghes->estatus)) |
392 | goto err_read_block; | 392 | goto err_read_block; |
393 | rc = 0; | 393 | rc = 0; |
394 | 394 | ||
@@ -409,7 +409,7 @@ static void ghes_clear_estatus(struct ghes *ghes) | |||
409 | ghes->flags &= ~GHES_TO_CLEAR; | 409 | ghes->flags &= ~GHES_TO_CLEAR; |
410 | } | 410 | } |
411 | 411 | ||
412 | static void ghes_handle_memory_failure(struct acpi_hest_generic_data *gdata, int sev) | 412 | static void ghes_handle_memory_failure(struct acpi_generic_data *gdata, int sev) |
413 | { | 413 | { |
414 | #ifdef CONFIG_ACPI_APEI_MEMORY_FAILURE | 414 | #ifdef CONFIG_ACPI_APEI_MEMORY_FAILURE |
415 | unsigned long pfn; | 415 | unsigned long pfn; |
@@ -419,7 +419,7 @@ static void ghes_handle_memory_failure(struct acpi_hest_generic_data *gdata, int | |||
419 | 419 | ||
420 | if (sec_sev == GHES_SEV_CORRECTED && | 420 | if (sec_sev == GHES_SEV_CORRECTED && |
421 | (gdata->flags & CPER_SEC_ERROR_THRESHOLD_EXCEEDED) && | 421 | (gdata->flags & CPER_SEC_ERROR_THRESHOLD_EXCEEDED) && |
422 | (mem_err->validation_bits & CPER_MEM_VALID_PHYSICAL_ADDRESS)) { | 422 | (mem_err->validation_bits & CPER_MEM_VALID_PA)) { |
423 | pfn = mem_err->physical_addr >> PAGE_SHIFT; | 423 | pfn = mem_err->physical_addr >> PAGE_SHIFT; |
424 | if (pfn_valid(pfn)) | 424 | if (pfn_valid(pfn)) |
425 | memory_failure_queue(pfn, 0, MF_SOFT_OFFLINE); | 425 | memory_failure_queue(pfn, 0, MF_SOFT_OFFLINE); |
@@ -430,7 +430,7 @@ static void ghes_handle_memory_failure(struct acpi_hest_generic_data *gdata, int | |||
430 | } | 430 | } |
431 | if (sev == GHES_SEV_RECOVERABLE && | 431 | if (sev == GHES_SEV_RECOVERABLE && |
432 | sec_sev == GHES_SEV_RECOVERABLE && | 432 | sec_sev == GHES_SEV_RECOVERABLE && |
433 | mem_err->validation_bits & CPER_MEM_VALID_PHYSICAL_ADDRESS) { | 433 | mem_err->validation_bits & CPER_MEM_VALID_PA) { |
434 | pfn = mem_err->physical_addr >> PAGE_SHIFT; | 434 | pfn = mem_err->physical_addr >> PAGE_SHIFT; |
435 | memory_failure_queue(pfn, 0, 0); | 435 | memory_failure_queue(pfn, 0, 0); |
436 | } | 436 | } |
@@ -438,10 +438,10 @@ static void ghes_handle_memory_failure(struct acpi_hest_generic_data *gdata, int | |||
438 | } | 438 | } |
439 | 439 | ||
440 | static void ghes_do_proc(struct ghes *ghes, | 440 | static void ghes_do_proc(struct ghes *ghes, |
441 | const struct acpi_hest_generic_status *estatus) | 441 | const struct acpi_generic_status *estatus) |
442 | { | 442 | { |
443 | int sev, sec_sev; | 443 | int sev, sec_sev; |
444 | struct acpi_hest_generic_data *gdata; | 444 | struct acpi_generic_data *gdata; |
445 | 445 | ||
446 | sev = ghes_severity(estatus->error_severity); | 446 | sev = ghes_severity(estatus->error_severity); |
447 | apei_estatus_for_each_section(estatus, gdata) { | 447 | apei_estatus_for_each_section(estatus, gdata) { |
@@ -496,7 +496,7 @@ static void ghes_do_proc(struct ghes *ghes, | |||
496 | 496 | ||
497 | static void __ghes_print_estatus(const char *pfx, | 497 | static void __ghes_print_estatus(const char *pfx, |
498 | const struct acpi_hest_generic *generic, | 498 | const struct acpi_hest_generic *generic, |
499 | const struct acpi_hest_generic_status *estatus) | 499 | const struct acpi_generic_status *estatus) |
500 | { | 500 | { |
501 | static atomic_t seqno; | 501 | static atomic_t seqno; |
502 | unsigned int curr_seqno; | 502 | unsigned int curr_seqno; |
@@ -513,12 +513,12 @@ static void __ghes_print_estatus(const char *pfx, | |||
513 | snprintf(pfx_seq, sizeof(pfx_seq), "%s{%u}" HW_ERR, pfx, curr_seqno); | 513 | snprintf(pfx_seq, sizeof(pfx_seq), "%s{%u}" HW_ERR, pfx, curr_seqno); |
514 | printk("%s""Hardware error from APEI Generic Hardware Error Source: %d\n", | 514 | printk("%s""Hardware error from APEI Generic Hardware Error Source: %d\n", |
515 | pfx_seq, generic->header.source_id); | 515 | pfx_seq, generic->header.source_id); |
516 | apei_estatus_print(pfx_seq, estatus); | 516 | cper_estatus_print(pfx_seq, estatus); |
517 | } | 517 | } |
518 | 518 | ||
519 | static int ghes_print_estatus(const char *pfx, | 519 | static int ghes_print_estatus(const char *pfx, |
520 | const struct acpi_hest_generic *generic, | 520 | const struct acpi_hest_generic *generic, |
521 | const struct acpi_hest_generic_status *estatus) | 521 | const struct acpi_generic_status *estatus) |
522 | { | 522 | { |
523 | /* Not more than 2 messages every 5 seconds */ | 523 | /* Not more than 2 messages every 5 seconds */ |
524 | static DEFINE_RATELIMIT_STATE(ratelimit_corrected, 5*HZ, 2); | 524 | static DEFINE_RATELIMIT_STATE(ratelimit_corrected, 5*HZ, 2); |
@@ -540,15 +540,15 @@ static int ghes_print_estatus(const char *pfx, | |||
540 | * GHES error status reporting throttle, to report more kinds of | 540 | * GHES error status reporting throttle, to report more kinds of |
541 | * errors, instead of just most frequently occurred errors. | 541 | * errors, instead of just most frequently occurred errors. |
542 | */ | 542 | */ |
543 | static int ghes_estatus_cached(struct acpi_hest_generic_status *estatus) | 543 | static int ghes_estatus_cached(struct acpi_generic_status *estatus) |
544 | { | 544 | { |
545 | u32 len; | 545 | u32 len; |
546 | int i, cached = 0; | 546 | int i, cached = 0; |
547 | unsigned long long now; | 547 | unsigned long long now; |
548 | struct ghes_estatus_cache *cache; | 548 | struct ghes_estatus_cache *cache; |
549 | struct acpi_hest_generic_status *cache_estatus; | 549 | struct acpi_generic_status *cache_estatus; |
550 | 550 | ||
551 | len = apei_estatus_len(estatus); | 551 | len = cper_estatus_len(estatus); |
552 | rcu_read_lock(); | 552 | rcu_read_lock(); |
553 | for (i = 0; i < GHES_ESTATUS_CACHES_SIZE; i++) { | 553 | for (i = 0; i < GHES_ESTATUS_CACHES_SIZE; i++) { |
554 | cache = rcu_dereference(ghes_estatus_caches[i]); | 554 | cache = rcu_dereference(ghes_estatus_caches[i]); |
@@ -571,19 +571,19 @@ static int ghes_estatus_cached(struct acpi_hest_generic_status *estatus) | |||
571 | 571 | ||
572 | static struct ghes_estatus_cache *ghes_estatus_cache_alloc( | 572 | static struct ghes_estatus_cache *ghes_estatus_cache_alloc( |
573 | struct acpi_hest_generic *generic, | 573 | struct acpi_hest_generic *generic, |
574 | struct acpi_hest_generic_status *estatus) | 574 | struct acpi_generic_status *estatus) |
575 | { | 575 | { |
576 | int alloced; | 576 | int alloced; |
577 | u32 len, cache_len; | 577 | u32 len, cache_len; |
578 | struct ghes_estatus_cache *cache; | 578 | struct ghes_estatus_cache *cache; |
579 | struct acpi_hest_generic_status *cache_estatus; | 579 | struct acpi_generic_status *cache_estatus; |
580 | 580 | ||
581 | alloced = atomic_add_return(1, &ghes_estatus_cache_alloced); | 581 | alloced = atomic_add_return(1, &ghes_estatus_cache_alloced); |
582 | if (alloced > GHES_ESTATUS_CACHE_ALLOCED_MAX) { | 582 | if (alloced > GHES_ESTATUS_CACHE_ALLOCED_MAX) { |
583 | atomic_dec(&ghes_estatus_cache_alloced); | 583 | atomic_dec(&ghes_estatus_cache_alloced); |
584 | return NULL; | 584 | return NULL; |
585 | } | 585 | } |
586 | len = apei_estatus_len(estatus); | 586 | len = cper_estatus_len(estatus); |
587 | cache_len = GHES_ESTATUS_CACHE_LEN(len); | 587 | cache_len = GHES_ESTATUS_CACHE_LEN(len); |
588 | cache = (void *)gen_pool_alloc(ghes_estatus_pool, cache_len); | 588 | cache = (void *)gen_pool_alloc(ghes_estatus_pool, cache_len); |
589 | if (!cache) { | 589 | if (!cache) { |
@@ -603,7 +603,7 @@ static void ghes_estatus_cache_free(struct ghes_estatus_cache *cache) | |||
603 | { | 603 | { |
604 | u32 len; | 604 | u32 len; |
605 | 605 | ||
606 | len = apei_estatus_len(GHES_ESTATUS_FROM_CACHE(cache)); | 606 | len = cper_estatus_len(GHES_ESTATUS_FROM_CACHE(cache)); |
607 | len = GHES_ESTATUS_CACHE_LEN(len); | 607 | len = GHES_ESTATUS_CACHE_LEN(len); |
608 | gen_pool_free(ghes_estatus_pool, (unsigned long)cache, len); | 608 | gen_pool_free(ghes_estatus_pool, (unsigned long)cache, len); |
609 | atomic_dec(&ghes_estatus_cache_alloced); | 609 | atomic_dec(&ghes_estatus_cache_alloced); |
@@ -619,7 +619,7 @@ static void ghes_estatus_cache_rcu_free(struct rcu_head *head) | |||
619 | 619 | ||
620 | static void ghes_estatus_cache_add( | 620 | static void ghes_estatus_cache_add( |
621 | struct acpi_hest_generic *generic, | 621 | struct acpi_hest_generic *generic, |
622 | struct acpi_hest_generic_status *estatus) | 622 | struct acpi_generic_status *estatus) |
623 | { | 623 | { |
624 | int i, slot = -1, count; | 624 | int i, slot = -1, count; |
625 | unsigned long long now, duration, period, max_period = 0; | 625 | unsigned long long now, duration, period, max_period = 0; |
@@ -751,7 +751,7 @@ static void ghes_proc_in_irq(struct irq_work *irq_work) | |||
751 | struct llist_node *llnode, *next; | 751 | struct llist_node *llnode, *next; |
752 | struct ghes_estatus_node *estatus_node; | 752 | struct ghes_estatus_node *estatus_node; |
753 | struct acpi_hest_generic *generic; | 753 | struct acpi_hest_generic *generic; |
754 | struct acpi_hest_generic_status *estatus; | 754 | struct acpi_generic_status *estatus; |
755 | u32 len, node_len; | 755 | u32 len, node_len; |
756 | 756 | ||
757 | llnode = llist_del_all(&ghes_estatus_llist); | 757 | llnode = llist_del_all(&ghes_estatus_llist); |
@@ -765,7 +765,7 @@ static void ghes_proc_in_irq(struct irq_work *irq_work) | |||
765 | estatus_node = llist_entry(llnode, struct ghes_estatus_node, | 765 | estatus_node = llist_entry(llnode, struct ghes_estatus_node, |
766 | llnode); | 766 | llnode); |
767 | estatus = GHES_ESTATUS_FROM_NODE(estatus_node); | 767 | estatus = GHES_ESTATUS_FROM_NODE(estatus_node); |
768 | len = apei_estatus_len(estatus); | 768 | len = cper_estatus_len(estatus); |
769 | node_len = GHES_ESTATUS_NODE_LEN(len); | 769 | node_len = GHES_ESTATUS_NODE_LEN(len); |
770 | ghes_do_proc(estatus_node->ghes, estatus); | 770 | ghes_do_proc(estatus_node->ghes, estatus); |
771 | if (!ghes_estatus_cached(estatus)) { | 771 | if (!ghes_estatus_cached(estatus)) { |
@@ -784,7 +784,7 @@ static void ghes_print_queued_estatus(void) | |||
784 | struct llist_node *llnode; | 784 | struct llist_node *llnode; |
785 | struct ghes_estatus_node *estatus_node; | 785 | struct ghes_estatus_node *estatus_node; |
786 | struct acpi_hest_generic *generic; | 786 | struct acpi_hest_generic *generic; |
787 | struct acpi_hest_generic_status *estatus; | 787 | struct acpi_generic_status *estatus; |
788 | u32 len, node_len; | 788 | u32 len, node_len; |
789 | 789 | ||
790 | llnode = llist_del_all(&ghes_estatus_llist); | 790 | llnode = llist_del_all(&ghes_estatus_llist); |
@@ -797,7 +797,7 @@ static void ghes_print_queued_estatus(void) | |||
797 | estatus_node = llist_entry(llnode, struct ghes_estatus_node, | 797 | estatus_node = llist_entry(llnode, struct ghes_estatus_node, |
798 | llnode); | 798 | llnode); |
799 | estatus = GHES_ESTATUS_FROM_NODE(estatus_node); | 799 | estatus = GHES_ESTATUS_FROM_NODE(estatus_node); |
800 | len = apei_estatus_len(estatus); | 800 | len = cper_estatus_len(estatus); |
801 | node_len = GHES_ESTATUS_NODE_LEN(len); | 801 | node_len = GHES_ESTATUS_NODE_LEN(len); |
802 | generic = estatus_node->generic; | 802 | generic = estatus_node->generic; |
803 | ghes_print_estatus(NULL, generic, estatus); | 803 | ghes_print_estatus(NULL, generic, estatus); |
@@ -843,7 +843,7 @@ static int ghes_notify_nmi(unsigned int cmd, struct pt_regs *regs) | |||
843 | #ifdef CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG | 843 | #ifdef CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG |
844 | u32 len, node_len; | 844 | u32 len, node_len; |
845 | struct ghes_estatus_node *estatus_node; | 845 | struct ghes_estatus_node *estatus_node; |
846 | struct acpi_hest_generic_status *estatus; | 846 | struct acpi_generic_status *estatus; |
847 | #endif | 847 | #endif |
848 | if (!(ghes->flags & GHES_TO_CLEAR)) | 848 | if (!(ghes->flags & GHES_TO_CLEAR)) |
849 | continue; | 849 | continue; |
@@ -851,7 +851,7 @@ static int ghes_notify_nmi(unsigned int cmd, struct pt_regs *regs) | |||
851 | if (ghes_estatus_cached(ghes->estatus)) | 851 | if (ghes_estatus_cached(ghes->estatus)) |
852 | goto next; | 852 | goto next; |
853 | /* Save estatus for further processing in IRQ context */ | 853 | /* Save estatus for further processing in IRQ context */ |
854 | len = apei_estatus_len(ghes->estatus); | 854 | len = cper_estatus_len(ghes->estatus); |
855 | node_len = GHES_ESTATUS_NODE_LEN(len); | 855 | node_len = GHES_ESTATUS_NODE_LEN(len); |
856 | estatus_node = (void *)gen_pool_alloc(ghes_estatus_pool, | 856 | estatus_node = (void *)gen_pool_alloc(ghes_estatus_pool, |
857 | node_len); | 857 | node_len); |
@@ -923,7 +923,7 @@ static int ghes_probe(struct platform_device *ghes_dev) | |||
923 | 923 | ||
924 | rc = -EIO; | 924 | rc = -EIO; |
925 | if (generic->error_block_length < | 925 | if (generic->error_block_length < |
926 | sizeof(struct acpi_hest_generic_status)) { | 926 | sizeof(struct acpi_generic_status)) { |
927 | pr_warning(FW_BUG GHES_PFX "Invalid error block length: %u for generic hardware error source: %d\n", | 927 | pr_warning(FW_BUG GHES_PFX "Invalid error block length: %u for generic hardware error source: %d\n", |
928 | generic->error_block_length, | 928 | generic->error_block_length, |
929 | generic->header.source_id); | 929 | generic->header.source_id); |
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 2c9958cd7a43..fbf1aceda8b8 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c | |||
@@ -36,12 +36,6 @@ | |||
36 | #include <linux/suspend.h> | 36 | #include <linux/suspend.h> |
37 | #include <asm/unaligned.h> | 37 | #include <asm/unaligned.h> |
38 | 38 | ||
39 | #ifdef CONFIG_ACPI_PROCFS_POWER | ||
40 | #include <linux/proc_fs.h> | ||
41 | #include <linux/seq_file.h> | ||
42 | #include <asm/uaccess.h> | ||
43 | #endif | ||
44 | |||
45 | #include <acpi/acpi_bus.h> | 39 | #include <acpi/acpi_bus.h> |
46 | #include <acpi/acpi_drivers.h> | 40 | #include <acpi/acpi_drivers.h> |
47 | #include <linux/power_supply.h> | 41 | #include <linux/power_supply.h> |
@@ -72,19 +66,6 @@ static unsigned int cache_time = 1000; | |||
72 | module_param(cache_time, uint, 0644); | 66 | module_param(cache_time, uint, 0644); |
73 | MODULE_PARM_DESC(cache_time, "cache time in milliseconds"); | 67 | MODULE_PARM_DESC(cache_time, "cache time in milliseconds"); |
74 | 68 | ||
75 | #ifdef CONFIG_ACPI_PROCFS_POWER | ||
76 | extern struct proc_dir_entry *acpi_lock_battery_dir(void); | ||
77 | extern void *acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir); | ||
78 | |||
79 | enum acpi_battery_files { | ||
80 | info_tag = 0, | ||
81 | state_tag, | ||
82 | alarm_tag, | ||
83 | ACPI_BATTERY_NUMFILES, | ||
84 | }; | ||
85 | |||
86 | #endif | ||
87 | |||
88 | static const struct acpi_device_id battery_device_ids[] = { | 69 | static const struct acpi_device_id battery_device_ids[] = { |
89 | {"PNP0C0A", 0}, | 70 | {"PNP0C0A", 0}, |
90 | {"", 0}, | 71 | {"", 0}, |
@@ -320,14 +301,6 @@ static enum power_supply_property energy_battery_props[] = { | |||
320 | POWER_SUPPLY_PROP_SERIAL_NUMBER, | 301 | POWER_SUPPLY_PROP_SERIAL_NUMBER, |
321 | }; | 302 | }; |
322 | 303 | ||
323 | #ifdef CONFIG_ACPI_PROCFS_POWER | ||
324 | inline char *acpi_battery_units(struct acpi_battery *battery) | ||
325 | { | ||
326 | return (battery->power_unit == ACPI_BATTERY_POWER_UNIT_MA) ? | ||
327 | "mA" : "mW"; | ||
328 | } | ||
329 | #endif | ||
330 | |||
331 | /* -------------------------------------------------------------------------- | 304 | /* -------------------------------------------------------------------------- |
332 | Battery Management | 305 | Battery Management |
333 | -------------------------------------------------------------------------- */ | 306 | -------------------------------------------------------------------------- */ |
@@ -741,279 +714,6 @@ static void acpi_battery_refresh(struct acpi_battery *battery) | |||
741 | } | 714 | } |
742 | 715 | ||
743 | /* -------------------------------------------------------------------------- | 716 | /* -------------------------------------------------------------------------- |
744 | FS Interface (/proc) | ||
745 | -------------------------------------------------------------------------- */ | ||
746 | |||
747 | #ifdef CONFIG_ACPI_PROCFS_POWER | ||
748 | static struct proc_dir_entry *acpi_battery_dir; | ||
749 | |||
750 | static int acpi_battery_print_info(struct seq_file *seq, int result) | ||
751 | { | ||
752 | struct acpi_battery *battery = seq->private; | ||
753 | |||
754 | if (result) | ||
755 | goto end; | ||
756 | |||
757 | seq_printf(seq, "present: %s\n", | ||
758 | acpi_battery_present(battery) ? "yes" : "no"); | ||
759 | if (!acpi_battery_present(battery)) | ||
760 | goto end; | ||
761 | if (battery->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN) | ||
762 | seq_printf(seq, "design capacity: unknown\n"); | ||
763 | else | ||
764 | seq_printf(seq, "design capacity: %d %sh\n", | ||
765 | battery->design_capacity, | ||
766 | acpi_battery_units(battery)); | ||
767 | |||
768 | if (battery->full_charge_capacity == ACPI_BATTERY_VALUE_UNKNOWN) | ||
769 | seq_printf(seq, "last full capacity: unknown\n"); | ||
770 | else | ||
771 | seq_printf(seq, "last full capacity: %d %sh\n", | ||
772 | battery->full_charge_capacity, | ||
773 | acpi_battery_units(battery)); | ||
774 | |||
775 | seq_printf(seq, "battery technology: %srechargeable\n", | ||
776 | (!battery->technology)?"non-":""); | ||
777 | |||
778 | if (battery->design_voltage == ACPI_BATTERY_VALUE_UNKNOWN) | ||
779 | seq_printf(seq, "design voltage: unknown\n"); | ||
780 | else | ||
781 | seq_printf(seq, "design voltage: %d mV\n", | ||
782 | battery->design_voltage); | ||
783 | seq_printf(seq, "design capacity warning: %d %sh\n", | ||
784 | battery->design_capacity_warning, | ||
785 | acpi_battery_units(battery)); | ||
786 | seq_printf(seq, "design capacity low: %d %sh\n", | ||
787 | battery->design_capacity_low, | ||
788 | acpi_battery_units(battery)); | ||
789 | seq_printf(seq, "cycle count: %i\n", battery->cycle_count); | ||
790 | seq_printf(seq, "capacity granularity 1: %d %sh\n", | ||
791 | battery->capacity_granularity_1, | ||
792 | acpi_battery_units(battery)); | ||
793 | seq_printf(seq, "capacity granularity 2: %d %sh\n", | ||
794 | battery->capacity_granularity_2, | ||
795 | acpi_battery_units(battery)); | ||
796 | seq_printf(seq, "model number: %s\n", battery->model_number); | ||
797 | seq_printf(seq, "serial number: %s\n", battery->serial_number); | ||
798 | seq_printf(seq, "battery type: %s\n", battery->type); | ||
799 | seq_printf(seq, "OEM info: %s\n", battery->oem_info); | ||
800 | end: | ||
801 | if (result) | ||
802 | seq_printf(seq, "ERROR: Unable to read battery info\n"); | ||
803 | return result; | ||
804 | } | ||
805 | |||
806 | static int acpi_battery_print_state(struct seq_file *seq, int result) | ||
807 | { | ||
808 | struct acpi_battery *battery = seq->private; | ||
809 | |||
810 | if (result) | ||
811 | goto end; | ||
812 | |||
813 | seq_printf(seq, "present: %s\n", | ||
814 | acpi_battery_present(battery) ? "yes" : "no"); | ||
815 | if (!acpi_battery_present(battery)) | ||
816 | goto end; | ||
817 | |||
818 | seq_printf(seq, "capacity state: %s\n", | ||
819 | (battery->state & 0x04) ? "critical" : "ok"); | ||
820 | if ((battery->state & 0x01) && (battery->state & 0x02)) | ||
821 | seq_printf(seq, | ||
822 | "charging state: charging/discharging\n"); | ||
823 | else if (battery->state & 0x01) | ||
824 | seq_printf(seq, "charging state: discharging\n"); | ||
825 | else if (battery->state & 0x02) | ||
826 | seq_printf(seq, "charging state: charging\n"); | ||
827 | else | ||
828 | seq_printf(seq, "charging state: charged\n"); | ||
829 | |||
830 | if (battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN) | ||
831 | seq_printf(seq, "present rate: unknown\n"); | ||
832 | else | ||
833 | seq_printf(seq, "present rate: %d %s\n", | ||
834 | battery->rate_now, acpi_battery_units(battery)); | ||
835 | |||
836 | if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN) | ||
837 | seq_printf(seq, "remaining capacity: unknown\n"); | ||
838 | else | ||
839 | seq_printf(seq, "remaining capacity: %d %sh\n", | ||
840 | battery->capacity_now, acpi_battery_units(battery)); | ||
841 | if (battery->voltage_now == ACPI_BATTERY_VALUE_UNKNOWN) | ||
842 | seq_printf(seq, "present voltage: unknown\n"); | ||
843 | else | ||
844 | seq_printf(seq, "present voltage: %d mV\n", | ||
845 | battery->voltage_now); | ||
846 | end: | ||
847 | if (result) | ||
848 | seq_printf(seq, "ERROR: Unable to read battery state\n"); | ||
849 | |||
850 | return result; | ||
851 | } | ||
852 | |||
853 | static int acpi_battery_print_alarm(struct seq_file *seq, int result) | ||
854 | { | ||
855 | struct acpi_battery *battery = seq->private; | ||
856 | |||
857 | if (result) | ||
858 | goto end; | ||
859 | |||
860 | if (!acpi_battery_present(battery)) { | ||
861 | seq_printf(seq, "present: no\n"); | ||
862 | goto end; | ||
863 | } | ||
864 | seq_printf(seq, "alarm: "); | ||
865 | if (!battery->alarm) | ||
866 | seq_printf(seq, "unsupported\n"); | ||
867 | else | ||
868 | seq_printf(seq, "%u %sh\n", battery->alarm, | ||
869 | acpi_battery_units(battery)); | ||
870 | end: | ||
871 | if (result) | ||
872 | seq_printf(seq, "ERROR: Unable to read battery alarm\n"); | ||
873 | return result; | ||
874 | } | ||
875 | |||
876 | static ssize_t acpi_battery_write_alarm(struct file *file, | ||
877 | const char __user * buffer, | ||
878 | size_t count, loff_t * ppos) | ||
879 | { | ||
880 | int result = 0; | ||
881 | char alarm_string[12] = { '\0' }; | ||
882 | struct seq_file *m = file->private_data; | ||
883 | struct acpi_battery *battery = m->private; | ||
884 | |||
885 | if (!battery || (count > sizeof(alarm_string) - 1)) | ||
886 | return -EINVAL; | ||
887 | if (!acpi_battery_present(battery)) { | ||
888 | result = -ENODEV; | ||
889 | goto end; | ||
890 | } | ||
891 | if (copy_from_user(alarm_string, buffer, count)) { | ||
892 | result = -EFAULT; | ||
893 | goto end; | ||
894 | } | ||
895 | alarm_string[count] = '\0'; | ||
896 | battery->alarm = simple_strtol(alarm_string, NULL, 0); | ||
897 | result = acpi_battery_set_alarm(battery); | ||
898 | end: | ||
899 | if (!result) | ||
900 | return count; | ||
901 | return result; | ||
902 | } | ||
903 | |||
904 | typedef int(*print_func)(struct seq_file *seq, int result); | ||
905 | |||
906 | static print_func acpi_print_funcs[ACPI_BATTERY_NUMFILES] = { | ||
907 | acpi_battery_print_info, | ||
908 | acpi_battery_print_state, | ||
909 | acpi_battery_print_alarm, | ||
910 | }; | ||
911 | |||
912 | static int acpi_battery_read(int fid, struct seq_file *seq) | ||
913 | { | ||
914 | struct acpi_battery *battery = seq->private; | ||
915 | int result = acpi_battery_update(battery); | ||
916 | return acpi_print_funcs[fid](seq, result); | ||
917 | } | ||
918 | |||
919 | #define DECLARE_FILE_FUNCTIONS(_name) \ | ||
920 | static int acpi_battery_read_##_name(struct seq_file *seq, void *offset) \ | ||
921 | { \ | ||
922 | return acpi_battery_read(_name##_tag, seq); \ | ||
923 | } \ | ||
924 | static int acpi_battery_##_name##_open_fs(struct inode *inode, struct file *file) \ | ||
925 | { \ | ||
926 | return single_open(file, acpi_battery_read_##_name, PDE_DATA(inode)); \ | ||
927 | } | ||
928 | |||
929 | DECLARE_FILE_FUNCTIONS(info); | ||
930 | DECLARE_FILE_FUNCTIONS(state); | ||
931 | DECLARE_FILE_FUNCTIONS(alarm); | ||
932 | |||
933 | #undef DECLARE_FILE_FUNCTIONS | ||
934 | |||
935 | #define FILE_DESCRIPTION_RO(_name) \ | ||
936 | { \ | ||
937 | .name = __stringify(_name), \ | ||
938 | .mode = S_IRUGO, \ | ||
939 | .ops = { \ | ||
940 | .open = acpi_battery_##_name##_open_fs, \ | ||
941 | .read = seq_read, \ | ||
942 | .llseek = seq_lseek, \ | ||
943 | .release = single_release, \ | ||
944 | .owner = THIS_MODULE, \ | ||
945 | }, \ | ||
946 | } | ||
947 | |||
948 | #define FILE_DESCRIPTION_RW(_name) \ | ||
949 | { \ | ||
950 | .name = __stringify(_name), \ | ||
951 | .mode = S_IFREG | S_IRUGO | S_IWUSR, \ | ||
952 | .ops = { \ | ||
953 | .open = acpi_battery_##_name##_open_fs, \ | ||
954 | .read = seq_read, \ | ||
955 | .llseek = seq_lseek, \ | ||
956 | .write = acpi_battery_write_##_name, \ | ||
957 | .release = single_release, \ | ||
958 | .owner = THIS_MODULE, \ | ||
959 | }, \ | ||
960 | } | ||
961 | |||
962 | static const struct battery_file { | ||
963 | struct file_operations ops; | ||
964 | umode_t mode; | ||
965 | const char *name; | ||
966 | } acpi_battery_file[] = { | ||
967 | FILE_DESCRIPTION_RO(info), | ||
968 | FILE_DESCRIPTION_RO(state), | ||
969 | FILE_DESCRIPTION_RW(alarm), | ||
970 | }; | ||
971 | |||
972 | #undef FILE_DESCRIPTION_RO | ||
973 | #undef FILE_DESCRIPTION_RW | ||
974 | |||
975 | static int acpi_battery_add_fs(struct acpi_device *device) | ||
976 | { | ||
977 | struct proc_dir_entry *entry = NULL; | ||
978 | int i; | ||
979 | |||
980 | printk(KERN_WARNING PREFIX "Deprecated procfs I/F for battery is loaded," | ||
981 | " please retry with CONFIG_ACPI_PROCFS_POWER cleared\n"); | ||
982 | if (!acpi_device_dir(device)) { | ||
983 | acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), | ||
984 | acpi_battery_dir); | ||
985 | if (!acpi_device_dir(device)) | ||
986 | return -ENODEV; | ||
987 | } | ||
988 | |||
989 | for (i = 0; i < ACPI_BATTERY_NUMFILES; ++i) { | ||
990 | entry = proc_create_data(acpi_battery_file[i].name, | ||
991 | acpi_battery_file[i].mode, | ||
992 | acpi_device_dir(device), | ||
993 | &acpi_battery_file[i].ops, | ||
994 | acpi_driver_data(device)); | ||
995 | if (!entry) | ||
996 | return -ENODEV; | ||
997 | } | ||
998 | return 0; | ||
999 | } | ||
1000 | |||
1001 | static void acpi_battery_remove_fs(struct acpi_device *device) | ||
1002 | { | ||
1003 | int i; | ||
1004 | if (!acpi_device_dir(device)) | ||
1005 | return; | ||
1006 | for (i = 0; i < ACPI_BATTERY_NUMFILES; ++i) | ||
1007 | remove_proc_entry(acpi_battery_file[i].name, | ||
1008 | acpi_device_dir(device)); | ||
1009 | |||
1010 | remove_proc_entry(acpi_device_bid(device), acpi_battery_dir); | ||
1011 | acpi_device_dir(device) = NULL; | ||
1012 | } | ||
1013 | |||
1014 | #endif | ||
1015 | |||
1016 | /* -------------------------------------------------------------------------- | ||
1017 | Driver Interface | 717 | Driver Interface |
1018 | -------------------------------------------------------------------------- */ | 718 | -------------------------------------------------------------------------- */ |
1019 | 719 | ||
@@ -1075,15 +775,6 @@ static int acpi_battery_add(struct acpi_device *device) | |||
1075 | result = acpi_battery_update(battery); | 775 | result = acpi_battery_update(battery); |
1076 | if (result) | 776 | if (result) |
1077 | goto fail; | 777 | goto fail; |
1078 | #ifdef CONFIG_ACPI_PROCFS_POWER | ||
1079 | result = acpi_battery_add_fs(device); | ||
1080 | #endif | ||
1081 | if (result) { | ||
1082 | #ifdef CONFIG_ACPI_PROCFS_POWER | ||
1083 | acpi_battery_remove_fs(device); | ||
1084 | #endif | ||
1085 | goto fail; | ||
1086 | } | ||
1087 | 778 | ||
1088 | printk(KERN_INFO PREFIX "%s Slot [%s] (battery %s)\n", | 779 | printk(KERN_INFO PREFIX "%s Slot [%s] (battery %s)\n", |
1089 | ACPI_BATTERY_DEVICE_NAME, acpi_device_bid(device), | 780 | ACPI_BATTERY_DEVICE_NAME, acpi_device_bid(device), |
@@ -1110,9 +801,6 @@ static int acpi_battery_remove(struct acpi_device *device) | |||
1110 | return -EINVAL; | 801 | return -EINVAL; |
1111 | battery = acpi_driver_data(device); | 802 | battery = acpi_driver_data(device); |
1112 | unregister_pm_notifier(&battery->pm_nb); | 803 | unregister_pm_notifier(&battery->pm_nb); |
1113 | #ifdef CONFIG_ACPI_PROCFS_POWER | ||
1114 | acpi_battery_remove_fs(device); | ||
1115 | #endif | ||
1116 | sysfs_remove_battery(battery); | 804 | sysfs_remove_battery(battery); |
1117 | mutex_destroy(&battery->lock); | 805 | mutex_destroy(&battery->lock); |
1118 | mutex_destroy(&battery->sysfs_lock); | 806 | mutex_destroy(&battery->sysfs_lock); |
@@ -1158,18 +846,7 @@ static void __init acpi_battery_init_async(void *unused, async_cookie_t cookie) | |||
1158 | { | 846 | { |
1159 | if (acpi_disabled) | 847 | if (acpi_disabled) |
1160 | return; | 848 | return; |
1161 | #ifdef CONFIG_ACPI_PROCFS_POWER | 849 | acpi_bus_register_driver(&acpi_battery_driver); |
1162 | acpi_battery_dir = acpi_lock_battery_dir(); | ||
1163 | if (!acpi_battery_dir) | ||
1164 | return; | ||
1165 | #endif | ||
1166 | if (acpi_bus_register_driver(&acpi_battery_driver) < 0) { | ||
1167 | #ifdef CONFIG_ACPI_PROCFS_POWER | ||
1168 | acpi_unlock_battery_dir(acpi_battery_dir); | ||
1169 | #endif | ||
1170 | return; | ||
1171 | } | ||
1172 | return; | ||
1173 | } | 850 | } |
1174 | 851 | ||
1175 | static int __init acpi_battery_init(void) | 852 | static int __init acpi_battery_init(void) |
@@ -1181,9 +858,6 @@ static int __init acpi_battery_init(void) | |||
1181 | static void __exit acpi_battery_exit(void) | 858 | static void __exit acpi_battery_exit(void) |
1182 | { | 859 | { |
1183 | acpi_bus_unregister_driver(&acpi_battery_driver); | 860 | acpi_bus_unregister_driver(&acpi_battery_driver); |
1184 | #ifdef CONFIG_ACPI_PROCFS_POWER | ||
1185 | acpi_unlock_battery_dir(acpi_battery_dir); | ||
1186 | #endif | ||
1187 | } | 861 | } |
1188 | 862 | ||
1189 | module_init(acpi_battery_init); | 863 | module_init(acpi_battery_init); |
diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c index 9515f18898b2..078c4f7fe2dd 100644 --- a/drivers/acpi/blacklist.c +++ b/drivers/acpi/blacklist.c | |||
@@ -75,39 +75,6 @@ static struct acpi_blacklist_item acpi_blacklist[] __initdata = { | |||
75 | {""} | 75 | {""} |
76 | }; | 76 | }; |
77 | 77 | ||
78 | #if CONFIG_ACPI_BLACKLIST_YEAR | ||
79 | |||
80 | static int __init blacklist_by_year(void) | ||
81 | { | ||
82 | int year; | ||
83 | |||
84 | /* Doesn't exist? Likely an old system */ | ||
85 | if (!dmi_get_date(DMI_BIOS_DATE, &year, NULL, NULL)) { | ||
86 | printk(KERN_ERR PREFIX "no DMI BIOS year, " | ||
87 | "acpi=force is required to enable ACPI\n" ); | ||
88 | return 1; | ||
89 | } | ||
90 | /* 0? Likely a buggy new BIOS */ | ||
91 | if (year == 0) { | ||
92 | printk(KERN_ERR PREFIX "DMI BIOS year==0, " | ||
93 | "assuming ACPI-capable machine\n" ); | ||
94 | return 0; | ||
95 | } | ||
96 | if (year < CONFIG_ACPI_BLACKLIST_YEAR) { | ||
97 | printk(KERN_ERR PREFIX "BIOS age (%d) fails cutoff (%d), " | ||
98 | "acpi=force is required to enable ACPI\n", | ||
99 | year, CONFIG_ACPI_BLACKLIST_YEAR); | ||
100 | return 1; | ||
101 | } | ||
102 | return 0; | ||
103 | } | ||
104 | #else | ||
105 | static inline int blacklist_by_year(void) | ||
106 | { | ||
107 | return 0; | ||
108 | } | ||
109 | #endif | ||
110 | |||
111 | int __init acpi_blacklisted(void) | 78 | int __init acpi_blacklisted(void) |
112 | { | 79 | { |
113 | int i = 0; | 80 | int i = 0; |
@@ -166,8 +133,6 @@ int __init acpi_blacklisted(void) | |||
166 | } | 133 | } |
167 | } | 134 | } |
168 | 135 | ||
169 | blacklisted += blacklist_by_year(); | ||
170 | |||
171 | dmi_check_system(acpi_osi_dmi_table); | 136 | dmi_check_system(acpi_osi_dmi_table); |
172 | 137 | ||
173 | return blacklisted; | 138 | return blacklisted; |
@@ -274,6 +239,19 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { | |||
274 | }, | 239 | }, |
275 | }, | 240 | }, |
276 | { | 241 | { |
242 | .callback = dmi_disable_osi_vista, | ||
243 | .ident = "Toshiba NB100", | ||
244 | .matches = { | ||
245 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | ||
246 | DMI_MATCH(DMI_PRODUCT_NAME, "NB100"), | ||
247 | }, | ||
248 | }, | ||
249 | |||
250 | /* | ||
251 | * The following machines have broken backlight support when reporting | ||
252 | * the Windows 2012 OSI, so disable it until their support is fixed. | ||
253 | */ | ||
254 | { | ||
277 | .callback = dmi_disable_osi_win8, | 255 | .callback = dmi_disable_osi_win8, |
278 | .ident = "ASUS Zenbook Prime UX31A", | 256 | .ident = "ASUS Zenbook Prime UX31A", |
279 | .matches = { | 257 | .matches = { |
@@ -291,12 +269,60 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { | |||
291 | }, | 269 | }, |
292 | { | 270 | { |
293 | .callback = dmi_disable_osi_win8, | 271 | .callback = dmi_disable_osi_win8, |
294 | .ident = "Lenovo ThinkPad Edge E530", | 272 | .ident = "ThinkPad Edge E530", |
295 | .matches = { | 273 | .matches = { |
296 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | 274 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), |
297 | DMI_MATCH(DMI_PRODUCT_VERSION, "3259A2G"), | 275 | DMI_MATCH(DMI_PRODUCT_VERSION, "3259A2G"), |
298 | }, | 276 | }, |
299 | }, | 277 | }, |
278 | { | ||
279 | .callback = dmi_disable_osi_win8, | ||
280 | .ident = "ThinkPad Edge E530", | ||
281 | .matches = { | ||
282 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
283 | DMI_MATCH(DMI_PRODUCT_VERSION, "3259CTO"), | ||
284 | }, | ||
285 | }, | ||
286 | { | ||
287 | .callback = dmi_disable_osi_win8, | ||
288 | .ident = "ThinkPad Edge E530", | ||
289 | .matches = { | ||
290 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
291 | DMI_MATCH(DMI_PRODUCT_VERSION, "3259HJG"), | ||
292 | }, | ||
293 | }, | ||
294 | { | ||
295 | .callback = dmi_disable_osi_win8, | ||
296 | .ident = "Acer Aspire V5-573G", | ||
297 | .matches = { | ||
298 | DMI_MATCH(DMI_SYS_VENDOR, "Acer Aspire"), | ||
299 | DMI_MATCH(DMI_PRODUCT_VERSION, "V5-573G/Dazzle_HW"), | ||
300 | }, | ||
301 | }, | ||
302 | { | ||
303 | .callback = dmi_disable_osi_win8, | ||
304 | .ident = "Acer Aspire V5-572G", | ||
305 | .matches = { | ||
306 | DMI_MATCH(DMI_SYS_VENDOR, "Acer Aspire"), | ||
307 | DMI_MATCH(DMI_PRODUCT_VERSION, "V5-572G/Dazzle_CX"), | ||
308 | }, | ||
309 | }, | ||
310 | { | ||
311 | .callback = dmi_disable_osi_win8, | ||
312 | .ident = "ThinkPad T431s", | ||
313 | .matches = { | ||
314 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
315 | DMI_MATCH(DMI_PRODUCT_VERSION, "20AACTO1WW"), | ||
316 | }, | ||
317 | }, | ||
318 | { | ||
319 | .callback = dmi_disable_osi_win8, | ||
320 | .ident = "ThinkPad T430", | ||
321 | .matches = { | ||
322 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
323 | DMI_MATCH(DMI_PRODUCT_VERSION, "2349D15"), | ||
324 | }, | ||
325 | }, | ||
300 | 326 | ||
301 | /* | 327 | /* |
302 | * BIOS invocation of _OSI(Linux) is almost always a BIOS bug. | 328 | * BIOS invocation of _OSI(Linux) is almost always a BIOS bug. |
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index b587ec8257b2..bba9b72e25f8 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c | |||
@@ -174,7 +174,7 @@ static void acpi_print_osc_error(acpi_handle handle, | |||
174 | printk("\n"); | 174 | printk("\n"); |
175 | } | 175 | } |
176 | 176 | ||
177 | static acpi_status acpi_str_to_uuid(char *str, u8 *uuid) | 177 | acpi_status acpi_str_to_uuid(char *str, u8 *uuid) |
178 | { | 178 | { |
179 | int i; | 179 | int i; |
180 | static int opc_map_to_uuid[16] = {6, 4, 2, 0, 11, 9, 16, 14, 19, 21, | 180 | static int opc_map_to_uuid[16] = {6, 4, 2, 0, 11, 9, 16, 14, 19, 21, |
@@ -195,6 +195,7 @@ static acpi_status acpi_str_to_uuid(char *str, u8 *uuid) | |||
195 | } | 195 | } |
196 | return AE_OK; | 196 | return AE_OK; |
197 | } | 197 | } |
198 | EXPORT_SYMBOL_GPL(acpi_str_to_uuid); | ||
198 | 199 | ||
199 | acpi_status acpi_run_osc(acpi_handle handle, struct acpi_osc_context *context) | 200 | acpi_status acpi_run_osc(acpi_handle handle, struct acpi_osc_context *context) |
200 | { | 201 | { |
@@ -255,7 +256,7 @@ acpi_status acpi_run_osc(acpi_handle handle, struct acpi_osc_context *context) | |||
255 | acpi_print_osc_error(handle, context, | 256 | acpi_print_osc_error(handle, context, |
256 | "_OSC invalid revision"); | 257 | "_OSC invalid revision"); |
257 | if (errors & OSC_CAPABILITIES_MASK_ERROR) { | 258 | if (errors & OSC_CAPABILITIES_MASK_ERROR) { |
258 | if (((u32 *)context->cap.pointer)[OSC_QUERY_TYPE] | 259 | if (((u32 *)context->cap.pointer)[OSC_QUERY_DWORD] |
259 | & OSC_QUERY_ENABLE) | 260 | & OSC_QUERY_ENABLE) |
260 | goto out_success; | 261 | goto out_success; |
261 | status = AE_SUPPORT; | 262 | status = AE_SUPPORT; |
@@ -295,30 +296,30 @@ static void acpi_bus_osc_support(void) | |||
295 | }; | 296 | }; |
296 | acpi_handle handle; | 297 | acpi_handle handle; |
297 | 298 | ||
298 | capbuf[OSC_QUERY_TYPE] = OSC_QUERY_ENABLE; | 299 | capbuf[OSC_QUERY_DWORD] = OSC_QUERY_ENABLE; |
299 | capbuf[OSC_SUPPORT_TYPE] = OSC_SB_PR3_SUPPORT; /* _PR3 is in use */ | 300 | capbuf[OSC_SUPPORT_DWORD] = OSC_SB_PR3_SUPPORT; /* _PR3 is in use */ |
300 | #if defined(CONFIG_ACPI_PROCESSOR_AGGREGATOR) ||\ | 301 | #if defined(CONFIG_ACPI_PROCESSOR_AGGREGATOR) ||\ |
301 | defined(CONFIG_ACPI_PROCESSOR_AGGREGATOR_MODULE) | 302 | defined(CONFIG_ACPI_PROCESSOR_AGGREGATOR_MODULE) |
302 | capbuf[OSC_SUPPORT_TYPE] |= OSC_SB_PAD_SUPPORT; | 303 | capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_PAD_SUPPORT; |
303 | #endif | 304 | #endif |
304 | 305 | ||
305 | #if defined(CONFIG_ACPI_PROCESSOR) || defined(CONFIG_ACPI_PROCESSOR_MODULE) | 306 | #if defined(CONFIG_ACPI_PROCESSOR) || defined(CONFIG_ACPI_PROCESSOR_MODULE) |
306 | capbuf[OSC_SUPPORT_TYPE] |= OSC_SB_PPC_OST_SUPPORT; | 307 | capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_PPC_OST_SUPPORT; |
307 | #endif | 308 | #endif |
308 | 309 | ||
309 | #ifdef ACPI_HOTPLUG_OST | 310 | #ifdef ACPI_HOTPLUG_OST |
310 | capbuf[OSC_SUPPORT_TYPE] |= OSC_SB_HOTPLUG_OST_SUPPORT; | 311 | capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_HOTPLUG_OST_SUPPORT; |
311 | #endif | 312 | #endif |
312 | 313 | ||
313 | if (!ghes_disable) | 314 | if (!ghes_disable) |
314 | capbuf[OSC_SUPPORT_TYPE] |= OSC_SB_APEI_SUPPORT; | 315 | capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_APEI_SUPPORT; |
315 | if (ACPI_FAILURE(acpi_get_handle(NULL, "\\_SB", &handle))) | 316 | if (ACPI_FAILURE(acpi_get_handle(NULL, "\\_SB", &handle))) |
316 | return; | 317 | return; |
317 | if (ACPI_SUCCESS(acpi_run_osc(handle, &context))) { | 318 | if (ACPI_SUCCESS(acpi_run_osc(handle, &context))) { |
318 | u32 *capbuf_ret = context.ret.pointer; | 319 | u32 *capbuf_ret = context.ret.pointer; |
319 | if (context.ret.length > OSC_SUPPORT_TYPE) | 320 | if (context.ret.length > OSC_SUPPORT_DWORD) |
320 | osc_sb_apei_support_acked = | 321 | osc_sb_apei_support_acked = |
321 | capbuf_ret[OSC_SUPPORT_TYPE] & OSC_SB_APEI_SUPPORT; | 322 | capbuf_ret[OSC_SUPPORT_DWORD] & OSC_SB_APEI_SUPPORT; |
322 | kfree(context.ret.pointer); | 323 | kfree(context.ret.pointer); |
323 | } | 324 | } |
324 | /* do we need to check other returned cap? Sounds no */ | 325 | /* do we need to check other returned cap? Sounds no */ |
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c index a55773801c5f..c971929d75c2 100644 --- a/drivers/acpi/button.c +++ b/drivers/acpi/button.c | |||
@@ -383,18 +383,15 @@ static int acpi_button_add(struct acpi_device *device) | |||
383 | 383 | ||
384 | switch (button->type) { | 384 | switch (button->type) { |
385 | case ACPI_BUTTON_TYPE_POWER: | 385 | case ACPI_BUTTON_TYPE_POWER: |
386 | input->evbit[0] = BIT_MASK(EV_KEY); | 386 | input_set_capability(input, EV_KEY, KEY_POWER); |
387 | set_bit(KEY_POWER, input->keybit); | ||
388 | break; | 387 | break; |
389 | 388 | ||
390 | case ACPI_BUTTON_TYPE_SLEEP: | 389 | case ACPI_BUTTON_TYPE_SLEEP: |
391 | input->evbit[0] = BIT_MASK(EV_KEY); | 390 | input_set_capability(input, EV_KEY, KEY_SLEEP); |
392 | set_bit(KEY_SLEEP, input->keybit); | ||
393 | break; | 391 | break; |
394 | 392 | ||
395 | case ACPI_BUTTON_TYPE_LID: | 393 | case ACPI_BUTTON_TYPE_LID: |
396 | input->evbit[0] = BIT_MASK(EV_SW); | 394 | input_set_capability(input, EV_SW, SW_LID); |
397 | set_bit(SW_LID, input->swbit); | ||
398 | break; | 395 | break; |
399 | } | 396 | } |
400 | 397 | ||
diff --git a/drivers/acpi/cm_sbs.c b/drivers/acpi/cm_sbs.c deleted file mode 100644 index 6c9ee68e46fb..000000000000 --- a/drivers/acpi/cm_sbs.c +++ /dev/null | |||
@@ -1,105 +0,0 @@ | |||
1 | /* | ||
2 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or (at | ||
7 | * your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but | ||
10 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
12 | * General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along | ||
15 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. | ||
17 | * | ||
18 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
19 | */ | ||
20 | |||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/module.h> | ||
23 | #include <linux/init.h> | ||
24 | #include <linux/acpi.h> | ||
25 | #include <linux/types.h> | ||
26 | #include <linux/proc_fs.h> | ||
27 | #include <linux/seq_file.h> | ||
28 | #include <acpi/acpi_bus.h> | ||
29 | #include <acpi/acpi_drivers.h> | ||
30 | |||
31 | #define PREFIX "ACPI: " | ||
32 | |||
33 | ACPI_MODULE_NAME("cm_sbs"); | ||
34 | #define ACPI_AC_CLASS "ac_adapter" | ||
35 | #define ACPI_BATTERY_CLASS "battery" | ||
36 | #define _COMPONENT ACPI_SBS_COMPONENT | ||
37 | static struct proc_dir_entry *acpi_ac_dir; | ||
38 | static struct proc_dir_entry *acpi_battery_dir; | ||
39 | |||
40 | static DEFINE_MUTEX(cm_sbs_mutex); | ||
41 | |||
42 | static int lock_ac_dir_cnt; | ||
43 | static int lock_battery_dir_cnt; | ||
44 | |||
45 | struct proc_dir_entry *acpi_lock_ac_dir(void) | ||
46 | { | ||
47 | mutex_lock(&cm_sbs_mutex); | ||
48 | if (!acpi_ac_dir) | ||
49 | acpi_ac_dir = proc_mkdir(ACPI_AC_CLASS, acpi_root_dir); | ||
50 | if (acpi_ac_dir) { | ||
51 | lock_ac_dir_cnt++; | ||
52 | } else { | ||
53 | printk(KERN_ERR PREFIX | ||
54 | "Cannot create %s\n", ACPI_AC_CLASS); | ||
55 | } | ||
56 | mutex_unlock(&cm_sbs_mutex); | ||
57 | return acpi_ac_dir; | ||
58 | } | ||
59 | EXPORT_SYMBOL(acpi_lock_ac_dir); | ||
60 | |||
61 | void acpi_unlock_ac_dir(struct proc_dir_entry *acpi_ac_dir_param) | ||
62 | { | ||
63 | mutex_lock(&cm_sbs_mutex); | ||
64 | if (acpi_ac_dir_param) | ||
65 | lock_ac_dir_cnt--; | ||
66 | if (lock_ac_dir_cnt == 0 && acpi_ac_dir_param && acpi_ac_dir) { | ||
67 | remove_proc_entry(ACPI_AC_CLASS, acpi_root_dir); | ||
68 | acpi_ac_dir = NULL; | ||
69 | } | ||
70 | mutex_unlock(&cm_sbs_mutex); | ||
71 | } | ||
72 | EXPORT_SYMBOL(acpi_unlock_ac_dir); | ||
73 | |||
74 | struct proc_dir_entry *acpi_lock_battery_dir(void) | ||
75 | { | ||
76 | mutex_lock(&cm_sbs_mutex); | ||
77 | if (!acpi_battery_dir) { | ||
78 | acpi_battery_dir = | ||
79 | proc_mkdir(ACPI_BATTERY_CLASS, acpi_root_dir); | ||
80 | } | ||
81 | if (acpi_battery_dir) { | ||
82 | lock_battery_dir_cnt++; | ||
83 | } else { | ||
84 | printk(KERN_ERR PREFIX | ||
85 | "Cannot create %s\n", ACPI_BATTERY_CLASS); | ||
86 | } | ||
87 | mutex_unlock(&cm_sbs_mutex); | ||
88 | return acpi_battery_dir; | ||
89 | } | ||
90 | EXPORT_SYMBOL(acpi_lock_battery_dir); | ||
91 | |||
92 | void acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir_param) | ||
93 | { | ||
94 | mutex_lock(&cm_sbs_mutex); | ||
95 | if (acpi_battery_dir_param) | ||
96 | lock_battery_dir_cnt--; | ||
97 | if (lock_battery_dir_cnt == 0 && acpi_battery_dir_param | ||
98 | && acpi_battery_dir) { | ||
99 | remove_proc_entry(ACPI_BATTERY_CLASS, acpi_root_dir); | ||
100 | acpi_battery_dir = NULL; | ||
101 | } | ||
102 | mutex_unlock(&cm_sbs_mutex); | ||
103 | return; | ||
104 | } | ||
105 | EXPORT_SYMBOL(acpi_unlock_battery_dir); | ||
diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c index a94383d1f350..b3480cf7db1a 100644 --- a/drivers/acpi/device_pm.c +++ b/drivers/acpi/device_pm.c | |||
@@ -22,16 +22,12 @@ | |||
22 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 22 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include <linux/device.h> | 25 | #include <linux/acpi.h> |
26 | #include <linux/export.h> | 26 | #include <linux/export.h> |
27 | #include <linux/mutex.h> | 27 | #include <linux/mutex.h> |
28 | #include <linux/pm_qos.h> | 28 | #include <linux/pm_qos.h> |
29 | #include <linux/pm_runtime.h> | 29 | #include <linux/pm_runtime.h> |
30 | 30 | ||
31 | #include <acpi/acpi.h> | ||
32 | #include <acpi/acpi_bus.h> | ||
33 | #include <acpi/acpi_drivers.h> | ||
34 | |||
35 | #include "internal.h" | 31 | #include "internal.h" |
36 | 32 | ||
37 | #define _COMPONENT ACPI_POWER_COMPONENT | 33 | #define _COMPONENT ACPI_POWER_COMPONENT |
@@ -118,9 +114,10 @@ int acpi_device_get_power(struct acpi_device *device, int *state) | |||
118 | /* | 114 | /* |
119 | * If we were unsure about the device parent's power state up to this | 115 | * If we were unsure about the device parent's power state up to this |
120 | * point, the fact that the device is in D0 implies that the parent has | 116 | * point, the fact that the device is in D0 implies that the parent has |
121 | * to be in D0 too. | 117 | * to be in D0 too, except if ignore_parent is set. |
122 | */ | 118 | */ |
123 | if (device->parent && device->parent->power.state == ACPI_STATE_UNKNOWN | 119 | if (!device->power.flags.ignore_parent && device->parent |
120 | && device->parent->power.state == ACPI_STATE_UNKNOWN | ||
124 | && result == ACPI_STATE_D0) | 121 | && result == ACPI_STATE_D0) |
125 | device->parent->power.state = ACPI_STATE_D0; | 122 | device->parent->power.state = ACPI_STATE_D0; |
126 | 123 | ||
@@ -177,7 +174,8 @@ int acpi_device_set_power(struct acpi_device *device, int state) | |||
177 | acpi_power_state_string(state)); | 174 | acpi_power_state_string(state)); |
178 | return -ENODEV; | 175 | return -ENODEV; |
179 | } | 176 | } |
180 | if (device->parent && (state < device->parent->power.state)) { | 177 | if (!device->power.flags.ignore_parent && |
178 | device->parent && (state < device->parent->power.state)) { | ||
181 | dev_warn(&device->dev, | 179 | dev_warn(&device->dev, |
182 | "Cannot transition to power state %s for parent in %s\n", | 180 | "Cannot transition to power state %s for parent in %s\n", |
183 | acpi_power_state_string(state), | 181 | acpi_power_state_string(state), |
@@ -546,7 +544,7 @@ static int acpi_dev_pm_get_state(struct device *dev, struct acpi_device *adev, | |||
546 | */ | 544 | */ |
547 | int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p, int d_max_in) | 545 | int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p, int d_max_in) |
548 | { | 546 | { |
549 | acpi_handle handle = DEVICE_ACPI_HANDLE(dev); | 547 | acpi_handle handle = ACPI_HANDLE(dev); |
550 | struct acpi_device *adev; | 548 | struct acpi_device *adev; |
551 | int ret, d_min, d_max; | 549 | int ret, d_min, d_max; |
552 | 550 | ||
@@ -654,7 +652,7 @@ int acpi_pm_device_run_wake(struct device *phys_dev, bool enable) | |||
654 | if (!device_run_wake(phys_dev)) | 652 | if (!device_run_wake(phys_dev)) |
655 | return -EINVAL; | 653 | return -EINVAL; |
656 | 654 | ||
657 | handle = DEVICE_ACPI_HANDLE(phys_dev); | 655 | handle = ACPI_HANDLE(phys_dev); |
658 | if (!handle || acpi_bus_get_device(handle, &adev)) { | 656 | if (!handle || acpi_bus_get_device(handle, &adev)) { |
659 | dev_dbg(phys_dev, "ACPI handle without context in %s!\n", | 657 | dev_dbg(phys_dev, "ACPI handle without context in %s!\n", |
660 | __func__); | 658 | __func__); |
@@ -698,7 +696,7 @@ int acpi_pm_device_sleep_wake(struct device *dev, bool enable) | |||
698 | if (!device_can_wakeup(dev)) | 696 | if (!device_can_wakeup(dev)) |
699 | return -EINVAL; | 697 | return -EINVAL; |
700 | 698 | ||
701 | handle = DEVICE_ACPI_HANDLE(dev); | 699 | handle = ACPI_HANDLE(dev); |
702 | if (!handle || acpi_bus_get_device(handle, &adev)) { | 700 | if (!handle || acpi_bus_get_device(handle, &adev)) { |
703 | dev_dbg(dev, "ACPI handle without context in %s!\n", __func__); | 701 | dev_dbg(dev, "ACPI handle without context in %s!\n", __func__); |
704 | return -ENODEV; | 702 | return -ENODEV; |
@@ -720,7 +718,7 @@ int acpi_pm_device_sleep_wake(struct device *dev, bool enable) | |||
720 | */ | 718 | */ |
721 | struct acpi_device *acpi_dev_pm_get_node(struct device *dev) | 719 | struct acpi_device *acpi_dev_pm_get_node(struct device *dev) |
722 | { | 720 | { |
723 | acpi_handle handle = DEVICE_ACPI_HANDLE(dev); | 721 | acpi_handle handle = ACPI_HANDLE(dev); |
724 | struct acpi_device *adev; | 722 | struct acpi_device *adev; |
725 | 723 | ||
726 | return handle && !acpi_bus_get_device(handle, &adev) ? adev : NULL; | 724 | return handle && !acpi_bus_get_device(handle, &adev) ? adev : NULL; |
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index 05ea4be01a83..dcd73ccb514c 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c | |||
@@ -441,7 +441,7 @@ static void handle_dock(struct dock_station *ds, int dock) | |||
441 | acpi_status status; | 441 | acpi_status status; |
442 | struct acpi_object_list arg_list; | 442 | struct acpi_object_list arg_list; |
443 | union acpi_object arg; | 443 | union acpi_object arg; |
444 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | 444 | unsigned long long value; |
445 | 445 | ||
446 | acpi_handle_info(ds->handle, "%s\n", dock ? "docking" : "undocking"); | 446 | acpi_handle_info(ds->handle, "%s\n", dock ? "docking" : "undocking"); |
447 | 447 | ||
@@ -450,12 +450,10 @@ static void handle_dock(struct dock_station *ds, int dock) | |||
450 | arg_list.pointer = &arg; | 450 | arg_list.pointer = &arg; |
451 | arg.type = ACPI_TYPE_INTEGER; | 451 | arg.type = ACPI_TYPE_INTEGER; |
452 | arg.integer.value = dock; | 452 | arg.integer.value = dock; |
453 | status = acpi_evaluate_object(ds->handle, "_DCK", &arg_list, &buffer); | 453 | status = acpi_evaluate_integer(ds->handle, "_DCK", &arg_list, &value); |
454 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) | 454 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) |
455 | acpi_handle_err(ds->handle, "Failed to execute _DCK (0x%x)\n", | 455 | acpi_handle_err(ds->handle, "Failed to execute _DCK (0x%x)\n", |
456 | status); | 456 | status); |
457 | |||
458 | kfree(buffer.pointer); | ||
459 | } | 457 | } |
460 | 458 | ||
461 | static inline void dock(struct dock_station *ds) | 459 | static inline void dock(struct dock_station *ds) |
@@ -671,39 +669,20 @@ static void dock_notify(struct dock_station *ds, u32 event) | |||
671 | } | 669 | } |
672 | } | 670 | } |
673 | 671 | ||
674 | struct dock_data { | 672 | static void acpi_dock_deferred_cb(void *data, u32 event) |
675 | struct dock_station *ds; | ||
676 | u32 event; | ||
677 | }; | ||
678 | |||
679 | static void acpi_dock_deferred_cb(void *context) | ||
680 | { | 673 | { |
681 | struct dock_data *data = context; | ||
682 | |||
683 | acpi_scan_lock_acquire(); | 674 | acpi_scan_lock_acquire(); |
684 | dock_notify(data->ds, data->event); | 675 | dock_notify(data, event); |
685 | acpi_scan_lock_release(); | 676 | acpi_scan_lock_release(); |
686 | kfree(data); | ||
687 | } | 677 | } |
688 | 678 | ||
689 | static void dock_notify_handler(acpi_handle handle, u32 event, void *data) | 679 | static void dock_notify_handler(acpi_handle handle, u32 event, void *data) |
690 | { | 680 | { |
691 | struct dock_data *dd; | ||
692 | |||
693 | if (event != ACPI_NOTIFY_BUS_CHECK && event != ACPI_NOTIFY_DEVICE_CHECK | 681 | if (event != ACPI_NOTIFY_BUS_CHECK && event != ACPI_NOTIFY_DEVICE_CHECK |
694 | && event != ACPI_NOTIFY_EJECT_REQUEST) | 682 | && event != ACPI_NOTIFY_EJECT_REQUEST) |
695 | return; | 683 | return; |
696 | 684 | ||
697 | dd = kmalloc(sizeof(*dd), GFP_KERNEL); | 685 | acpi_hotplug_execute(acpi_dock_deferred_cb, data, event); |
698 | if (dd) { | ||
699 | acpi_status status; | ||
700 | |||
701 | dd->ds = data; | ||
702 | dd->event = event; | ||
703 | status = acpi_os_hotplug_execute(acpi_dock_deferred_cb, dd); | ||
704 | if (ACPI_FAILURE(status)) | ||
705 | kfree(dd); | ||
706 | } | ||
707 | } | 686 | } |
708 | 687 | ||
709 | /** | 688 | /** |
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 15986f32009e..ba5b56db9d27 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
@@ -28,6 +28,7 @@ | |||
28 | 28 | ||
29 | /* Uncomment next line to get verbose printout */ | 29 | /* Uncomment next line to get verbose printout */ |
30 | /* #define DEBUG */ | 30 | /* #define DEBUG */ |
31 | #define pr_fmt(fmt) "ACPI : EC: " fmt | ||
31 | 32 | ||
32 | #include <linux/kernel.h> | 33 | #include <linux/kernel.h> |
33 | #include <linux/module.h> | 34 | #include <linux/module.h> |
@@ -49,9 +50,6 @@ | |||
49 | #define ACPI_EC_DEVICE_NAME "Embedded Controller" | 50 | #define ACPI_EC_DEVICE_NAME "Embedded Controller" |
50 | #define ACPI_EC_FILE_INFO "info" | 51 | #define ACPI_EC_FILE_INFO "info" |
51 | 52 | ||
52 | #undef PREFIX | ||
53 | #define PREFIX "ACPI: EC: " | ||
54 | |||
55 | /* EC status register */ | 53 | /* EC status register */ |
56 | #define ACPI_EC_FLAG_OBF 0x01 /* Output buffer full */ | 54 | #define ACPI_EC_FLAG_OBF 0x01 /* Output buffer full */ |
57 | #define ACPI_EC_FLAG_IBF 0x02 /* Input buffer full */ | 55 | #define ACPI_EC_FLAG_IBF 0x02 /* Input buffer full */ |
@@ -131,26 +129,26 @@ static int EC_FLAGS_SKIP_DSDT_SCAN; /* Not all BIOS survive early DSDT scan */ | |||
131 | static inline u8 acpi_ec_read_status(struct acpi_ec *ec) | 129 | static inline u8 acpi_ec_read_status(struct acpi_ec *ec) |
132 | { | 130 | { |
133 | u8 x = inb(ec->command_addr); | 131 | u8 x = inb(ec->command_addr); |
134 | pr_debug(PREFIX "---> status = 0x%2.2x\n", x); | 132 | pr_debug("---> status = 0x%2.2x\n", x); |
135 | return x; | 133 | return x; |
136 | } | 134 | } |
137 | 135 | ||
138 | static inline u8 acpi_ec_read_data(struct acpi_ec *ec) | 136 | static inline u8 acpi_ec_read_data(struct acpi_ec *ec) |
139 | { | 137 | { |
140 | u8 x = inb(ec->data_addr); | 138 | u8 x = inb(ec->data_addr); |
141 | pr_debug(PREFIX "---> data = 0x%2.2x\n", x); | 139 | pr_debug("---> data = 0x%2.2x\n", x); |
142 | return x; | 140 | return x; |
143 | } | 141 | } |
144 | 142 | ||
145 | static inline void acpi_ec_write_cmd(struct acpi_ec *ec, u8 command) | 143 | static inline void acpi_ec_write_cmd(struct acpi_ec *ec, u8 command) |
146 | { | 144 | { |
147 | pr_debug(PREFIX "<--- command = 0x%2.2x\n", command); | 145 | pr_debug("<--- command = 0x%2.2x\n", command); |
148 | outb(command, ec->command_addr); | 146 | outb(command, ec->command_addr); |
149 | } | 147 | } |
150 | 148 | ||
151 | static inline void acpi_ec_write_data(struct acpi_ec *ec, u8 data) | 149 | static inline void acpi_ec_write_data(struct acpi_ec *ec, u8 data) |
152 | { | 150 | { |
153 | pr_debug(PREFIX "<--- data = 0x%2.2x\n", data); | 151 | pr_debug("<--- data = 0x%2.2x\n", data); |
154 | outb(data, ec->data_addr); | 152 | outb(data, ec->data_addr); |
155 | } | 153 | } |
156 | 154 | ||
@@ -242,7 +240,7 @@ static int ec_poll(struct acpi_ec *ec) | |||
242 | } | 240 | } |
243 | advance_transaction(ec, acpi_ec_read_status(ec)); | 241 | advance_transaction(ec, acpi_ec_read_status(ec)); |
244 | } while (time_before(jiffies, delay)); | 242 | } while (time_before(jiffies, delay)); |
245 | pr_debug(PREFIX "controller reset, restart transaction\n"); | 243 | pr_debug("controller reset, restart transaction\n"); |
246 | spin_lock_irqsave(&ec->lock, flags); | 244 | spin_lock_irqsave(&ec->lock, flags); |
247 | start_transaction(ec); | 245 | start_transaction(ec); |
248 | spin_unlock_irqrestore(&ec->lock, flags); | 246 | spin_unlock_irqrestore(&ec->lock, flags); |
@@ -310,12 +308,12 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t) | |||
310 | } | 308 | } |
311 | } | 309 | } |
312 | if (ec_wait_ibf0(ec)) { | 310 | if (ec_wait_ibf0(ec)) { |
313 | pr_err(PREFIX "input buffer is not empty, " | 311 | pr_err("input buffer is not empty, " |
314 | "aborting transaction\n"); | 312 | "aborting transaction\n"); |
315 | status = -ETIME; | 313 | status = -ETIME; |
316 | goto end; | 314 | goto end; |
317 | } | 315 | } |
318 | pr_debug(PREFIX "transaction start (cmd=0x%02x, addr=0x%02x)\n", | 316 | pr_debug("transaction start (cmd=0x%02x, addr=0x%02x)\n", |
319 | t->command, t->wdata ? t->wdata[0] : 0); | 317 | t->command, t->wdata ? t->wdata[0] : 0); |
320 | /* disable GPE during transaction if storm is detected */ | 318 | /* disable GPE during transaction if storm is detected */ |
321 | if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) { | 319 | if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) { |
@@ -332,12 +330,12 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t) | |||
332 | /* It is safe to enable the GPE outside of the transaction. */ | 330 | /* It is safe to enable the GPE outside of the transaction. */ |
333 | acpi_enable_gpe(NULL, ec->gpe); | 331 | acpi_enable_gpe(NULL, ec->gpe); |
334 | } else if (t->irq_count > ec_storm_threshold) { | 332 | } else if (t->irq_count > ec_storm_threshold) { |
335 | pr_info(PREFIX "GPE storm detected(%d GPEs), " | 333 | pr_info("GPE storm detected(%d GPEs), " |
336 | "transactions will use polling mode\n", | 334 | "transactions will use polling mode\n", |
337 | t->irq_count); | 335 | t->irq_count); |
338 | set_bit(EC_FLAGS_GPE_STORM, &ec->flags); | 336 | set_bit(EC_FLAGS_GPE_STORM, &ec->flags); |
339 | } | 337 | } |
340 | pr_debug(PREFIX "transaction end\n"); | 338 | pr_debug("transaction end\n"); |
341 | end: | 339 | end: |
342 | if (ec->global_lock) | 340 | if (ec->global_lock) |
343 | acpi_release_global_lock(glk); | 341 | acpi_release_global_lock(glk); |
@@ -571,12 +569,12 @@ static void acpi_ec_run(void *cxt) | |||
571 | struct acpi_ec_query_handler *handler = cxt; | 569 | struct acpi_ec_query_handler *handler = cxt; |
572 | if (!handler) | 570 | if (!handler) |
573 | return; | 571 | return; |
574 | pr_debug(PREFIX "start query execution\n"); | 572 | pr_debug("start query execution\n"); |
575 | if (handler->func) | 573 | if (handler->func) |
576 | handler->func(handler->data); | 574 | handler->func(handler->data); |
577 | else if (handler->handle) | 575 | else if (handler->handle) |
578 | acpi_evaluate_object(handler->handle, NULL, NULL, NULL); | 576 | acpi_evaluate_object(handler->handle, NULL, NULL, NULL); |
579 | pr_debug(PREFIX "stop query execution\n"); | 577 | pr_debug("stop query execution\n"); |
580 | kfree(handler); | 578 | kfree(handler); |
581 | } | 579 | } |
582 | 580 | ||
@@ -594,7 +592,8 @@ static int acpi_ec_sync_query(struct acpi_ec *ec) | |||
594 | if (!copy) | 592 | if (!copy) |
595 | return -ENOMEM; | 593 | return -ENOMEM; |
596 | memcpy(copy, handler, sizeof(*copy)); | 594 | memcpy(copy, handler, sizeof(*copy)); |
597 | pr_debug(PREFIX "push query execution (0x%2x) on queue\n", value); | 595 | pr_debug("push query execution (0x%2x) on queue\n", |
596 | value); | ||
598 | return acpi_os_execute((copy->func) ? | 597 | return acpi_os_execute((copy->func) ? |
599 | OSL_NOTIFY_HANDLER : OSL_GPE_HANDLER, | 598 | OSL_NOTIFY_HANDLER : OSL_GPE_HANDLER, |
600 | acpi_ec_run, copy); | 599 | acpi_ec_run, copy); |
@@ -617,7 +616,7 @@ static int ec_check_sci(struct acpi_ec *ec, u8 state) | |||
617 | { | 616 | { |
618 | if (state & ACPI_EC_FLAG_SCI) { | 617 | if (state & ACPI_EC_FLAG_SCI) { |
619 | if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags)) { | 618 | if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags)) { |
620 | pr_debug(PREFIX "push gpe query to the queue\n"); | 619 | pr_debug("push gpe query to the queue\n"); |
621 | return acpi_os_execute(OSL_NOTIFY_HANDLER, | 620 | return acpi_os_execute(OSL_NOTIFY_HANDLER, |
622 | acpi_ec_gpe_query, ec); | 621 | acpi_ec_gpe_query, ec); |
623 | } | 622 | } |
@@ -631,7 +630,7 @@ static u32 acpi_ec_gpe_handler(acpi_handle gpe_device, | |||
631 | struct acpi_ec *ec = data; | 630 | struct acpi_ec *ec = data; |
632 | u8 status = acpi_ec_read_status(ec); | 631 | u8 status = acpi_ec_read_status(ec); |
633 | 632 | ||
634 | pr_debug(PREFIX "~~~> interrupt, status:0x%02x\n", status); | 633 | pr_debug("~~~> interrupt, status:0x%02x\n", status); |
635 | 634 | ||
636 | advance_transaction(ec, status); | 635 | advance_transaction(ec, status); |
637 | if (ec_transaction_done(ec) && | 636 | if (ec_transaction_done(ec) && |
@@ -777,7 +776,7 @@ static int ec_install_handlers(struct acpi_ec *ec) | |||
777 | * The AE_NOT_FOUND error will be ignored and OS | 776 | * The AE_NOT_FOUND error will be ignored and OS |
778 | * continue to initialize EC. | 777 | * continue to initialize EC. |
779 | */ | 778 | */ |
780 | printk(KERN_ERR "Fail in evaluating the _REG object" | 779 | pr_err("Fail in evaluating the _REG object" |
781 | " of EC device. Broken bios is suspected.\n"); | 780 | " of EC device. Broken bios is suspected.\n"); |
782 | } else { | 781 | } else { |
783 | acpi_remove_gpe_handler(NULL, ec->gpe, | 782 | acpi_remove_gpe_handler(NULL, ec->gpe, |
@@ -796,10 +795,10 @@ static void ec_remove_handlers(struct acpi_ec *ec) | |||
796 | acpi_disable_gpe(NULL, ec->gpe); | 795 | acpi_disable_gpe(NULL, ec->gpe); |
797 | if (ACPI_FAILURE(acpi_remove_address_space_handler(ec->handle, | 796 | if (ACPI_FAILURE(acpi_remove_address_space_handler(ec->handle, |
798 | ACPI_ADR_SPACE_EC, &acpi_ec_space_handler))) | 797 | ACPI_ADR_SPACE_EC, &acpi_ec_space_handler))) |
799 | pr_err(PREFIX "failed to remove space handler\n"); | 798 | pr_err("failed to remove space handler\n"); |
800 | if (ACPI_FAILURE(acpi_remove_gpe_handler(NULL, ec->gpe, | 799 | if (ACPI_FAILURE(acpi_remove_gpe_handler(NULL, ec->gpe, |
801 | &acpi_ec_gpe_handler))) | 800 | &acpi_ec_gpe_handler))) |
802 | pr_err(PREFIX "failed to remove gpe handler\n"); | 801 | pr_err("failed to remove gpe handler\n"); |
803 | clear_bit(EC_FLAGS_HANDLERS_INSTALLED, &ec->flags); | 802 | clear_bit(EC_FLAGS_HANDLERS_INSTALLED, &ec->flags); |
804 | } | 803 | } |
805 | 804 | ||
@@ -841,7 +840,7 @@ static int acpi_ec_add(struct acpi_device *device) | |||
841 | ret = !!request_region(ec->command_addr, 1, "EC cmd"); | 840 | ret = !!request_region(ec->command_addr, 1, "EC cmd"); |
842 | WARN(!ret, "Could not request EC cmd io port 0x%lx", ec->command_addr); | 841 | WARN(!ret, "Could not request EC cmd io port 0x%lx", ec->command_addr); |
843 | 842 | ||
844 | pr_info(PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n", | 843 | pr_info("GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n", |
845 | ec->gpe, ec->command_addr, ec->data_addr); | 844 | ec->gpe, ec->command_addr, ec->data_addr); |
846 | 845 | ||
847 | ret = ec_install_handlers(ec); | 846 | ret = ec_install_handlers(ec); |
@@ -932,7 +931,7 @@ static int ec_validate_ecdt(const struct dmi_system_id *id) | |||
932 | /* MSI EC needs special treatment, enable it */ | 931 | /* MSI EC needs special treatment, enable it */ |
933 | static int ec_flag_msi(const struct dmi_system_id *id) | 932 | static int ec_flag_msi(const struct dmi_system_id *id) |
934 | { | 933 | { |
935 | printk(KERN_DEBUG PREFIX "Detected MSI hardware, enabling workarounds.\n"); | 934 | pr_debug("Detected MSI hardware, enabling workarounds.\n"); |
936 | EC_FLAGS_MSI = 1; | 935 | EC_FLAGS_MSI = 1; |
937 | EC_FLAGS_VALIDATE_ECDT = 1; | 936 | EC_FLAGS_VALIDATE_ECDT = 1; |
938 | return 0; | 937 | return 0; |
@@ -1011,7 +1010,7 @@ int __init acpi_ec_ecdt_probe(void) | |||
1011 | status = acpi_get_table(ACPI_SIG_ECDT, 1, | 1010 | status = acpi_get_table(ACPI_SIG_ECDT, 1, |
1012 | (struct acpi_table_header **)&ecdt_ptr); | 1011 | (struct acpi_table_header **)&ecdt_ptr); |
1013 | if (ACPI_SUCCESS(status)) { | 1012 | if (ACPI_SUCCESS(status)) { |
1014 | pr_info(PREFIX "EC description table is found, configuring boot EC\n"); | 1013 | pr_info("EC description table is found, configuring boot EC\n"); |
1015 | boot_ec->command_addr = ecdt_ptr->control.address; | 1014 | boot_ec->command_addr = ecdt_ptr->control.address; |
1016 | boot_ec->data_addr = ecdt_ptr->data.address; | 1015 | boot_ec->data_addr = ecdt_ptr->data.address; |
1017 | boot_ec->gpe = ecdt_ptr->gpe; | 1016 | boot_ec->gpe = ecdt_ptr->gpe; |
@@ -1031,7 +1030,7 @@ int __init acpi_ec_ecdt_probe(void) | |||
1031 | 1030 | ||
1032 | /* This workaround is needed only on some broken machines, | 1031 | /* This workaround is needed only on some broken machines, |
1033 | * which require early EC, but fail to provide ECDT */ | 1032 | * which require early EC, but fail to provide ECDT */ |
1034 | printk(KERN_DEBUG PREFIX "Look up EC in DSDT\n"); | 1033 | pr_debug("Look up EC in DSDT\n"); |
1035 | status = acpi_get_devices(ec_device_ids[0].id, ec_parse_device, | 1034 | status = acpi_get_devices(ec_device_ids[0].id, ec_parse_device, |
1036 | boot_ec, NULL); | 1035 | boot_ec, NULL); |
1037 | /* Check that acpi_get_devices actually find something */ | 1036 | /* Check that acpi_get_devices actually find something */ |
@@ -1043,7 +1042,7 @@ int __init acpi_ec_ecdt_probe(void) | |||
1043 | saved_ec->data_addr != boot_ec->data_addr || | 1042 | saved_ec->data_addr != boot_ec->data_addr || |
1044 | saved_ec->gpe != boot_ec->gpe || | 1043 | saved_ec->gpe != boot_ec->gpe || |
1045 | saved_ec->handle != boot_ec->handle) | 1044 | saved_ec->handle != boot_ec->handle) |
1046 | pr_info(PREFIX "ASUSTek keeps feeding us with broken " | 1045 | pr_info("ASUSTek keeps feeding us with broken " |
1047 | "ECDT tables, which are very hard to workaround. " | 1046 | "ECDT tables, which are very hard to workaround. " |
1048 | "Trying to use DSDT EC info instead. Please send " | 1047 | "Trying to use DSDT EC info instead. Please send " |
1049 | "output of acpidump to linux-acpi@vger.kernel.org\n"); | 1048 | "output of acpidump to linux-acpi@vger.kernel.org\n"); |
diff --git a/drivers/acpi/event.c b/drivers/acpi/event.c index 8247fcdde079..fdef416c0ff6 100644 --- a/drivers/acpi/event.c +++ b/drivers/acpi/event.c | |||
@@ -127,11 +127,6 @@ int acpi_bus_generate_netlink_event(const char *device_class, | |||
127 | } | 127 | } |
128 | 128 | ||
129 | event = nla_data(attr); | 129 | event = nla_data(attr); |
130 | if (!event) { | ||
131 | nlmsg_free(skb); | ||
132 | return -EINVAL; | ||
133 | } | ||
134 | |||
135 | memset(event, 0, sizeof(struct acpi_genl_event)); | 130 | memset(event, 0, sizeof(struct acpi_genl_event)); |
136 | 131 | ||
137 | strcpy(event->device_class, device_class); | 132 | strcpy(event->device_class, device_class); |
diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c index 41ade6570bc0..ba3da88cee45 100644 --- a/drivers/acpi/fan.c +++ b/drivers/acpi/fan.c | |||
@@ -168,7 +168,7 @@ static int acpi_fan_add(struct acpi_device *device) | |||
168 | acpi_device_name(device), acpi_device_bid(device), | 168 | acpi_device_name(device), acpi_device_bid(device), |
169 | !device->power.state ? "on" : "off"); | 169 | !device->power.state ? "on" : "off"); |
170 | 170 | ||
171 | end: | 171 | end: |
172 | return result; | 172 | return result; |
173 | } | 173 | } |
174 | 174 | ||
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index 10f0f40587bb..a22a295edb69 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c | |||
@@ -197,30 +197,28 @@ static void acpi_physnode_link_name(char *buf, unsigned int node_id) | |||
197 | 197 | ||
198 | int acpi_bind_one(struct device *dev, acpi_handle handle) | 198 | int acpi_bind_one(struct device *dev, acpi_handle handle) |
199 | { | 199 | { |
200 | struct acpi_device *acpi_dev; | 200 | struct acpi_device *acpi_dev = NULL; |
201 | acpi_status status; | ||
202 | struct acpi_device_physical_node *physical_node, *pn; | 201 | struct acpi_device_physical_node *physical_node, *pn; |
203 | char physical_node_name[PHYSICAL_NODE_NAME_SIZE]; | 202 | char physical_node_name[PHYSICAL_NODE_NAME_SIZE]; |
204 | struct list_head *physnode_list; | 203 | struct list_head *physnode_list; |
205 | unsigned int node_id; | 204 | unsigned int node_id; |
206 | int retval = -EINVAL; | 205 | int retval = -EINVAL; |
207 | 206 | ||
208 | if (ACPI_HANDLE(dev)) { | 207 | if (ACPI_COMPANION(dev)) { |
209 | if (handle) { | 208 | if (handle) { |
210 | dev_warn(dev, "ACPI handle is already set\n"); | 209 | dev_warn(dev, "ACPI companion already set\n"); |
211 | return -EINVAL; | 210 | return -EINVAL; |
212 | } else { | 211 | } else { |
213 | handle = ACPI_HANDLE(dev); | 212 | acpi_dev = ACPI_COMPANION(dev); |
214 | } | 213 | } |
214 | } else { | ||
215 | acpi_bus_get_device(handle, &acpi_dev); | ||
215 | } | 216 | } |
216 | if (!handle) | 217 | if (!acpi_dev) |
217 | return -EINVAL; | 218 | return -EINVAL; |
218 | 219 | ||
220 | get_device(&acpi_dev->dev); | ||
219 | get_device(dev); | 221 | get_device(dev); |
220 | status = acpi_bus_get_device(handle, &acpi_dev); | ||
221 | if (ACPI_FAILURE(status)) | ||
222 | goto err; | ||
223 | |||
224 | physical_node = kzalloc(sizeof(*physical_node), GFP_KERNEL); | 222 | physical_node = kzalloc(sizeof(*physical_node), GFP_KERNEL); |
225 | if (!physical_node) { | 223 | if (!physical_node) { |
226 | retval = -ENOMEM; | 224 | retval = -ENOMEM; |
@@ -242,10 +240,11 @@ int acpi_bind_one(struct device *dev, acpi_handle handle) | |||
242 | 240 | ||
243 | dev_warn(dev, "Already associated with ACPI node\n"); | 241 | dev_warn(dev, "Already associated with ACPI node\n"); |
244 | kfree(physical_node); | 242 | kfree(physical_node); |
245 | if (ACPI_HANDLE(dev) != handle) | 243 | if (ACPI_COMPANION(dev) != acpi_dev) |
246 | goto err; | 244 | goto err; |
247 | 245 | ||
248 | put_device(dev); | 246 | put_device(dev); |
247 | put_device(&acpi_dev->dev); | ||
249 | return 0; | 248 | return 0; |
250 | } | 249 | } |
251 | if (pn->node_id == node_id) { | 250 | if (pn->node_id == node_id) { |
@@ -259,8 +258,8 @@ int acpi_bind_one(struct device *dev, acpi_handle handle) | |||
259 | list_add(&physical_node->node, physnode_list); | 258 | list_add(&physical_node->node, physnode_list); |
260 | acpi_dev->physical_node_count++; | 259 | acpi_dev->physical_node_count++; |
261 | 260 | ||
262 | if (!ACPI_HANDLE(dev)) | 261 | if (!ACPI_COMPANION(dev)) |
263 | ACPI_HANDLE_SET(dev, acpi_dev->handle); | 262 | ACPI_COMPANION_SET(dev, acpi_dev); |
264 | 263 | ||
265 | acpi_physnode_link_name(physical_node_name, node_id); | 264 | acpi_physnode_link_name(physical_node_name, node_id); |
266 | retval = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj, | 265 | retval = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj, |
@@ -283,27 +282,21 @@ int acpi_bind_one(struct device *dev, acpi_handle handle) | |||
283 | return 0; | 282 | return 0; |
284 | 283 | ||
285 | err: | 284 | err: |
286 | ACPI_HANDLE_SET(dev, NULL); | 285 | ACPI_COMPANION_SET(dev, NULL); |
287 | put_device(dev); | 286 | put_device(dev); |
287 | put_device(&acpi_dev->dev); | ||
288 | return retval; | 288 | return retval; |
289 | } | 289 | } |
290 | EXPORT_SYMBOL_GPL(acpi_bind_one); | 290 | EXPORT_SYMBOL_GPL(acpi_bind_one); |
291 | 291 | ||
292 | int acpi_unbind_one(struct device *dev) | 292 | int acpi_unbind_one(struct device *dev) |
293 | { | 293 | { |
294 | struct acpi_device *acpi_dev = ACPI_COMPANION(dev); | ||
294 | struct acpi_device_physical_node *entry; | 295 | struct acpi_device_physical_node *entry; |
295 | struct acpi_device *acpi_dev; | ||
296 | acpi_status status; | ||
297 | 296 | ||
298 | if (!ACPI_HANDLE(dev)) | 297 | if (!acpi_dev) |
299 | return 0; | 298 | return 0; |
300 | 299 | ||
301 | status = acpi_bus_get_device(ACPI_HANDLE(dev), &acpi_dev); | ||
302 | if (ACPI_FAILURE(status)) { | ||
303 | dev_err(dev, "Oops, ACPI handle corrupt in %s()\n", __func__); | ||
304 | return -EINVAL; | ||
305 | } | ||
306 | |||
307 | mutex_lock(&acpi_dev->physical_node_lock); | 300 | mutex_lock(&acpi_dev->physical_node_lock); |
308 | 301 | ||
309 | list_for_each_entry(entry, &acpi_dev->physical_node_list, node) | 302 | list_for_each_entry(entry, &acpi_dev->physical_node_list, node) |
@@ -316,9 +309,10 @@ int acpi_unbind_one(struct device *dev) | |||
316 | acpi_physnode_link_name(physnode_name, entry->node_id); | 309 | acpi_physnode_link_name(physnode_name, entry->node_id); |
317 | sysfs_remove_link(&acpi_dev->dev.kobj, physnode_name); | 310 | sysfs_remove_link(&acpi_dev->dev.kobj, physnode_name); |
318 | sysfs_remove_link(&dev->kobj, "firmware_node"); | 311 | sysfs_remove_link(&dev->kobj, "firmware_node"); |
319 | ACPI_HANDLE_SET(dev, NULL); | 312 | ACPI_COMPANION_SET(dev, NULL); |
320 | /* acpi_bind_one() increase refcnt by one. */ | 313 | /* Drop references taken by acpi_bind_one(). */ |
321 | put_device(dev); | 314 | put_device(dev); |
315 | put_device(&acpi_dev->dev); | ||
322 | kfree(entry); | 316 | kfree(entry); |
323 | break; | 317 | break; |
324 | } | 318 | } |
@@ -328,6 +322,15 @@ int acpi_unbind_one(struct device *dev) | |||
328 | } | 322 | } |
329 | EXPORT_SYMBOL_GPL(acpi_unbind_one); | 323 | EXPORT_SYMBOL_GPL(acpi_unbind_one); |
330 | 324 | ||
325 | void acpi_preset_companion(struct device *dev, acpi_handle parent, u64 addr) | ||
326 | { | ||
327 | struct acpi_device *adev; | ||
328 | |||
329 | if (!acpi_bus_get_device(acpi_get_child(parent, addr), &adev)) | ||
330 | ACPI_COMPANION_SET(dev, adev); | ||
331 | } | ||
332 | EXPORT_SYMBOL_GPL(acpi_preset_companion); | ||
333 | |||
331 | static int acpi_platform_notify(struct device *dev) | 334 | static int acpi_platform_notify(struct device *dev) |
332 | { | 335 | { |
333 | struct acpi_bus_type *type = acpi_get_bus_type(dev); | 336 | struct acpi_bus_type *type = acpi_get_bus_type(dev); |
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index 20f423337e1f..a29739c0ba79 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h | |||
@@ -26,11 +26,6 @@ | |||
26 | acpi_status acpi_os_initialize1(void); | 26 | acpi_status acpi_os_initialize1(void); |
27 | int init_acpi_device_notify(void); | 27 | int init_acpi_device_notify(void); |
28 | int acpi_scan_init(void); | 28 | int acpi_scan_init(void); |
29 | #ifdef CONFIG_ACPI_PCI_SLOT | ||
30 | void acpi_pci_slot_init(void); | ||
31 | #else | ||
32 | static inline void acpi_pci_slot_init(void) { } | ||
33 | #endif | ||
34 | void acpi_pci_root_init(void); | 29 | void acpi_pci_root_init(void); |
35 | void acpi_pci_link_init(void); | 30 | void acpi_pci_link_init(void); |
36 | void acpi_pci_root_hp_init(void); | 31 | void acpi_pci_root_hp_init(void); |
@@ -92,6 +87,7 @@ void acpi_device_add_finalize(struct acpi_device *device); | |||
92 | void acpi_free_pnp_ids(struct acpi_device_pnp *pnp); | 87 | void acpi_free_pnp_ids(struct acpi_device_pnp *pnp); |
93 | int acpi_bind_one(struct device *dev, acpi_handle handle); | 88 | int acpi_bind_one(struct device *dev, acpi_handle handle); |
94 | int acpi_unbind_one(struct device *dev); | 89 | int acpi_unbind_one(struct device *dev); |
90 | void acpi_bus_device_eject(void *data, u32 ost_src); | ||
95 | 91 | ||
96 | /* -------------------------------------------------------------------------- | 92 | /* -------------------------------------------------------------------------- |
97 | Power Resource | 93 | Power Resource |
@@ -169,9 +165,7 @@ int acpi_create_platform_device(struct acpi_device *adev, | |||
169 | Video | 165 | Video |
170 | -------------------------------------------------------------------------- */ | 166 | -------------------------------------------------------------------------- */ |
171 | #if defined(CONFIG_ACPI_VIDEO) || defined(CONFIG_ACPI_VIDEO_MODULE) | 167 | #if defined(CONFIG_ACPI_VIDEO) || defined(CONFIG_ACPI_VIDEO_MODULE) |
172 | bool acpi_video_backlight_quirks(void); | 168 | bool acpi_osi_is_win8(void); |
173 | #else | ||
174 | static inline bool acpi_video_backlight_quirks(void) { return false; } | ||
175 | #endif | 169 | #endif |
176 | 170 | ||
177 | #endif /* _ACPI_INTERNAL_H_ */ | 171 | #endif /* _ACPI_INTERNAL_H_ */ |
diff --git a/drivers/acpi/numa.c b/drivers/acpi/numa.c index 2e82e5d76930..a2343a1d9e0b 100644 --- a/drivers/acpi/numa.c +++ b/drivers/acpi/numa.c | |||
@@ -73,7 +73,7 @@ int acpi_map_pxm_to_node(int pxm) | |||
73 | { | 73 | { |
74 | int node = pxm_to_node_map[pxm]; | 74 | int node = pxm_to_node_map[pxm]; |
75 | 75 | ||
76 | if (node < 0) { | 76 | if (node == NUMA_NO_NODE) { |
77 | if (nodes_weight(nodes_found_map) >= MAX_NUMNODES) | 77 | if (nodes_weight(nodes_found_map) >= MAX_NUMNODES) |
78 | return NUMA_NO_NODE; | 78 | return NUMA_NO_NODE; |
79 | node = first_unset_node(nodes_found_map); | 79 | node = first_unset_node(nodes_found_map); |
@@ -334,7 +334,7 @@ int acpi_get_pxm(acpi_handle h) | |||
334 | 334 | ||
335 | int acpi_get_node(acpi_handle *handle) | 335 | int acpi_get_node(acpi_handle *handle) |
336 | { | 336 | { |
337 | int pxm, node = -1; | 337 | int pxm, node = NUMA_NO_NODE; |
338 | 338 | ||
339 | pxm = acpi_get_pxm(handle); | 339 | pxm = acpi_get_pxm(handle); |
340 | if (pxm >= 0 && pxm < MAX_PXM_DOMAINS) | 340 | if (pxm >= 0 && pxm < MAX_PXM_DOMAINS) |
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index e5f416c7f66e..54a20ff4b864 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c | |||
@@ -61,7 +61,6 @@ struct acpi_os_dpc { | |||
61 | acpi_osd_exec_callback function; | 61 | acpi_osd_exec_callback function; |
62 | void *context; | 62 | void *context; |
63 | struct work_struct work; | 63 | struct work_struct work; |
64 | int wait; | ||
65 | }; | 64 | }; |
66 | 65 | ||
67 | #ifdef CONFIG_ACPI_CUSTOM_DSDT | 66 | #ifdef CONFIG_ACPI_CUSTOM_DSDT |
@@ -569,8 +568,10 @@ static const char * const table_sigs[] = { | |||
569 | 568 | ||
570 | #define ACPI_HEADER_SIZE sizeof(struct acpi_table_header) | 569 | #define ACPI_HEADER_SIZE sizeof(struct acpi_table_header) |
571 | 570 | ||
572 | /* Must not increase 10 or needs code modification below */ | 571 | #define ACPI_OVERRIDE_TABLES 64 |
573 | #define ACPI_OVERRIDE_TABLES 10 | 572 | static struct cpio_data __initdata acpi_initrd_files[ACPI_OVERRIDE_TABLES]; |
573 | |||
574 | #define MAP_CHUNK_SIZE (NR_FIX_BTMAPS << PAGE_SHIFT) | ||
574 | 575 | ||
575 | void __init acpi_initrd_override(void *data, size_t size) | 576 | void __init acpi_initrd_override(void *data, size_t size) |
576 | { | 577 | { |
@@ -579,8 +580,6 @@ void __init acpi_initrd_override(void *data, size_t size) | |||
579 | struct acpi_table_header *table; | 580 | struct acpi_table_header *table; |
580 | char cpio_path[32] = "kernel/firmware/acpi/"; | 581 | char cpio_path[32] = "kernel/firmware/acpi/"; |
581 | struct cpio_data file; | 582 | struct cpio_data file; |
582 | struct cpio_data early_initrd_files[ACPI_OVERRIDE_TABLES]; | ||
583 | char *p; | ||
584 | 583 | ||
585 | if (data == NULL || size == 0) | 584 | if (data == NULL || size == 0) |
586 | return; | 585 | return; |
@@ -625,8 +624,8 @@ void __init acpi_initrd_override(void *data, size_t size) | |||
625 | table->signature, cpio_path, file.name, table->length); | 624 | table->signature, cpio_path, file.name, table->length); |
626 | 625 | ||
627 | all_tables_size += table->length; | 626 | all_tables_size += table->length; |
628 | early_initrd_files[table_nr].data = file.data; | 627 | acpi_initrd_files[table_nr].data = file.data; |
629 | early_initrd_files[table_nr].size = file.size; | 628 | acpi_initrd_files[table_nr].size = file.size; |
630 | table_nr++; | 629 | table_nr++; |
631 | } | 630 | } |
632 | if (table_nr == 0) | 631 | if (table_nr == 0) |
@@ -652,14 +651,34 @@ void __init acpi_initrd_override(void *data, size_t size) | |||
652 | memblock_reserve(acpi_tables_addr, all_tables_size); | 651 | memblock_reserve(acpi_tables_addr, all_tables_size); |
653 | arch_reserve_mem_area(acpi_tables_addr, all_tables_size); | 652 | arch_reserve_mem_area(acpi_tables_addr, all_tables_size); |
654 | 653 | ||
655 | p = early_ioremap(acpi_tables_addr, all_tables_size); | 654 | /* |
656 | 655 | * early_ioremap only can remap 256k one time. If we map all | |
656 | * tables one time, we will hit the limit. Need to map chunks | ||
657 | * one by one during copying the same as that in relocate_initrd(). | ||
658 | */ | ||
657 | for (no = 0; no < table_nr; no++) { | 659 | for (no = 0; no < table_nr; no++) { |
658 | memcpy(p + total_offset, early_initrd_files[no].data, | 660 | unsigned char *src_p = acpi_initrd_files[no].data; |
659 | early_initrd_files[no].size); | 661 | phys_addr_t size = acpi_initrd_files[no].size; |
660 | total_offset += early_initrd_files[no].size; | 662 | phys_addr_t dest_addr = acpi_tables_addr + total_offset; |
663 | phys_addr_t slop, clen; | ||
664 | char *dest_p; | ||
665 | |||
666 | total_offset += size; | ||
667 | |||
668 | while (size) { | ||
669 | slop = dest_addr & ~PAGE_MASK; | ||
670 | clen = size; | ||
671 | if (clen > MAP_CHUNK_SIZE - slop) | ||
672 | clen = MAP_CHUNK_SIZE - slop; | ||
673 | dest_p = early_ioremap(dest_addr & PAGE_MASK, | ||
674 | clen + slop); | ||
675 | memcpy(dest_p + slop, src_p, clen); | ||
676 | early_iounmap(dest_p, clen + slop); | ||
677 | src_p += clen; | ||
678 | dest_addr += clen; | ||
679 | size -= clen; | ||
680 | } | ||
661 | } | 681 | } |
662 | early_iounmap(p, all_tables_size); | ||
663 | } | 682 | } |
664 | #endif /* CONFIG_ACPI_INITRD_TABLE_OVERRIDE */ | 683 | #endif /* CONFIG_ACPI_INITRD_TABLE_OVERRIDE */ |
665 | 684 | ||
@@ -820,7 +839,7 @@ acpi_status acpi_os_remove_interrupt_handler(u32 irq, acpi_osd_handler handler) | |||
820 | 839 | ||
821 | void acpi_os_sleep(u64 ms) | 840 | void acpi_os_sleep(u64 ms) |
822 | { | 841 | { |
823 | schedule_timeout_interruptible(msecs_to_jiffies(ms)); | 842 | msleep(ms); |
824 | } | 843 | } |
825 | 844 | ||
826 | void acpi_os_stall(u32 us) | 845 | void acpi_os_stall(u32 us) |
@@ -1067,9 +1086,6 @@ static void acpi_os_execute_deferred(struct work_struct *work) | |||
1067 | { | 1086 | { |
1068 | struct acpi_os_dpc *dpc = container_of(work, struct acpi_os_dpc, work); | 1087 | struct acpi_os_dpc *dpc = container_of(work, struct acpi_os_dpc, work); |
1069 | 1088 | ||
1070 | if (dpc->wait) | ||
1071 | acpi_os_wait_events_complete(); | ||
1072 | |||
1073 | dpc->function(dpc->context); | 1089 | dpc->function(dpc->context); |
1074 | kfree(dpc); | 1090 | kfree(dpc); |
1075 | } | 1091 | } |
@@ -1089,8 +1105,8 @@ static void acpi_os_execute_deferred(struct work_struct *work) | |||
1089 | * | 1105 | * |
1090 | ******************************************************************************/ | 1106 | ******************************************************************************/ |
1091 | 1107 | ||
1092 | static acpi_status __acpi_os_execute(acpi_execute_type type, | 1108 | acpi_status acpi_os_execute(acpi_execute_type type, |
1093 | acpi_osd_exec_callback function, void *context, int hp) | 1109 | acpi_osd_exec_callback function, void *context) |
1094 | { | 1110 | { |
1095 | acpi_status status = AE_OK; | 1111 | acpi_status status = AE_OK; |
1096 | struct acpi_os_dpc *dpc; | 1112 | struct acpi_os_dpc *dpc; |
@@ -1117,20 +1133,11 @@ static acpi_status __acpi_os_execute(acpi_execute_type type, | |||
1117 | dpc->context = context; | 1133 | dpc->context = context; |
1118 | 1134 | ||
1119 | /* | 1135 | /* |
1120 | * We can't run hotplug code in keventd_wq/kacpid_wq/kacpid_notify_wq | ||
1121 | * because the hotplug code may call driver .remove() functions, | ||
1122 | * which invoke flush_scheduled_work/acpi_os_wait_events_complete | ||
1123 | * to flush these workqueues. | ||
1124 | * | ||
1125 | * To prevent lockdep from complaining unnecessarily, make sure that | 1136 | * To prevent lockdep from complaining unnecessarily, make sure that |
1126 | * there is a different static lockdep key for each workqueue by using | 1137 | * there is a different static lockdep key for each workqueue by using |
1127 | * INIT_WORK() for each of them separately. | 1138 | * INIT_WORK() for each of them separately. |
1128 | */ | 1139 | */ |
1129 | if (hp) { | 1140 | if (type == OSL_NOTIFY_HANDLER) { |
1130 | queue = kacpi_hotplug_wq; | ||
1131 | dpc->wait = 1; | ||
1132 | INIT_WORK(&dpc->work, acpi_os_execute_deferred); | ||
1133 | } else if (type == OSL_NOTIFY_HANDLER) { | ||
1134 | queue = kacpi_notify_wq; | 1141 | queue = kacpi_notify_wq; |
1135 | INIT_WORK(&dpc->work, acpi_os_execute_deferred); | 1142 | INIT_WORK(&dpc->work, acpi_os_execute_deferred); |
1136 | } else { | 1143 | } else { |
@@ -1155,28 +1162,59 @@ static acpi_status __acpi_os_execute(acpi_execute_type type, | |||
1155 | } | 1162 | } |
1156 | return status; | 1163 | return status; |
1157 | } | 1164 | } |
1165 | EXPORT_SYMBOL(acpi_os_execute); | ||
1158 | 1166 | ||
1159 | acpi_status acpi_os_execute(acpi_execute_type type, | 1167 | void acpi_os_wait_events_complete(void) |
1160 | acpi_osd_exec_callback function, void *context) | ||
1161 | { | 1168 | { |
1162 | return __acpi_os_execute(type, function, context, 0); | 1169 | flush_workqueue(kacpid_wq); |
1170 | flush_workqueue(kacpi_notify_wq); | ||
1163 | } | 1171 | } |
1164 | EXPORT_SYMBOL(acpi_os_execute); | ||
1165 | 1172 | ||
1166 | acpi_status acpi_os_hotplug_execute(acpi_osd_exec_callback function, | 1173 | struct acpi_hp_work { |
1167 | void *context) | 1174 | struct work_struct work; |
1175 | acpi_hp_callback func; | ||
1176 | void *data; | ||
1177 | u32 src; | ||
1178 | }; | ||
1179 | |||
1180 | static void acpi_hotplug_work_fn(struct work_struct *work) | ||
1168 | { | 1181 | { |
1169 | return __acpi_os_execute(0, function, context, 1); | 1182 | struct acpi_hp_work *hpw = container_of(work, struct acpi_hp_work, work); |
1183 | |||
1184 | acpi_os_wait_events_complete(); | ||
1185 | hpw->func(hpw->data, hpw->src); | ||
1186 | kfree(hpw); | ||
1170 | } | 1187 | } |
1171 | EXPORT_SYMBOL(acpi_os_hotplug_execute); | ||
1172 | 1188 | ||
1173 | void acpi_os_wait_events_complete(void) | 1189 | acpi_status acpi_hotplug_execute(acpi_hp_callback func, void *data, u32 src) |
1174 | { | 1190 | { |
1175 | flush_workqueue(kacpid_wq); | 1191 | struct acpi_hp_work *hpw; |
1176 | flush_workqueue(kacpi_notify_wq); | 1192 | |
1193 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | ||
1194 | "Scheduling function [%p(%p, %u)] for deferred execution.\n", | ||
1195 | func, data, src)); | ||
1196 | |||
1197 | hpw = kmalloc(sizeof(*hpw), GFP_KERNEL); | ||
1198 | if (!hpw) | ||
1199 | return AE_NO_MEMORY; | ||
1200 | |||
1201 | INIT_WORK(&hpw->work, acpi_hotplug_work_fn); | ||
1202 | hpw->func = func; | ||
1203 | hpw->data = data; | ||
1204 | hpw->src = src; | ||
1205 | /* | ||
1206 | * We can't run hotplug code in kacpid_wq/kacpid_notify_wq etc., because | ||
1207 | * the hotplug code may call driver .remove() functions, which may | ||
1208 | * invoke flush_scheduled_work()/acpi_os_wait_events_complete() to flush | ||
1209 | * these workqueues. | ||
1210 | */ | ||
1211 | if (!queue_work(kacpi_hotplug_wq, &hpw->work)) { | ||
1212 | kfree(hpw); | ||
1213 | return AE_ERROR; | ||
1214 | } | ||
1215 | return AE_OK; | ||
1177 | } | 1216 | } |
1178 | 1217 | ||
1179 | EXPORT_SYMBOL(acpi_os_wait_events_complete); | ||
1180 | 1218 | ||
1181 | acpi_status | 1219 | acpi_status |
1182 | acpi_os_create_semaphore(u32 max_units, u32 initial_units, acpi_handle * handle) | 1220 | acpi_os_create_semaphore(u32 max_units, u32 initial_units, acpi_handle * handle) |
@@ -1335,7 +1373,7 @@ static int __init acpi_os_name_setup(char *str) | |||
1335 | if (!str || !*str) | 1373 | if (!str || !*str) |
1336 | return 0; | 1374 | return 0; |
1337 | 1375 | ||
1338 | for (; count-- && str && *str; str++) { | 1376 | for (; count-- && *str; str++) { |
1339 | if (isalnum(*str) || *str == ' ' || *str == ':') | 1377 | if (isalnum(*str) || *str == ' ' || *str == ':') |
1340 | *p++ = *str; | 1378 | *p++ = *str; |
1341 | else if (*str == '\'' || *str == '"') | 1379 | else if (*str == '\'' || *str == '"') |
@@ -1825,25 +1863,3 @@ void acpi_os_set_prepare_extended_sleep(int (*func)(u8 sleep_state, | |||
1825 | { | 1863 | { |
1826 | __acpi_os_prepare_extended_sleep = func; | 1864 | __acpi_os_prepare_extended_sleep = func; |
1827 | } | 1865 | } |
1828 | |||
1829 | |||
1830 | void alloc_acpi_hp_work(acpi_handle handle, u32 type, void *context, | ||
1831 | void (*func)(struct work_struct *work)) | ||
1832 | { | ||
1833 | struct acpi_hp_work *hp_work; | ||
1834 | int ret; | ||
1835 | |||
1836 | hp_work = kmalloc(sizeof(*hp_work), GFP_KERNEL); | ||
1837 | if (!hp_work) | ||
1838 | return; | ||
1839 | |||
1840 | hp_work->handle = handle; | ||
1841 | hp_work->type = type; | ||
1842 | hp_work->context = context; | ||
1843 | |||
1844 | INIT_WORK(&hp_work->work, func); | ||
1845 | ret = queue_work(kacpi_hotplug_wq, &hp_work->work); | ||
1846 | if (!ret) | ||
1847 | kfree(hp_work); | ||
1848 | } | ||
1849 | EXPORT_SYMBOL_GPL(alloc_acpi_hp_work); | ||
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index d3874f425653..0703bff5e60e 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c | |||
@@ -39,6 +39,8 @@ | |||
39 | #include <acpi/acpi_drivers.h> | 39 | #include <acpi/acpi_drivers.h> |
40 | #include <acpi/apei.h> | 40 | #include <acpi/apei.h> |
41 | 41 | ||
42 | #include "internal.h" | ||
43 | |||
42 | #define PREFIX "ACPI: " | 44 | #define PREFIX "ACPI: " |
43 | 45 | ||
44 | #define _COMPONENT ACPI_PCI_COMPONENT | 46 | #define _COMPONENT ACPI_PCI_COMPONENT |
@@ -49,10 +51,10 @@ static int acpi_pci_root_add(struct acpi_device *device, | |||
49 | const struct acpi_device_id *not_used); | 51 | const struct acpi_device_id *not_used); |
50 | static void acpi_pci_root_remove(struct acpi_device *device); | 52 | static void acpi_pci_root_remove(struct acpi_device *device); |
51 | 53 | ||
52 | #define ACPI_PCIE_REQ_SUPPORT (OSC_EXT_PCI_CONFIG_SUPPORT \ | 54 | #define ACPI_PCIE_REQ_SUPPORT (OSC_PCI_EXT_CONFIG_SUPPORT \ |
53 | | OSC_ACTIVE_STATE_PWR_SUPPORT \ | 55 | | OSC_PCI_ASPM_SUPPORT \ |
54 | | OSC_CLOCK_PWR_CAPABILITY_SUPPORT \ | 56 | | OSC_PCI_CLOCK_PM_SUPPORT \ |
55 | | OSC_MSI_SUPPORT) | 57 | | OSC_PCI_MSI_SUPPORT) |
56 | 58 | ||
57 | static const struct acpi_device_id root_device_ids[] = { | 59 | static const struct acpi_device_id root_device_ids[] = { |
58 | {"PNP0A03", 0}, | 60 | {"PNP0A03", 0}, |
@@ -127,6 +129,55 @@ static acpi_status try_get_root_bridge_busnr(acpi_handle handle, | |||
127 | return AE_OK; | 129 | return AE_OK; |
128 | } | 130 | } |
129 | 131 | ||
132 | struct pci_osc_bit_struct { | ||
133 | u32 bit; | ||
134 | char *desc; | ||
135 | }; | ||
136 | |||
137 | static struct pci_osc_bit_struct pci_osc_support_bit[] = { | ||
138 | { OSC_PCI_EXT_CONFIG_SUPPORT, "ExtendedConfig" }, | ||
139 | { OSC_PCI_ASPM_SUPPORT, "ASPM" }, | ||
140 | { OSC_PCI_CLOCK_PM_SUPPORT, "ClockPM" }, | ||
141 | { OSC_PCI_SEGMENT_GROUPS_SUPPORT, "Segments" }, | ||
142 | { OSC_PCI_MSI_SUPPORT, "MSI" }, | ||
143 | }; | ||
144 | |||
145 | static struct pci_osc_bit_struct pci_osc_control_bit[] = { | ||
146 | { OSC_PCI_EXPRESS_NATIVE_HP_CONTROL, "PCIeHotplug" }, | ||
147 | { OSC_PCI_SHPC_NATIVE_HP_CONTROL, "SHPCHotplug" }, | ||
148 | { OSC_PCI_EXPRESS_PME_CONTROL, "PME" }, | ||
149 | { OSC_PCI_EXPRESS_AER_CONTROL, "AER" }, | ||
150 | { OSC_PCI_EXPRESS_CAPABILITY_CONTROL, "PCIeCapability" }, | ||
151 | }; | ||
152 | |||
153 | static void decode_osc_bits(struct acpi_pci_root *root, char *msg, u32 word, | ||
154 | struct pci_osc_bit_struct *table, int size) | ||
155 | { | ||
156 | char buf[80]; | ||
157 | int i, len = 0; | ||
158 | struct pci_osc_bit_struct *entry; | ||
159 | |||
160 | buf[0] = '\0'; | ||
161 | for (i = 0, entry = table; i < size; i++, entry++) | ||
162 | if (word & entry->bit) | ||
163 | len += snprintf(buf + len, sizeof(buf) - len, "%s%s", | ||
164 | len ? " " : "", entry->desc); | ||
165 | |||
166 | dev_info(&root->device->dev, "_OSC: %s [%s]\n", msg, buf); | ||
167 | } | ||
168 | |||
169 | static void decode_osc_support(struct acpi_pci_root *root, char *msg, u32 word) | ||
170 | { | ||
171 | decode_osc_bits(root, msg, word, pci_osc_support_bit, | ||
172 | ARRAY_SIZE(pci_osc_support_bit)); | ||
173 | } | ||
174 | |||
175 | static void decode_osc_control(struct acpi_pci_root *root, char *msg, u32 word) | ||
176 | { | ||
177 | decode_osc_bits(root, msg, word, pci_osc_control_bit, | ||
178 | ARRAY_SIZE(pci_osc_control_bit)); | ||
179 | } | ||
180 | |||
130 | static u8 pci_osc_uuid_str[] = "33DB4D5B-1FF7-401C-9657-7441C03DD766"; | 181 | static u8 pci_osc_uuid_str[] = "33DB4D5B-1FF7-401C-9657-7441C03DD766"; |
131 | 182 | ||
132 | static acpi_status acpi_pci_run_osc(acpi_handle handle, | 183 | static acpi_status acpi_pci_run_osc(acpi_handle handle, |
@@ -158,14 +209,14 @@ static acpi_status acpi_pci_query_osc(struct acpi_pci_root *root, | |||
158 | support &= OSC_PCI_SUPPORT_MASKS; | 209 | support &= OSC_PCI_SUPPORT_MASKS; |
159 | support |= root->osc_support_set; | 210 | support |= root->osc_support_set; |
160 | 211 | ||
161 | capbuf[OSC_QUERY_TYPE] = OSC_QUERY_ENABLE; | 212 | capbuf[OSC_QUERY_DWORD] = OSC_QUERY_ENABLE; |
162 | capbuf[OSC_SUPPORT_TYPE] = support; | 213 | capbuf[OSC_SUPPORT_DWORD] = support; |
163 | if (control) { | 214 | if (control) { |
164 | *control &= OSC_PCI_CONTROL_MASKS; | 215 | *control &= OSC_PCI_CONTROL_MASKS; |
165 | capbuf[OSC_CONTROL_TYPE] = *control | root->osc_control_set; | 216 | capbuf[OSC_CONTROL_DWORD] = *control | root->osc_control_set; |
166 | } else { | 217 | } else { |
167 | /* Run _OSC query only with existing controls. */ | 218 | /* Run _OSC query only with existing controls. */ |
168 | capbuf[OSC_CONTROL_TYPE] = root->osc_control_set; | 219 | capbuf[OSC_CONTROL_DWORD] = root->osc_control_set; |
169 | } | 220 | } |
170 | 221 | ||
171 | status = acpi_pci_run_osc(root->device->handle, capbuf, &result); | 222 | status = acpi_pci_run_osc(root->device->handle, capbuf, &result); |
@@ -180,11 +231,7 @@ static acpi_status acpi_pci_query_osc(struct acpi_pci_root *root, | |||
180 | static acpi_status acpi_pci_osc_support(struct acpi_pci_root *root, u32 flags) | 231 | static acpi_status acpi_pci_osc_support(struct acpi_pci_root *root, u32 flags) |
181 | { | 232 | { |
182 | acpi_status status; | 233 | acpi_status status; |
183 | acpi_handle tmp; | ||
184 | 234 | ||
185 | status = acpi_get_handle(root->device->handle, "_OSC", &tmp); | ||
186 | if (ACPI_FAILURE(status)) | ||
187 | return status; | ||
188 | mutex_lock(&osc_lock); | 235 | mutex_lock(&osc_lock); |
189 | status = acpi_pci_query_osc(root, flags, NULL); | 236 | status = acpi_pci_query_osc(root, flags, NULL); |
190 | mutex_unlock(&osc_lock); | 237 | mutex_unlock(&osc_lock); |
@@ -316,9 +363,8 @@ EXPORT_SYMBOL_GPL(acpi_get_pci_dev); | |||
316 | acpi_status acpi_pci_osc_control_set(acpi_handle handle, u32 *mask, u32 req) | 363 | acpi_status acpi_pci_osc_control_set(acpi_handle handle, u32 *mask, u32 req) |
317 | { | 364 | { |
318 | struct acpi_pci_root *root; | 365 | struct acpi_pci_root *root; |
319 | acpi_status status; | 366 | acpi_status status = AE_OK; |
320 | u32 ctrl, capbuf[3]; | 367 | u32 ctrl, capbuf[3]; |
321 | acpi_handle tmp; | ||
322 | 368 | ||
323 | if (!mask) | 369 | if (!mask) |
324 | return AE_BAD_PARAMETER; | 370 | return AE_BAD_PARAMETER; |
@@ -331,10 +377,6 @@ acpi_status acpi_pci_osc_control_set(acpi_handle handle, u32 *mask, u32 req) | |||
331 | if (!root) | 377 | if (!root) |
332 | return AE_NOT_EXIST; | 378 | return AE_NOT_EXIST; |
333 | 379 | ||
334 | status = acpi_get_handle(handle, "_OSC", &tmp); | ||
335 | if (ACPI_FAILURE(status)) | ||
336 | return status; | ||
337 | |||
338 | mutex_lock(&osc_lock); | 380 | mutex_lock(&osc_lock); |
339 | 381 | ||
340 | *mask = ctrl | root->osc_control_set; | 382 | *mask = ctrl | root->osc_control_set; |
@@ -349,17 +391,21 @@ acpi_status acpi_pci_osc_control_set(acpi_handle handle, u32 *mask, u32 req) | |||
349 | goto out; | 391 | goto out; |
350 | if (ctrl == *mask) | 392 | if (ctrl == *mask) |
351 | break; | 393 | break; |
394 | decode_osc_control(root, "platform does not support", | ||
395 | ctrl & ~(*mask)); | ||
352 | ctrl = *mask; | 396 | ctrl = *mask; |
353 | } | 397 | } |
354 | 398 | ||
355 | if ((ctrl & req) != req) { | 399 | if ((ctrl & req) != req) { |
400 | decode_osc_control(root, "not requesting control; platform does not support", | ||
401 | req & ~(ctrl)); | ||
356 | status = AE_SUPPORT; | 402 | status = AE_SUPPORT; |
357 | goto out; | 403 | goto out; |
358 | } | 404 | } |
359 | 405 | ||
360 | capbuf[OSC_QUERY_TYPE] = 0; | 406 | capbuf[OSC_QUERY_DWORD] = 0; |
361 | capbuf[OSC_SUPPORT_TYPE] = root->osc_support_set; | 407 | capbuf[OSC_SUPPORT_DWORD] = root->osc_support_set; |
362 | capbuf[OSC_CONTROL_TYPE] = ctrl; | 408 | capbuf[OSC_CONTROL_DWORD] = ctrl; |
363 | status = acpi_pci_run_osc(handle, capbuf, mask); | 409 | status = acpi_pci_run_osc(handle, capbuf, mask); |
364 | if (ACPI_SUCCESS(status)) | 410 | if (ACPI_SUCCESS(status)) |
365 | root->osc_control_set = *mask; | 411 | root->osc_control_set = *mask; |
@@ -369,6 +415,87 @@ out: | |||
369 | } | 415 | } |
370 | EXPORT_SYMBOL(acpi_pci_osc_control_set); | 416 | EXPORT_SYMBOL(acpi_pci_osc_control_set); |
371 | 417 | ||
418 | static void negotiate_os_control(struct acpi_pci_root *root, int *no_aspm, | ||
419 | int *clear_aspm) | ||
420 | { | ||
421 | u32 support, control, requested; | ||
422 | acpi_status status; | ||
423 | struct acpi_device *device = root->device; | ||
424 | acpi_handle handle = device->handle; | ||
425 | |||
426 | /* | ||
427 | * All supported architectures that use ACPI have support for | ||
428 | * PCI domains, so we indicate this in _OSC support capabilities. | ||
429 | */ | ||
430 | support = OSC_PCI_SEGMENT_GROUPS_SUPPORT; | ||
431 | if (pci_ext_cfg_avail()) | ||
432 | support |= OSC_PCI_EXT_CONFIG_SUPPORT; | ||
433 | if (pcie_aspm_support_enabled()) | ||
434 | support |= OSC_PCI_ASPM_SUPPORT | OSC_PCI_CLOCK_PM_SUPPORT; | ||
435 | if (pci_msi_enabled()) | ||
436 | support |= OSC_PCI_MSI_SUPPORT; | ||
437 | |||
438 | decode_osc_support(root, "OS supports", support); | ||
439 | status = acpi_pci_osc_support(root, support); | ||
440 | if (ACPI_FAILURE(status)) { | ||
441 | dev_info(&device->dev, "_OSC failed (%s); disabling ASPM\n", | ||
442 | acpi_format_exception(status)); | ||
443 | *no_aspm = 1; | ||
444 | return; | ||
445 | } | ||
446 | |||
447 | if (pcie_ports_disabled) { | ||
448 | dev_info(&device->dev, "PCIe port services disabled; not requesting _OSC control\n"); | ||
449 | return; | ||
450 | } | ||
451 | |||
452 | if ((support & ACPI_PCIE_REQ_SUPPORT) != ACPI_PCIE_REQ_SUPPORT) { | ||
453 | decode_osc_support(root, "not requesting OS control; OS requires", | ||
454 | ACPI_PCIE_REQ_SUPPORT); | ||
455 | return; | ||
456 | } | ||
457 | |||
458 | control = OSC_PCI_EXPRESS_CAPABILITY_CONTROL | ||
459 | | OSC_PCI_EXPRESS_NATIVE_HP_CONTROL | ||
460 | | OSC_PCI_EXPRESS_PME_CONTROL; | ||
461 | |||
462 | if (pci_aer_available()) { | ||
463 | if (aer_acpi_firmware_first()) | ||
464 | dev_info(&device->dev, | ||
465 | "PCIe AER handled by firmware\n"); | ||
466 | else | ||
467 | control |= OSC_PCI_EXPRESS_AER_CONTROL; | ||
468 | } | ||
469 | |||
470 | requested = control; | ||
471 | status = acpi_pci_osc_control_set(handle, &control, | ||
472 | OSC_PCI_EXPRESS_CAPABILITY_CONTROL); | ||
473 | if (ACPI_SUCCESS(status)) { | ||
474 | decode_osc_control(root, "OS now controls", control); | ||
475 | if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_ASPM) { | ||
476 | /* | ||
477 | * We have ASPM control, but the FADT indicates | ||
478 | * that it's unsupported. Clear it. | ||
479 | */ | ||
480 | *clear_aspm = 1; | ||
481 | } | ||
482 | } else { | ||
483 | decode_osc_control(root, "OS requested", requested); | ||
484 | decode_osc_control(root, "platform willing to grant", control); | ||
485 | dev_info(&device->dev, "_OSC failed (%s); disabling ASPM\n", | ||
486 | acpi_format_exception(status)); | ||
487 | |||
488 | /* | ||
489 | * We want to disable ASPM here, but aspm_disabled | ||
490 | * needs to remain in its state from boot so that we | ||
491 | * properly handle PCIe 1.1 devices. So we set this | ||
492 | * flag here, to defer the action until after the ACPI | ||
493 | * root scan. | ||
494 | */ | ||
495 | *no_aspm = 1; | ||
496 | } | ||
497 | } | ||
498 | |||
372 | static int acpi_pci_root_add(struct acpi_device *device, | 499 | static int acpi_pci_root_add(struct acpi_device *device, |
373 | const struct acpi_device_id *not_used) | 500 | const struct acpi_device_id *not_used) |
374 | { | 501 | { |
@@ -376,9 +503,8 @@ static int acpi_pci_root_add(struct acpi_device *device, | |||
376 | acpi_status status; | 503 | acpi_status status; |
377 | int result; | 504 | int result; |
378 | struct acpi_pci_root *root; | 505 | struct acpi_pci_root *root; |
379 | u32 flags, base_flags; | ||
380 | acpi_handle handle = device->handle; | 506 | acpi_handle handle = device->handle; |
381 | bool no_aspm = false, clear_aspm = false; | 507 | int no_aspm = 0, clear_aspm = 0; |
382 | 508 | ||
383 | root = kzalloc(sizeof(struct acpi_pci_root), GFP_KERNEL); | 509 | root = kzalloc(sizeof(struct acpi_pci_root), GFP_KERNEL); |
384 | if (!root) | 510 | if (!root) |
@@ -431,81 +557,7 @@ static int acpi_pci_root_add(struct acpi_device *device, | |||
431 | 557 | ||
432 | root->mcfg_addr = acpi_pci_root_get_mcfg_addr(handle); | 558 | root->mcfg_addr = acpi_pci_root_get_mcfg_addr(handle); |
433 | 559 | ||
434 | /* | 560 | negotiate_os_control(root, &no_aspm, &clear_aspm); |
435 | * All supported architectures that use ACPI have support for | ||
436 | * PCI domains, so we indicate this in _OSC support capabilities. | ||
437 | */ | ||
438 | flags = base_flags = OSC_PCI_SEGMENT_GROUPS_SUPPORT; | ||
439 | acpi_pci_osc_support(root, flags); | ||
440 | |||
441 | if (pci_ext_cfg_avail()) | ||
442 | flags |= OSC_EXT_PCI_CONFIG_SUPPORT; | ||
443 | if (pcie_aspm_support_enabled()) { | ||
444 | flags |= OSC_ACTIVE_STATE_PWR_SUPPORT | | ||
445 | OSC_CLOCK_PWR_CAPABILITY_SUPPORT; | ||
446 | } | ||
447 | if (pci_msi_enabled()) | ||
448 | flags |= OSC_MSI_SUPPORT; | ||
449 | if (flags != base_flags) { | ||
450 | status = acpi_pci_osc_support(root, flags); | ||
451 | if (ACPI_FAILURE(status)) { | ||
452 | dev_info(&device->dev, "ACPI _OSC support " | ||
453 | "notification failed, disabling PCIe ASPM\n"); | ||
454 | no_aspm = true; | ||
455 | flags = base_flags; | ||
456 | } | ||
457 | } | ||
458 | |||
459 | if (!pcie_ports_disabled | ||
460 | && (flags & ACPI_PCIE_REQ_SUPPORT) == ACPI_PCIE_REQ_SUPPORT) { | ||
461 | flags = OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL | ||
462 | | OSC_PCI_EXPRESS_NATIVE_HP_CONTROL | ||
463 | | OSC_PCI_EXPRESS_PME_CONTROL; | ||
464 | |||
465 | if (pci_aer_available()) { | ||
466 | if (aer_acpi_firmware_first()) | ||
467 | dev_dbg(&device->dev, | ||
468 | "PCIe errors handled by BIOS.\n"); | ||
469 | else | ||
470 | flags |= OSC_PCI_EXPRESS_AER_CONTROL; | ||
471 | } | ||
472 | |||
473 | dev_info(&device->dev, | ||
474 | "Requesting ACPI _OSC control (0x%02x)\n", flags); | ||
475 | |||
476 | status = acpi_pci_osc_control_set(handle, &flags, | ||
477 | OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL); | ||
478 | if (ACPI_SUCCESS(status)) { | ||
479 | dev_info(&device->dev, | ||
480 | "ACPI _OSC control (0x%02x) granted\n", flags); | ||
481 | if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_ASPM) { | ||
482 | /* | ||
483 | * We have ASPM control, but the FADT indicates | ||
484 | * that it's unsupported. Clear it. | ||
485 | */ | ||
486 | clear_aspm = true; | ||
487 | } | ||
488 | } else { | ||
489 | dev_info(&device->dev, | ||
490 | "ACPI _OSC request failed (%s), " | ||
491 | "returned control mask: 0x%02x\n", | ||
492 | acpi_format_exception(status), flags); | ||
493 | dev_info(&device->dev, | ||
494 | "ACPI _OSC control for PCIe not granted, disabling ASPM\n"); | ||
495 | /* | ||
496 | * We want to disable ASPM here, but aspm_disabled | ||
497 | * needs to remain in its state from boot so that we | ||
498 | * properly handle PCIe 1.1 devices. So we set this | ||
499 | * flag here, to defer the action until after the ACPI | ||
500 | * root scan. | ||
501 | */ | ||
502 | no_aspm = true; | ||
503 | } | ||
504 | } else { | ||
505 | dev_info(&device->dev, | ||
506 | "Unable to request _OSC control " | ||
507 | "(_OSC support mask: 0x%02x)\n", flags); | ||
508 | } | ||
509 | 561 | ||
510 | /* | 562 | /* |
511 | * TBD: Need PCI interface for enumeration/configuration of roots. | 563 | * TBD: Need PCI interface for enumeration/configuration of roots. |
@@ -523,6 +575,7 @@ static int acpi_pci_root_add(struct acpi_device *device, | |||
523 | dev_err(&device->dev, | 575 | dev_err(&device->dev, |
524 | "Bus %04x:%02x not present in PCI namespace\n", | 576 | "Bus %04x:%02x not present in PCI namespace\n", |
525 | root->segment, (unsigned int)root->secondary.start); | 577 | root->segment, (unsigned int)root->secondary.start); |
578 | device->driver_data = NULL; | ||
526 | result = -ENODEV; | 579 | result = -ENODEV; |
527 | goto end; | 580 | goto end; |
528 | } | 581 | } |
@@ -590,39 +643,10 @@ static void handle_root_bridge_insertion(acpi_handle handle) | |||
590 | acpi_handle_err(handle, "cannot add bridge to acpi list\n"); | 643 | acpi_handle_err(handle, "cannot add bridge to acpi list\n"); |
591 | } | 644 | } |
592 | 645 | ||
593 | static void handle_root_bridge_removal(struct acpi_device *device) | 646 | static void hotplug_event_root(void *data, u32 type) |
594 | { | ||
595 | acpi_status status; | ||
596 | struct acpi_eject_event *ej_event; | ||
597 | |||
598 | ej_event = kmalloc(sizeof(*ej_event), GFP_KERNEL); | ||
599 | if (!ej_event) { | ||
600 | /* Inform firmware the hot-remove operation has error */ | ||
601 | (void) acpi_evaluate_hotplug_ost(device->handle, | ||
602 | ACPI_NOTIFY_EJECT_REQUEST, | ||
603 | ACPI_OST_SC_NON_SPECIFIC_FAILURE, | ||
604 | NULL); | ||
605 | return; | ||
606 | } | ||
607 | |||
608 | ej_event->device = device; | ||
609 | ej_event->event = ACPI_NOTIFY_EJECT_REQUEST; | ||
610 | |||
611 | status = acpi_os_hotplug_execute(acpi_bus_hot_remove_device, ej_event); | ||
612 | if (ACPI_FAILURE(status)) | ||
613 | kfree(ej_event); | ||
614 | } | ||
615 | |||
616 | static void _handle_hotplug_event_root(struct work_struct *work) | ||
617 | { | 647 | { |
648 | acpi_handle handle = data; | ||
618 | struct acpi_pci_root *root; | 649 | struct acpi_pci_root *root; |
619 | struct acpi_hp_work *hp_work; | ||
620 | acpi_handle handle; | ||
621 | u32 type; | ||
622 | |||
623 | hp_work = container_of(work, struct acpi_hp_work, work); | ||
624 | handle = hp_work->handle; | ||
625 | type = hp_work->type; | ||
626 | 650 | ||
627 | acpi_scan_lock_acquire(); | 651 | acpi_scan_lock_acquire(); |
628 | 652 | ||
@@ -652,9 +676,15 @@ static void _handle_hotplug_event_root(struct work_struct *work) | |||
652 | /* request device eject */ | 676 | /* request device eject */ |
653 | acpi_handle_printk(KERN_DEBUG, handle, | 677 | acpi_handle_printk(KERN_DEBUG, handle, |
654 | "Device eject notify on %s\n", __func__); | 678 | "Device eject notify on %s\n", __func__); |
655 | if (root) | 679 | if (!root) |
656 | handle_root_bridge_removal(root->device); | 680 | break; |
657 | break; | 681 | |
682 | get_device(&root->device->dev); | ||
683 | |||
684 | acpi_scan_lock_release(); | ||
685 | |||
686 | acpi_bus_device_eject(root->device, ACPI_NOTIFY_EJECT_REQUEST); | ||
687 | return; | ||
658 | default: | 688 | default: |
659 | acpi_handle_warn(handle, | 689 | acpi_handle_warn(handle, |
660 | "notify_handler: unknown event type 0x%x\n", | 690 | "notify_handler: unknown event type 0x%x\n", |
@@ -663,14 +693,12 @@ static void _handle_hotplug_event_root(struct work_struct *work) | |||
663 | } | 693 | } |
664 | 694 | ||
665 | acpi_scan_lock_release(); | 695 | acpi_scan_lock_release(); |
666 | kfree(hp_work); /* allocated in handle_hotplug_event_bridge */ | ||
667 | } | 696 | } |
668 | 697 | ||
669 | static void handle_hotplug_event_root(acpi_handle handle, u32 type, | 698 | static void handle_hotplug_event_root(acpi_handle handle, u32 type, |
670 | void *context) | 699 | void *context) |
671 | { | 700 | { |
672 | alloc_acpi_hp_work(handle, type, context, | 701 | acpi_hotplug_execute(hotplug_event_root, handle, type); |
673 | _handle_hotplug_event_root); | ||
674 | } | 702 | } |
675 | 703 | ||
676 | static acpi_status __init | 704 | static acpi_status __init |
diff --git a/drivers/acpi/proc.c b/drivers/acpi/proc.c index 04a13784dd20..6a5b152ad4d0 100644 --- a/drivers/acpi/proc.c +++ b/drivers/acpi/proc.c | |||
@@ -8,289 +8,17 @@ | |||
8 | #include <acpi/acpi_bus.h> | 8 | #include <acpi/acpi_bus.h> |
9 | #include <acpi/acpi_drivers.h> | 9 | #include <acpi/acpi_drivers.h> |
10 | 10 | ||
11 | #ifdef CONFIG_X86 | ||
12 | #include <linux/mc146818rtc.h> | ||
13 | #endif | ||
14 | |||
15 | #include "sleep.h" | 11 | #include "sleep.h" |
16 | 12 | ||
17 | #define _COMPONENT ACPI_SYSTEM_COMPONENT | 13 | #define _COMPONENT ACPI_SYSTEM_COMPONENT |
18 | 14 | ||
19 | /* | 15 | /* |
20 | * this file provides support for: | 16 | * this file provides support for: |
21 | * /proc/acpi/alarm | ||
22 | * /proc/acpi/wakeup | 17 | * /proc/acpi/wakeup |
23 | */ | 18 | */ |
24 | 19 | ||
25 | ACPI_MODULE_NAME("sleep") | 20 | ACPI_MODULE_NAME("sleep") |
26 | 21 | ||
27 | #if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE) || !defined(CONFIG_X86) | ||
28 | /* use /sys/class/rtc/rtcX/wakealarm instead; it's not ACPI-specific */ | ||
29 | #else | ||
30 | #define HAVE_ACPI_LEGACY_ALARM | ||
31 | #endif | ||
32 | |||
33 | #ifdef HAVE_ACPI_LEGACY_ALARM | ||
34 | |||
35 | static u32 cmos_bcd_read(int offset, int rtc_control); | ||
36 | |||
37 | static int acpi_system_alarm_seq_show(struct seq_file *seq, void *offset) | ||
38 | { | ||
39 | u32 sec, min, hr; | ||
40 | u32 day, mo, yr, cent = 0; | ||
41 | u32 today = 0; | ||
42 | unsigned char rtc_control = 0; | ||
43 | unsigned long flags; | ||
44 | |||
45 | spin_lock_irqsave(&rtc_lock, flags); | ||
46 | |||
47 | rtc_control = CMOS_READ(RTC_CONTROL); | ||
48 | sec = cmos_bcd_read(RTC_SECONDS_ALARM, rtc_control); | ||
49 | min = cmos_bcd_read(RTC_MINUTES_ALARM, rtc_control); | ||
50 | hr = cmos_bcd_read(RTC_HOURS_ALARM, rtc_control); | ||
51 | |||
52 | /* If we ever get an FACP with proper values... */ | ||
53 | if (acpi_gbl_FADT.day_alarm) { | ||
54 | /* ACPI spec: only low 6 its should be cared */ | ||
55 | day = CMOS_READ(acpi_gbl_FADT.day_alarm) & 0x3F; | ||
56 | if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) | ||
57 | day = bcd2bin(day); | ||
58 | } else | ||
59 | day = cmos_bcd_read(RTC_DAY_OF_MONTH, rtc_control); | ||
60 | if (acpi_gbl_FADT.month_alarm) | ||
61 | mo = cmos_bcd_read(acpi_gbl_FADT.month_alarm, rtc_control); | ||
62 | else { | ||
63 | mo = cmos_bcd_read(RTC_MONTH, rtc_control); | ||
64 | today = cmos_bcd_read(RTC_DAY_OF_MONTH, rtc_control); | ||
65 | } | ||
66 | if (acpi_gbl_FADT.century) | ||
67 | cent = cmos_bcd_read(acpi_gbl_FADT.century, rtc_control); | ||
68 | |||
69 | yr = cmos_bcd_read(RTC_YEAR, rtc_control); | ||
70 | |||
71 | spin_unlock_irqrestore(&rtc_lock, flags); | ||
72 | |||
73 | /* we're trusting the FADT (see above) */ | ||
74 | if (!acpi_gbl_FADT.century) | ||
75 | /* If we're not trusting the FADT, we should at least make it | ||
76 | * right for _this_ century... ehm, what is _this_ century? | ||
77 | * | ||
78 | * TBD: | ||
79 | * ASAP: find piece of code in the kernel, e.g. star tracker driver, | ||
80 | * which we can trust to determine the century correctly. Atom | ||
81 | * watch driver would be nice, too... | ||
82 | * | ||
83 | * if that has not happened, change for first release in 2050: | ||
84 | * if (yr<50) | ||
85 | * yr += 2100; | ||
86 | * else | ||
87 | * yr += 2000; // current line of code | ||
88 | * | ||
89 | * if that has not happened either, please do on 2099/12/31:23:59:59 | ||
90 | * s/2000/2100 | ||
91 | * | ||
92 | */ | ||
93 | yr += 2000; | ||
94 | else | ||
95 | yr += cent * 100; | ||
96 | |||
97 | /* | ||
98 | * Show correct dates for alarms up to a month into the future. | ||
99 | * This solves issues for nearly all situations with the common | ||
100 | * 30-day alarm clocks in PC hardware. | ||
101 | */ | ||
102 | if (day < today) { | ||
103 | if (mo < 12) { | ||
104 | mo += 1; | ||
105 | } else { | ||
106 | mo = 1; | ||
107 | yr += 1; | ||
108 | } | ||
109 | } | ||
110 | |||
111 | seq_printf(seq, "%4.4u-", yr); | ||
112 | (mo > 12) ? seq_puts(seq, "**-") : seq_printf(seq, "%2.2u-", mo); | ||
113 | (day > 31) ? seq_puts(seq, "** ") : seq_printf(seq, "%2.2u ", day); | ||
114 | (hr > 23) ? seq_puts(seq, "**:") : seq_printf(seq, "%2.2u:", hr); | ||
115 | (min > 59) ? seq_puts(seq, "**:") : seq_printf(seq, "%2.2u:", min); | ||
116 | (sec > 59) ? seq_puts(seq, "**\n") : seq_printf(seq, "%2.2u\n", sec); | ||
117 | |||
118 | return 0; | ||
119 | } | ||
120 | |||
121 | static int acpi_system_alarm_open_fs(struct inode *inode, struct file *file) | ||
122 | { | ||
123 | return single_open(file, acpi_system_alarm_seq_show, PDE_DATA(inode)); | ||
124 | } | ||
125 | |||
126 | static int get_date_field(char **p, u32 * value) | ||
127 | { | ||
128 | char *next = NULL; | ||
129 | char *string_end = NULL; | ||
130 | int result = -EINVAL; | ||
131 | |||
132 | /* | ||
133 | * Try to find delimeter, only to insert null. The end of the | ||
134 | * string won't have one, but is still valid. | ||
135 | */ | ||
136 | if (*p == NULL) | ||
137 | return result; | ||
138 | |||
139 | next = strpbrk(*p, "- :"); | ||
140 | if (next) | ||
141 | *next++ = '\0'; | ||
142 | |||
143 | *value = simple_strtoul(*p, &string_end, 10); | ||
144 | |||
145 | /* Signal success if we got a good digit */ | ||
146 | if (string_end != *p) | ||
147 | result = 0; | ||
148 | |||
149 | if (next) | ||
150 | *p = next; | ||
151 | else | ||
152 | *p = NULL; | ||
153 | |||
154 | return result; | ||
155 | } | ||
156 | |||
157 | /* Read a possibly BCD register, always return binary */ | ||
158 | static u32 cmos_bcd_read(int offset, int rtc_control) | ||
159 | { | ||
160 | u32 val = CMOS_READ(offset); | ||
161 | if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) | ||
162 | val = bcd2bin(val); | ||
163 | return val; | ||
164 | } | ||
165 | |||
166 | /* Write binary value into possibly BCD register */ | ||
167 | static void cmos_bcd_write(u32 val, int offset, int rtc_control) | ||
168 | { | ||
169 | if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) | ||
170 | val = bin2bcd(val); | ||
171 | CMOS_WRITE(val, offset); | ||
172 | } | ||
173 | |||
174 | static ssize_t | ||
175 | acpi_system_write_alarm(struct file *file, | ||
176 | const char __user * buffer, size_t count, loff_t * ppos) | ||
177 | { | ||
178 | int result = 0; | ||
179 | char alarm_string[30] = { '\0' }; | ||
180 | char *p = alarm_string; | ||
181 | u32 sec, min, hr, day, mo, yr; | ||
182 | int adjust = 0; | ||
183 | unsigned char rtc_control = 0; | ||
184 | |||
185 | if (count > sizeof(alarm_string) - 1) | ||
186 | return -EINVAL; | ||
187 | |||
188 | if (copy_from_user(alarm_string, buffer, count)) | ||
189 | return -EFAULT; | ||
190 | |||
191 | alarm_string[count] = '\0'; | ||
192 | |||
193 | /* check for time adjustment */ | ||
194 | if (alarm_string[0] == '+') { | ||
195 | p++; | ||
196 | adjust = 1; | ||
197 | } | ||
198 | |||
199 | if ((result = get_date_field(&p, &yr))) | ||
200 | goto end; | ||
201 | if ((result = get_date_field(&p, &mo))) | ||
202 | goto end; | ||
203 | if ((result = get_date_field(&p, &day))) | ||
204 | goto end; | ||
205 | if ((result = get_date_field(&p, &hr))) | ||
206 | goto end; | ||
207 | if ((result = get_date_field(&p, &min))) | ||
208 | goto end; | ||
209 | if ((result = get_date_field(&p, &sec))) | ||
210 | goto end; | ||
211 | |||
212 | spin_lock_irq(&rtc_lock); | ||
213 | |||
214 | rtc_control = CMOS_READ(RTC_CONTROL); | ||
215 | |||
216 | if (adjust) { | ||
217 | yr += cmos_bcd_read(RTC_YEAR, rtc_control); | ||
218 | mo += cmos_bcd_read(RTC_MONTH, rtc_control); | ||
219 | day += cmos_bcd_read(RTC_DAY_OF_MONTH, rtc_control); | ||
220 | hr += cmos_bcd_read(RTC_HOURS, rtc_control); | ||
221 | min += cmos_bcd_read(RTC_MINUTES, rtc_control); | ||
222 | sec += cmos_bcd_read(RTC_SECONDS, rtc_control); | ||
223 | } | ||
224 | |||
225 | spin_unlock_irq(&rtc_lock); | ||
226 | |||
227 | if (sec > 59) { | ||
228 | min += sec/60; | ||
229 | sec = sec%60; | ||
230 | } | ||
231 | if (min > 59) { | ||
232 | hr += min/60; | ||
233 | min = min%60; | ||
234 | } | ||
235 | if (hr > 23) { | ||
236 | day += hr/24; | ||
237 | hr = hr%24; | ||
238 | } | ||
239 | if (day > 31) { | ||
240 | mo += day/32; | ||
241 | day = day%32; | ||
242 | } | ||
243 | if (mo > 12) { | ||
244 | yr += mo/13; | ||
245 | mo = mo%13; | ||
246 | } | ||
247 | |||
248 | spin_lock_irq(&rtc_lock); | ||
249 | /* | ||
250 | * Disable alarm interrupt before setting alarm timer or else | ||
251 | * when ACPI_EVENT_RTC is enabled, a spurious ACPI interrupt occurs | ||
252 | */ | ||
253 | rtc_control &= ~RTC_AIE; | ||
254 | CMOS_WRITE(rtc_control, RTC_CONTROL); | ||
255 | CMOS_READ(RTC_INTR_FLAGS); | ||
256 | |||
257 | /* write the fields the rtc knows about */ | ||
258 | cmos_bcd_write(hr, RTC_HOURS_ALARM, rtc_control); | ||
259 | cmos_bcd_write(min, RTC_MINUTES_ALARM, rtc_control); | ||
260 | cmos_bcd_write(sec, RTC_SECONDS_ALARM, rtc_control); | ||
261 | |||
262 | /* | ||
263 | * If the system supports an enhanced alarm it will have non-zero | ||
264 | * offsets into the CMOS RAM here -- which for some reason are pointing | ||
265 | * to the RTC area of memory. | ||
266 | */ | ||
267 | if (acpi_gbl_FADT.day_alarm) | ||
268 | cmos_bcd_write(day, acpi_gbl_FADT.day_alarm, rtc_control); | ||
269 | if (acpi_gbl_FADT.month_alarm) | ||
270 | cmos_bcd_write(mo, acpi_gbl_FADT.month_alarm, rtc_control); | ||
271 | if (acpi_gbl_FADT.century) { | ||
272 | if (adjust) | ||
273 | yr += cmos_bcd_read(acpi_gbl_FADT.century, rtc_control) * 100; | ||
274 | cmos_bcd_write(yr / 100, acpi_gbl_FADT.century, rtc_control); | ||
275 | } | ||
276 | /* enable the rtc alarm interrupt */ | ||
277 | rtc_control |= RTC_AIE; | ||
278 | CMOS_WRITE(rtc_control, RTC_CONTROL); | ||
279 | CMOS_READ(RTC_INTR_FLAGS); | ||
280 | |||
281 | spin_unlock_irq(&rtc_lock); | ||
282 | |||
283 | acpi_clear_event(ACPI_EVENT_RTC); | ||
284 | acpi_enable_event(ACPI_EVENT_RTC, 0); | ||
285 | |||
286 | *ppos += count; | ||
287 | |||
288 | result = 0; | ||
289 | end: | ||
290 | return result ? result : count; | ||
291 | } | ||
292 | #endif /* HAVE_ACPI_LEGACY_ALARM */ | ||
293 | |||
294 | static int | 22 | static int |
295 | acpi_system_wakeup_device_seq_show(struct seq_file *seq, void *offset) | 23 | acpi_system_wakeup_device_seq_show(struct seq_file *seq, void *offset) |
296 | { | 24 | { |
@@ -417,41 +145,8 @@ static const struct file_operations acpi_system_wakeup_device_fops = { | |||
417 | .release = single_release, | 145 | .release = single_release, |
418 | }; | 146 | }; |
419 | 147 | ||
420 | #ifdef HAVE_ACPI_LEGACY_ALARM | ||
421 | static const struct file_operations acpi_system_alarm_fops = { | ||
422 | .owner = THIS_MODULE, | ||
423 | .open = acpi_system_alarm_open_fs, | ||
424 | .read = seq_read, | ||
425 | .write = acpi_system_write_alarm, | ||
426 | .llseek = seq_lseek, | ||
427 | .release = single_release, | ||
428 | }; | ||
429 | |||
430 | static u32 rtc_handler(void *context) | ||
431 | { | ||
432 | acpi_clear_event(ACPI_EVENT_RTC); | ||
433 | acpi_disable_event(ACPI_EVENT_RTC, 0); | ||
434 | |||
435 | return ACPI_INTERRUPT_HANDLED; | ||
436 | } | ||
437 | #endif /* HAVE_ACPI_LEGACY_ALARM */ | ||
438 | |||
439 | int __init acpi_sleep_proc_init(void) | 148 | int __init acpi_sleep_proc_init(void) |
440 | { | 149 | { |
441 | #ifdef HAVE_ACPI_LEGACY_ALARM | ||
442 | /* 'alarm' [R/W] */ | ||
443 | proc_create("alarm", S_IFREG | S_IRUGO | S_IWUSR, | ||
444 | acpi_root_dir, &acpi_system_alarm_fops); | ||
445 | |||
446 | acpi_install_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler, NULL); | ||
447 | /* | ||
448 | * Disable the RTC event after installing RTC handler. | ||
449 | * Only when RTC alarm is set will it be enabled. | ||
450 | */ | ||
451 | acpi_clear_event(ACPI_EVENT_RTC); | ||
452 | acpi_disable_event(ACPI_EVENT_RTC, 0); | ||
453 | #endif /* HAVE_ACPI_LEGACY_ALARM */ | ||
454 | |||
455 | /* 'wakeup device' [R/W] */ | 150 | /* 'wakeup device' [R/W] */ |
456 | proc_create("wakeup", S_IFREG | S_IRUGO | S_IWUSR, | 151 | proc_create("wakeup", S_IFREG | S_IRUGO | S_IWUSR, |
457 | acpi_root_dir, &acpi_system_wakeup_device_fops); | 152 | acpi_root_dir, &acpi_system_wakeup_device_fops); |
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index cf34d903f4fb..b3171f30b319 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c | |||
@@ -162,16 +162,23 @@ exit: | |||
162 | return apic_id; | 162 | return apic_id; |
163 | } | 163 | } |
164 | 164 | ||
165 | int acpi_get_cpuid(acpi_handle handle, int type, u32 acpi_id) | 165 | int acpi_get_apicid(acpi_handle handle, int type, u32 acpi_id) |
166 | { | 166 | { |
167 | #ifdef CONFIG_SMP | 167 | int apic_id; |
168 | int i; | ||
169 | #endif | ||
170 | int apic_id = -1; | ||
171 | 168 | ||
172 | apic_id = map_mat_entry(handle, type, acpi_id); | 169 | apic_id = map_mat_entry(handle, type, acpi_id); |
173 | if (apic_id == -1) | 170 | if (apic_id == -1) |
174 | apic_id = map_madt_entry(type, acpi_id); | 171 | apic_id = map_madt_entry(type, acpi_id); |
172 | |||
173 | return apic_id; | ||
174 | } | ||
175 | |||
176 | int acpi_map_cpuid(int apic_id, u32 acpi_id) | ||
177 | { | ||
178 | #ifdef CONFIG_SMP | ||
179 | int i; | ||
180 | #endif | ||
181 | |||
175 | if (apic_id == -1) { | 182 | if (apic_id == -1) { |
176 | /* | 183 | /* |
177 | * On UP processor, there is no _MAT or MADT table. | 184 | * On UP processor, there is no _MAT or MADT table. |
@@ -211,6 +218,15 @@ int acpi_get_cpuid(acpi_handle handle, int type, u32 acpi_id) | |||
211 | #endif | 218 | #endif |
212 | return -1; | 219 | return -1; |
213 | } | 220 | } |
221 | |||
222 | int acpi_get_cpuid(acpi_handle handle, int type, u32 acpi_id) | ||
223 | { | ||
224 | int apic_id; | ||
225 | |||
226 | apic_id = acpi_get_apicid(handle, type, acpi_id); | ||
227 | |||
228 | return acpi_map_cpuid(apic_id, acpi_id); | ||
229 | } | ||
214 | EXPORT_SYMBOL_GPL(acpi_get_cpuid); | 230 | EXPORT_SYMBOL_GPL(acpi_get_cpuid); |
215 | 231 | ||
216 | static bool __init processor_physically_present(acpi_handle handle) | 232 | static bool __init processor_physically_present(acpi_handle handle) |
diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c index e534ba66d5b8..146ab7e2b81d 100644 --- a/drivers/acpi/processor_driver.c +++ b/drivers/acpi/processor_driver.c | |||
@@ -153,8 +153,7 @@ static int acpi_cpu_soft_notify(struct notifier_block *nfb, | |||
153 | return NOTIFY_OK; | 153 | return NOTIFY_OK; |
154 | } | 154 | } |
155 | 155 | ||
156 | static struct notifier_block __refdata acpi_cpu_notifier = | 156 | static struct notifier_block __refdata acpi_cpu_notifier = { |
157 | { | ||
158 | .notifier_call = acpi_cpu_soft_notify, | 157 | .notifier_call = acpi_cpu_soft_notify, |
159 | }; | 158 | }; |
160 | 159 | ||
@@ -172,7 +171,6 @@ static int __acpi_processor_start(struct acpi_device *device) | |||
172 | 171 | ||
173 | #ifdef CONFIG_CPU_FREQ | 172 | #ifdef CONFIG_CPU_FREQ |
174 | acpi_processor_ppc_has_changed(pr, 0); | 173 | acpi_processor_ppc_has_changed(pr, 0); |
175 | acpi_processor_load_module(pr); | ||
176 | #endif | 174 | #endif |
177 | acpi_processor_get_throttling_info(pr); | 175 | acpi_processor_get_throttling_info(pr); |
178 | 176 | ||
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index f98dd00b51a9..644516d9bde6 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c | |||
@@ -119,17 +119,10 @@ static struct dmi_system_id processor_power_dmi_table[] = { | |||
119 | */ | 119 | */ |
120 | static void acpi_safe_halt(void) | 120 | static void acpi_safe_halt(void) |
121 | { | 121 | { |
122 | current_thread_info()->status &= ~TS_POLLING; | 122 | if (!tif_need_resched()) { |
123 | /* | ||
124 | * TS_POLLING-cleared state must be visible before we | ||
125 | * test NEED_RESCHED: | ||
126 | */ | ||
127 | smp_mb(); | ||
128 | if (!need_resched()) { | ||
129 | safe_halt(); | 123 | safe_halt(); |
130 | local_irq_disable(); | 124 | local_irq_disable(); |
131 | } | 125 | } |
132 | current_thread_info()->status |= TS_POLLING; | ||
133 | } | 126 | } |
134 | 127 | ||
135 | #ifdef ARCH_APICTIMER_STOPS_ON_C3 | 128 | #ifdef ARCH_APICTIMER_STOPS_ON_C3 |
@@ -272,9 +265,6 @@ static void tsc_check_state(int state) { return; } | |||
272 | static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr) | 265 | static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr) |
273 | { | 266 | { |
274 | 267 | ||
275 | if (!pr) | ||
276 | return -EINVAL; | ||
277 | |||
278 | if (!pr->pblk) | 268 | if (!pr->pblk) |
279 | return -ENODEV; | 269 | return -ENODEV; |
280 | 270 | ||
@@ -737,6 +727,11 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev, | |||
737 | if (unlikely(!pr)) | 727 | if (unlikely(!pr)) |
738 | return -EINVAL; | 728 | return -EINVAL; |
739 | 729 | ||
730 | if (cx->entry_method == ACPI_CSTATE_FFH) { | ||
731 | if (current_set_polling_and_test()) | ||
732 | return -EINVAL; | ||
733 | } | ||
734 | |||
740 | lapic_timer_state_broadcast(pr, cx, 1); | 735 | lapic_timer_state_broadcast(pr, cx, 1); |
741 | acpi_idle_do_entry(cx); | 736 | acpi_idle_do_entry(cx); |
742 | 737 | ||
@@ -790,18 +785,9 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, | |||
790 | if (unlikely(!pr)) | 785 | if (unlikely(!pr)) |
791 | return -EINVAL; | 786 | return -EINVAL; |
792 | 787 | ||
793 | if (cx->entry_method != ACPI_CSTATE_FFH) { | 788 | if (cx->entry_method == ACPI_CSTATE_FFH) { |
794 | current_thread_info()->status &= ~TS_POLLING; | 789 | if (current_set_polling_and_test()) |
795 | /* | ||
796 | * TS_POLLING-cleared state must be visible before we test | ||
797 | * NEED_RESCHED: | ||
798 | */ | ||
799 | smp_mb(); | ||
800 | |||
801 | if (unlikely(need_resched())) { | ||
802 | current_thread_info()->status |= TS_POLLING; | ||
803 | return -EINVAL; | 790 | return -EINVAL; |
804 | } | ||
805 | } | 791 | } |
806 | 792 | ||
807 | /* | 793 | /* |
@@ -819,9 +805,6 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, | |||
819 | 805 | ||
820 | sched_clock_idle_wakeup_event(0); | 806 | sched_clock_idle_wakeup_event(0); |
821 | 807 | ||
822 | if (cx->entry_method != ACPI_CSTATE_FFH) | ||
823 | current_thread_info()->status |= TS_POLLING; | ||
824 | |||
825 | lapic_timer_state_broadcast(pr, cx, 0); | 808 | lapic_timer_state_broadcast(pr, cx, 0); |
826 | return index; | 809 | return index; |
827 | } | 810 | } |
@@ -858,18 +841,9 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, | |||
858 | } | 841 | } |
859 | } | 842 | } |
860 | 843 | ||
861 | if (cx->entry_method != ACPI_CSTATE_FFH) { | 844 | if (cx->entry_method == ACPI_CSTATE_FFH) { |
862 | current_thread_info()->status &= ~TS_POLLING; | 845 | if (current_set_polling_and_test()) |
863 | /* | ||
864 | * TS_POLLING-cleared state must be visible before we test | ||
865 | * NEED_RESCHED: | ||
866 | */ | ||
867 | smp_mb(); | ||
868 | |||
869 | if (unlikely(need_resched())) { | ||
870 | current_thread_info()->status |= TS_POLLING; | ||
871 | return -EINVAL; | 846 | return -EINVAL; |
872 | } | ||
873 | } | 847 | } |
874 | 848 | ||
875 | acpi_unlazy_tlb(smp_processor_id()); | 849 | acpi_unlazy_tlb(smp_processor_id()); |
@@ -915,9 +889,6 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, | |||
915 | 889 | ||
916 | sched_clock_idle_wakeup_event(0); | 890 | sched_clock_idle_wakeup_event(0); |
917 | 891 | ||
918 | if (cx->entry_method != ACPI_CSTATE_FFH) | ||
919 | current_thread_info()->status |= TS_POLLING; | ||
920 | |||
921 | lapic_timer_state_broadcast(pr, cx, 0); | 892 | lapic_timer_state_broadcast(pr, cx, 0); |
922 | return index; | 893 | return index; |
923 | } | 894 | } |
@@ -1076,12 +1047,8 @@ int acpi_processor_hotplug(struct acpi_processor *pr) | |||
1076 | if (disabled_by_idle_boot_param()) | 1047 | if (disabled_by_idle_boot_param()) |
1077 | return 0; | 1048 | return 0; |
1078 | 1049 | ||
1079 | if (!pr) | 1050 | if (nocst) |
1080 | return -EINVAL; | ||
1081 | |||
1082 | if (nocst) { | ||
1083 | return -ENODEV; | 1051 | return -ENODEV; |
1084 | } | ||
1085 | 1052 | ||
1086 | if (!pr->flags.power_setup_done) | 1053 | if (!pr->flags.power_setup_done) |
1087 | return -ENODEV; | 1054 | return -ENODEV; |
@@ -1108,9 +1075,6 @@ int acpi_processor_cst_has_changed(struct acpi_processor *pr) | |||
1108 | if (disabled_by_idle_boot_param()) | 1075 | if (disabled_by_idle_boot_param()) |
1109 | return 0; | 1076 | return 0; |
1110 | 1077 | ||
1111 | if (!pr) | ||
1112 | return -EINVAL; | ||
1113 | |||
1114 | if (nocst) | 1078 | if (nocst) |
1115 | return -ENODEV; | 1079 | return -ENODEV; |
1116 | 1080 | ||
@@ -1183,9 +1147,6 @@ int acpi_processor_power_init(struct acpi_processor *pr) | |||
1183 | first_run++; | 1147 | first_run++; |
1184 | } | 1148 | } |
1185 | 1149 | ||
1186 | if (!pr) | ||
1187 | return -EINVAL; | ||
1188 | |||
1189 | if (acpi_gbl_FADT.cst_control && !nocst) { | 1150 | if (acpi_gbl_FADT.cst_control && !nocst) { |
1190 | status = | 1151 | status = |
1191 | acpi_os_write_port(acpi_gbl_FADT.smi_command, acpi_gbl_FADT.cst_control, 8); | 1152 | acpi_os_write_port(acpi_gbl_FADT.smi_command, acpi_gbl_FADT.cst_control, 8); |
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index 51d7948611da..60a7c28fc167 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c | |||
@@ -235,28 +235,6 @@ void acpi_processor_ppc_exit(void) | |||
235 | acpi_processor_ppc_status &= ~PPC_REGISTERED; | 235 | acpi_processor_ppc_status &= ~PPC_REGISTERED; |
236 | } | 236 | } |
237 | 237 | ||
238 | /* | ||
239 | * Do a quick check if the systems looks like it should use ACPI | ||
240 | * cpufreq. We look at a _PCT method being available, but don't | ||
241 | * do a whole lot of sanity checks. | ||
242 | */ | ||
243 | void acpi_processor_load_module(struct acpi_processor *pr) | ||
244 | { | ||
245 | static int requested; | ||
246 | acpi_status status = 0; | ||
247 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
248 | |||
249 | if (!arch_has_acpi_pdc() || requested) | ||
250 | return; | ||
251 | status = acpi_evaluate_object(pr->handle, "_PCT", NULL, &buffer); | ||
252 | if (!ACPI_FAILURE(status)) { | ||
253 | printk(KERN_INFO PREFIX "Requesting acpi_cpufreq\n"); | ||
254 | request_module_nowait("acpi_cpufreq"); | ||
255 | requested = 1; | ||
256 | } | ||
257 | kfree(buffer.pointer); | ||
258 | } | ||
259 | |||
260 | static int acpi_processor_get_performance_control(struct acpi_processor *pr) | 238 | static int acpi_processor_get_performance_control(struct acpi_processor *pr) |
261 | { | 239 | { |
262 | int result = 0; | 240 | int result = 0; |
diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c index aef7e1cd1e5d..d465ae6cdd00 100644 --- a/drivers/acpi/sbs.c +++ b/drivers/acpi/sbs.c | |||
@@ -30,12 +30,6 @@ | |||
30 | #include <linux/moduleparam.h> | 30 | #include <linux/moduleparam.h> |
31 | #include <linux/kernel.h> | 31 | #include <linux/kernel.h> |
32 | 32 | ||
33 | #ifdef CONFIG_ACPI_PROCFS_POWER | ||
34 | #include <linux/proc_fs.h> | ||
35 | #include <linux/seq_file.h> | ||
36 | #include <asm/uaccess.h> | ||
37 | #endif | ||
38 | |||
39 | #include <linux/acpi.h> | 33 | #include <linux/acpi.h> |
40 | #include <linux/timer.h> | 34 | #include <linux/timer.h> |
41 | #include <linux/jiffies.h> | 35 | #include <linux/jiffies.h> |
@@ -67,11 +61,6 @@ static unsigned int cache_time = 1000; | |||
67 | module_param(cache_time, uint, 0644); | 61 | module_param(cache_time, uint, 0644); |
68 | MODULE_PARM_DESC(cache_time, "cache time in milliseconds"); | 62 | MODULE_PARM_DESC(cache_time, "cache time in milliseconds"); |
69 | 63 | ||
70 | extern struct proc_dir_entry *acpi_lock_ac_dir(void); | ||
71 | extern struct proc_dir_entry *acpi_lock_battery_dir(void); | ||
72 | extern void acpi_unlock_ac_dir(struct proc_dir_entry *acpi_ac_dir); | ||
73 | extern void acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir); | ||
74 | |||
75 | #define MAX_SBS_BAT 4 | 64 | #define MAX_SBS_BAT 4 |
76 | #define ACPI_SBS_BLOCK_MAX 32 | 65 | #define ACPI_SBS_BLOCK_MAX 32 |
77 | 66 | ||
@@ -84,9 +73,6 @@ MODULE_DEVICE_TABLE(acpi, sbs_device_ids); | |||
84 | struct acpi_battery { | 73 | struct acpi_battery { |
85 | struct power_supply bat; | 74 | struct power_supply bat; |
86 | struct acpi_sbs *sbs; | 75 | struct acpi_sbs *sbs; |
87 | #ifdef CONFIG_ACPI_PROCFS_POWER | ||
88 | struct proc_dir_entry *proc_entry; | ||
89 | #endif | ||
90 | unsigned long update_time; | 76 | unsigned long update_time; |
91 | char name[8]; | 77 | char name[8]; |
92 | char manufacturer_name[ACPI_SBS_BLOCK_MAX]; | 78 | char manufacturer_name[ACPI_SBS_BLOCK_MAX]; |
@@ -119,9 +105,6 @@ struct acpi_sbs { | |||
119 | struct acpi_device *device; | 105 | struct acpi_device *device; |
120 | struct acpi_smb_hc *hc; | 106 | struct acpi_smb_hc *hc; |
121 | struct mutex lock; | 107 | struct mutex lock; |
122 | #ifdef CONFIG_ACPI_PROCFS_POWER | ||
123 | struct proc_dir_entry *charger_entry; | ||
124 | #endif | ||
125 | struct acpi_battery battery[MAX_SBS_BAT]; | 108 | struct acpi_battery battery[MAX_SBS_BAT]; |
126 | u8 batteries_supported:4; | 109 | u8 batteries_supported:4; |
127 | u8 manager_present:1; | 110 | u8 manager_present:1; |
@@ -482,261 +465,6 @@ static struct device_attribute alarm_attr = { | |||
482 | }; | 465 | }; |
483 | 466 | ||
484 | /* -------------------------------------------------------------------------- | 467 | /* -------------------------------------------------------------------------- |
485 | FS Interface (/proc/acpi) | ||
486 | -------------------------------------------------------------------------- */ | ||
487 | |||
488 | #ifdef CONFIG_ACPI_PROCFS_POWER | ||
489 | /* Generic Routines */ | ||
490 | static int | ||
491 | acpi_sbs_add_fs(struct proc_dir_entry **dir, | ||
492 | struct proc_dir_entry *parent_dir, | ||
493 | char *dir_name, | ||
494 | const struct file_operations *info_fops, | ||
495 | const struct file_operations *state_fops, | ||
496 | const struct file_operations *alarm_fops, void *data) | ||
497 | { | ||
498 | printk(KERN_WARNING PREFIX "Deprecated procfs I/F for SBS is loaded," | ||
499 | " please retry with CONFIG_ACPI_PROCFS_POWER cleared\n"); | ||
500 | if (!*dir) { | ||
501 | *dir = proc_mkdir(dir_name, parent_dir); | ||
502 | if (!*dir) { | ||
503 | return -ENODEV; | ||
504 | } | ||
505 | } | ||
506 | |||
507 | /* 'info' [R] */ | ||
508 | if (info_fops) | ||
509 | proc_create_data(ACPI_SBS_FILE_INFO, S_IRUGO, *dir, | ||
510 | info_fops, data); | ||
511 | |||
512 | /* 'state' [R] */ | ||
513 | if (state_fops) | ||
514 | proc_create_data(ACPI_SBS_FILE_STATE, S_IRUGO, *dir, | ||
515 | state_fops, data); | ||
516 | |||
517 | /* 'alarm' [R/W] */ | ||
518 | if (alarm_fops) | ||
519 | proc_create_data(ACPI_SBS_FILE_ALARM, S_IRUGO, *dir, | ||
520 | alarm_fops, data); | ||
521 | return 0; | ||
522 | } | ||
523 | |||
524 | /* Smart Battery Interface */ | ||
525 | static struct proc_dir_entry *acpi_battery_dir = NULL; | ||
526 | |||
527 | static inline char *acpi_battery_units(struct acpi_battery *battery) | ||
528 | { | ||
529 | return acpi_battery_mode(battery) ? " mW" : " mA"; | ||
530 | } | ||
531 | |||
532 | |||
533 | static int acpi_battery_read_info(struct seq_file *seq, void *offset) | ||
534 | { | ||
535 | struct acpi_battery *battery = seq->private; | ||
536 | struct acpi_sbs *sbs = battery->sbs; | ||
537 | int result = 0; | ||
538 | |||
539 | mutex_lock(&sbs->lock); | ||
540 | |||
541 | seq_printf(seq, "present: %s\n", | ||
542 | (battery->present) ? "yes" : "no"); | ||
543 | if (!battery->present) | ||
544 | goto end; | ||
545 | |||
546 | seq_printf(seq, "design capacity: %i%sh\n", | ||
547 | battery->design_capacity * acpi_battery_scale(battery), | ||
548 | acpi_battery_units(battery)); | ||
549 | seq_printf(seq, "last full capacity: %i%sh\n", | ||
550 | battery->full_charge_capacity * acpi_battery_scale(battery), | ||
551 | acpi_battery_units(battery)); | ||
552 | seq_printf(seq, "battery technology: rechargeable\n"); | ||
553 | seq_printf(seq, "design voltage: %i mV\n", | ||
554 | battery->design_voltage * acpi_battery_vscale(battery)); | ||
555 | seq_printf(seq, "design capacity warning: unknown\n"); | ||
556 | seq_printf(seq, "design capacity low: unknown\n"); | ||
557 | seq_printf(seq, "cycle count: %i\n", battery->cycle_count); | ||
558 | seq_printf(seq, "capacity granularity 1: unknown\n"); | ||
559 | seq_printf(seq, "capacity granularity 2: unknown\n"); | ||
560 | seq_printf(seq, "model number: %s\n", battery->device_name); | ||
561 | seq_printf(seq, "serial number: %i\n", | ||
562 | battery->serial_number); | ||
563 | seq_printf(seq, "battery type: %s\n", | ||
564 | battery->device_chemistry); | ||
565 | seq_printf(seq, "OEM info: %s\n", | ||
566 | battery->manufacturer_name); | ||
567 | end: | ||
568 | mutex_unlock(&sbs->lock); | ||
569 | return result; | ||
570 | } | ||
571 | |||
572 | static int acpi_battery_info_open_fs(struct inode *inode, struct file *file) | ||
573 | { | ||
574 | return single_open(file, acpi_battery_read_info, PDE_DATA(inode)); | ||
575 | } | ||
576 | |||
577 | static int acpi_battery_read_state(struct seq_file *seq, void *offset) | ||
578 | { | ||
579 | struct acpi_battery *battery = seq->private; | ||
580 | struct acpi_sbs *sbs = battery->sbs; | ||
581 | int rate; | ||
582 | |||
583 | mutex_lock(&sbs->lock); | ||
584 | seq_printf(seq, "present: %s\n", | ||
585 | (battery->present) ? "yes" : "no"); | ||
586 | if (!battery->present) | ||
587 | goto end; | ||
588 | |||
589 | acpi_battery_get_state(battery); | ||
590 | seq_printf(seq, "capacity state: %s\n", | ||
591 | (battery->state & 0x0010) ? "critical" : "ok"); | ||
592 | seq_printf(seq, "charging state: %s\n", | ||
593 | (battery->rate_now < 0) ? "discharging" : | ||
594 | ((battery->rate_now > 0) ? "charging" : "charged")); | ||
595 | rate = abs(battery->rate_now) * acpi_battery_ipscale(battery); | ||
596 | rate *= (acpi_battery_mode(battery))?(battery->voltage_now * | ||
597 | acpi_battery_vscale(battery)/1000):1; | ||
598 | seq_printf(seq, "present rate: %d%s\n", rate, | ||
599 | acpi_battery_units(battery)); | ||
600 | seq_printf(seq, "remaining capacity: %i%sh\n", | ||
601 | battery->capacity_now * acpi_battery_scale(battery), | ||
602 | acpi_battery_units(battery)); | ||
603 | seq_printf(seq, "present voltage: %i mV\n", | ||
604 | battery->voltage_now * acpi_battery_vscale(battery)); | ||
605 | |||
606 | end: | ||
607 | mutex_unlock(&sbs->lock); | ||
608 | return 0; | ||
609 | } | ||
610 | |||
611 | static int acpi_battery_state_open_fs(struct inode *inode, struct file *file) | ||
612 | { | ||
613 | return single_open(file, acpi_battery_read_state, PDE_DATA(inode)); | ||
614 | } | ||
615 | |||
616 | static int acpi_battery_read_alarm(struct seq_file *seq, void *offset) | ||
617 | { | ||
618 | struct acpi_battery *battery = seq->private; | ||
619 | struct acpi_sbs *sbs = battery->sbs; | ||
620 | int result = 0; | ||
621 | |||
622 | mutex_lock(&sbs->lock); | ||
623 | |||
624 | if (!battery->present) { | ||
625 | seq_printf(seq, "present: no\n"); | ||
626 | goto end; | ||
627 | } | ||
628 | |||
629 | acpi_battery_get_alarm(battery); | ||
630 | seq_printf(seq, "alarm: "); | ||
631 | if (battery->alarm_capacity) | ||
632 | seq_printf(seq, "%i%sh\n", | ||
633 | battery->alarm_capacity * | ||
634 | acpi_battery_scale(battery), | ||
635 | acpi_battery_units(battery)); | ||
636 | else | ||
637 | seq_printf(seq, "disabled\n"); | ||
638 | end: | ||
639 | mutex_unlock(&sbs->lock); | ||
640 | return result; | ||
641 | } | ||
642 | |||
643 | static ssize_t | ||
644 | acpi_battery_write_alarm(struct file *file, const char __user * buffer, | ||
645 | size_t count, loff_t * ppos) | ||
646 | { | ||
647 | struct seq_file *seq = file->private_data; | ||
648 | struct acpi_battery *battery = seq->private; | ||
649 | struct acpi_sbs *sbs = battery->sbs; | ||
650 | char alarm_string[12] = { '\0' }; | ||
651 | int result = 0; | ||
652 | mutex_lock(&sbs->lock); | ||
653 | if (!battery->present) { | ||
654 | result = -ENODEV; | ||
655 | goto end; | ||
656 | } | ||
657 | if (count > sizeof(alarm_string) - 1) { | ||
658 | result = -EINVAL; | ||
659 | goto end; | ||
660 | } | ||
661 | if (copy_from_user(alarm_string, buffer, count)) { | ||
662 | result = -EFAULT; | ||
663 | goto end; | ||
664 | } | ||
665 | alarm_string[count] = 0; | ||
666 | battery->alarm_capacity = simple_strtoul(alarm_string, NULL, 0) / | ||
667 | acpi_battery_scale(battery); | ||
668 | acpi_battery_set_alarm(battery); | ||
669 | end: | ||
670 | mutex_unlock(&sbs->lock); | ||
671 | if (result) | ||
672 | return result; | ||
673 | return count; | ||
674 | } | ||
675 | |||
676 | static int acpi_battery_alarm_open_fs(struct inode *inode, struct file *file) | ||
677 | { | ||
678 | return single_open(file, acpi_battery_read_alarm, PDE_DATA(inode)); | ||
679 | } | ||
680 | |||
681 | static const struct file_operations acpi_battery_info_fops = { | ||
682 | .open = acpi_battery_info_open_fs, | ||
683 | .read = seq_read, | ||
684 | .llseek = seq_lseek, | ||
685 | .release = single_release, | ||
686 | .owner = THIS_MODULE, | ||
687 | }; | ||
688 | |||
689 | static const struct file_operations acpi_battery_state_fops = { | ||
690 | .open = acpi_battery_state_open_fs, | ||
691 | .read = seq_read, | ||
692 | .llseek = seq_lseek, | ||
693 | .release = single_release, | ||
694 | .owner = THIS_MODULE, | ||
695 | }; | ||
696 | |||
697 | static const struct file_operations acpi_battery_alarm_fops = { | ||
698 | .open = acpi_battery_alarm_open_fs, | ||
699 | .read = seq_read, | ||
700 | .write = acpi_battery_write_alarm, | ||
701 | .llseek = seq_lseek, | ||
702 | .release = single_release, | ||
703 | .owner = THIS_MODULE, | ||
704 | }; | ||
705 | |||
706 | /* Legacy AC Adapter Interface */ | ||
707 | |||
708 | static struct proc_dir_entry *acpi_ac_dir = NULL; | ||
709 | |||
710 | static int acpi_ac_read_state(struct seq_file *seq, void *offset) | ||
711 | { | ||
712 | |||
713 | struct acpi_sbs *sbs = seq->private; | ||
714 | |||
715 | mutex_lock(&sbs->lock); | ||
716 | |||
717 | seq_printf(seq, "state: %s\n", | ||
718 | sbs->charger_present ? "on-line" : "off-line"); | ||
719 | |||
720 | mutex_unlock(&sbs->lock); | ||
721 | return 0; | ||
722 | } | ||
723 | |||
724 | static int acpi_ac_state_open_fs(struct inode *inode, struct file *file) | ||
725 | { | ||
726 | return single_open(file, acpi_ac_read_state, PDE_DATA(inode)); | ||
727 | } | ||
728 | |||
729 | static const struct file_operations acpi_ac_state_fops = { | ||
730 | .open = acpi_ac_state_open_fs, | ||
731 | .read = seq_read, | ||
732 | .llseek = seq_lseek, | ||
733 | .release = single_release, | ||
734 | .owner = THIS_MODULE, | ||
735 | }; | ||
736 | |||
737 | #endif | ||
738 | |||
739 | /* -------------------------------------------------------------------------- | ||
740 | Driver Interface | 468 | Driver Interface |
741 | -------------------------------------------------------------------------- */ | 469 | -------------------------------------------------------------------------- */ |
742 | static int acpi_battery_read(struct acpi_battery *battery) | 470 | static int acpi_battery_read(struct acpi_battery *battery) |
@@ -781,12 +509,6 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id) | |||
781 | return result; | 509 | return result; |
782 | 510 | ||
783 | sprintf(battery->name, ACPI_BATTERY_DIR_NAME, id); | 511 | sprintf(battery->name, ACPI_BATTERY_DIR_NAME, id); |
784 | #ifdef CONFIG_ACPI_PROCFS_POWER | ||
785 | acpi_sbs_add_fs(&battery->proc_entry, acpi_battery_dir, | ||
786 | battery->name, &acpi_battery_info_fops, | ||
787 | &acpi_battery_state_fops, &acpi_battery_alarm_fops, | ||
788 | battery); | ||
789 | #endif | ||
790 | battery->bat.name = battery->name; | 512 | battery->bat.name = battery->name; |
791 | battery->bat.type = POWER_SUPPLY_TYPE_BATTERY; | 513 | battery->bat.type = POWER_SUPPLY_TYPE_BATTERY; |
792 | if (!acpi_battery_mode(battery)) { | 514 | if (!acpi_battery_mode(battery)) { |
@@ -822,10 +544,6 @@ static void acpi_battery_remove(struct acpi_sbs *sbs, int id) | |||
822 | device_remove_file(battery->bat.dev, &alarm_attr); | 544 | device_remove_file(battery->bat.dev, &alarm_attr); |
823 | power_supply_unregister(&battery->bat); | 545 | power_supply_unregister(&battery->bat); |
824 | } | 546 | } |
825 | #ifdef CONFIG_ACPI_PROCFS_POWER | ||
826 | proc_remove(battery->proc_entry); | ||
827 | battery->proc_entry = NULL; | ||
828 | #endif | ||
829 | } | 547 | } |
830 | 548 | ||
831 | static int acpi_charger_add(struct acpi_sbs *sbs) | 549 | static int acpi_charger_add(struct acpi_sbs *sbs) |
@@ -835,13 +553,7 @@ static int acpi_charger_add(struct acpi_sbs *sbs) | |||
835 | result = acpi_ac_get_present(sbs); | 553 | result = acpi_ac_get_present(sbs); |
836 | if (result) | 554 | if (result) |
837 | goto end; | 555 | goto end; |
838 | #ifdef CONFIG_ACPI_PROCFS_POWER | 556 | |
839 | result = acpi_sbs_add_fs(&sbs->charger_entry, acpi_ac_dir, | ||
840 | ACPI_AC_DIR_NAME, NULL, | ||
841 | &acpi_ac_state_fops, NULL, sbs); | ||
842 | if (result) | ||
843 | goto end; | ||
844 | #endif | ||
845 | sbs->charger.name = "sbs-charger"; | 557 | sbs->charger.name = "sbs-charger"; |
846 | sbs->charger.type = POWER_SUPPLY_TYPE_MAINS; | 558 | sbs->charger.type = POWER_SUPPLY_TYPE_MAINS; |
847 | sbs->charger.properties = sbs_ac_props; | 559 | sbs->charger.properties = sbs_ac_props; |
@@ -859,10 +571,6 @@ static void acpi_charger_remove(struct acpi_sbs *sbs) | |||
859 | { | 571 | { |
860 | if (sbs->charger.dev) | 572 | if (sbs->charger.dev) |
861 | power_supply_unregister(&sbs->charger); | 573 | power_supply_unregister(&sbs->charger); |
862 | #ifdef CONFIG_ACPI_PROCFS_POWER | ||
863 | proc_remove(sbs->charger_entry); | ||
864 | sbs->charger_entry = NULL; | ||
865 | #endif | ||
866 | } | 574 | } |
867 | 575 | ||
868 | static void acpi_sbs_callback(void *context) | 576 | static void acpi_sbs_callback(void *context) |
@@ -950,20 +658,6 @@ static int acpi_sbs_remove(struct acpi_device *device) | |||
950 | return 0; | 658 | return 0; |
951 | } | 659 | } |
952 | 660 | ||
953 | static void acpi_sbs_rmdirs(void) | ||
954 | { | ||
955 | #ifdef CONFIG_ACPI_PROCFS_POWER | ||
956 | if (acpi_ac_dir) { | ||
957 | acpi_unlock_ac_dir(acpi_ac_dir); | ||
958 | acpi_ac_dir = NULL; | ||
959 | } | ||
960 | if (acpi_battery_dir) { | ||
961 | acpi_unlock_battery_dir(acpi_battery_dir); | ||
962 | acpi_battery_dir = NULL; | ||
963 | } | ||
964 | #endif | ||
965 | } | ||
966 | |||
967 | #ifdef CONFIG_PM_SLEEP | 661 | #ifdef CONFIG_PM_SLEEP |
968 | static int acpi_sbs_resume(struct device *dev) | 662 | static int acpi_sbs_resume(struct device *dev) |
969 | { | 663 | { |
@@ -995,28 +689,17 @@ static int __init acpi_sbs_init(void) | |||
995 | 689 | ||
996 | if (acpi_disabled) | 690 | if (acpi_disabled) |
997 | return -ENODEV; | 691 | return -ENODEV; |
998 | #ifdef CONFIG_ACPI_PROCFS_POWER | 692 | |
999 | acpi_ac_dir = acpi_lock_ac_dir(); | ||
1000 | if (!acpi_ac_dir) | ||
1001 | return -ENODEV; | ||
1002 | acpi_battery_dir = acpi_lock_battery_dir(); | ||
1003 | if (!acpi_battery_dir) { | ||
1004 | acpi_sbs_rmdirs(); | ||
1005 | return -ENODEV; | ||
1006 | } | ||
1007 | #endif | ||
1008 | result = acpi_bus_register_driver(&acpi_sbs_driver); | 693 | result = acpi_bus_register_driver(&acpi_sbs_driver); |
1009 | if (result < 0) { | 694 | if (result < 0) |
1010 | acpi_sbs_rmdirs(); | ||
1011 | return -ENODEV; | 695 | return -ENODEV; |
1012 | } | 696 | |
1013 | return 0; | 697 | return 0; |
1014 | } | 698 | } |
1015 | 699 | ||
1016 | static void __exit acpi_sbs_exit(void) | 700 | static void __exit acpi_sbs_exit(void) |
1017 | { | 701 | { |
1018 | acpi_bus_unregister_driver(&acpi_sbs_driver); | 702 | acpi_bus_unregister_driver(&acpi_sbs_driver); |
1019 | acpi_sbs_rmdirs(); | ||
1020 | return; | 703 | return; |
1021 | } | 704 | } |
1022 | 705 | ||
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index fee8a297c7d9..15daa21fcd05 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
@@ -125,8 +125,8 @@ acpi_device_modalias_show(struct device *dev, struct device_attribute *attr, cha | |||
125 | } | 125 | } |
126 | static DEVICE_ATTR(modalias, 0444, acpi_device_modalias_show, NULL); | 126 | static DEVICE_ATTR(modalias, 0444, acpi_device_modalias_show, NULL); |
127 | 127 | ||
128 | static acpi_status acpi_bus_offline_companions(acpi_handle handle, u32 lvl, | 128 | static acpi_status acpi_bus_offline(acpi_handle handle, u32 lvl, void *data, |
129 | void *data, void **ret_p) | 129 | void **ret_p) |
130 | { | 130 | { |
131 | struct acpi_device *device = NULL; | 131 | struct acpi_device *device = NULL; |
132 | struct acpi_device_physical_node *pn; | 132 | struct acpi_device_physical_node *pn; |
@@ -136,6 +136,11 @@ static acpi_status acpi_bus_offline_companions(acpi_handle handle, u32 lvl, | |||
136 | if (acpi_bus_get_device(handle, &device)) | 136 | if (acpi_bus_get_device(handle, &device)) |
137 | return AE_OK; | 137 | return AE_OK; |
138 | 138 | ||
139 | if (device->handler && !device->handler->hotplug.enabled) { | ||
140 | *ret_p = &device->dev; | ||
141 | return AE_SUPPORT; | ||
142 | } | ||
143 | |||
139 | mutex_lock(&device->physical_node_lock); | 144 | mutex_lock(&device->physical_node_lock); |
140 | 145 | ||
141 | list_for_each_entry(pn, &device->physical_node_list, node) { | 146 | list_for_each_entry(pn, &device->physical_node_list, node) { |
@@ -168,8 +173,8 @@ static acpi_status acpi_bus_offline_companions(acpi_handle handle, u32 lvl, | |||
168 | return status; | 173 | return status; |
169 | } | 174 | } |
170 | 175 | ||
171 | static acpi_status acpi_bus_online_companions(acpi_handle handle, u32 lvl, | 176 | static acpi_status acpi_bus_online(acpi_handle handle, u32 lvl, void *data, |
172 | void *data, void **ret_p) | 177 | void **ret_p) |
173 | { | 178 | { |
174 | struct acpi_device *device = NULL; | 179 | struct acpi_device *device = NULL; |
175 | struct acpi_device_physical_node *pn; | 180 | struct acpi_device_physical_node *pn; |
@@ -214,26 +219,32 @@ static int acpi_scan_hot_remove(struct acpi_device *device) | |||
214 | * If the first pass is successful, the second one isn't needed, though. | 219 | * If the first pass is successful, the second one isn't needed, though. |
215 | */ | 220 | */ |
216 | errdev = NULL; | 221 | errdev = NULL; |
217 | acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX, | 222 | status = acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX, |
218 | NULL, acpi_bus_offline_companions, | 223 | NULL, acpi_bus_offline, (void *)false, |
219 | (void *)false, (void **)&errdev); | 224 | (void **)&errdev); |
220 | acpi_bus_offline_companions(handle, 0, (void *)false, (void **)&errdev); | 225 | if (status == AE_SUPPORT) { |
226 | dev_warn(errdev, "Offline disabled.\n"); | ||
227 | acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX, | ||
228 | acpi_bus_online, NULL, NULL, NULL); | ||
229 | put_device(&device->dev); | ||
230 | return -EPERM; | ||
231 | } | ||
232 | acpi_bus_offline(handle, 0, (void *)false, (void **)&errdev); | ||
221 | if (errdev) { | 233 | if (errdev) { |
222 | errdev = NULL; | 234 | errdev = NULL; |
223 | acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX, | 235 | acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX, |
224 | NULL, acpi_bus_offline_companions, | 236 | NULL, acpi_bus_offline, (void *)true, |
225 | (void *)true , (void **)&errdev); | 237 | (void **)&errdev); |
226 | if (!errdev || acpi_force_hot_remove) | 238 | if (!errdev || acpi_force_hot_remove) |
227 | acpi_bus_offline_companions(handle, 0, (void *)true, | 239 | acpi_bus_offline(handle, 0, (void *)true, |
228 | (void **)&errdev); | 240 | (void **)&errdev); |
229 | 241 | ||
230 | if (errdev && !acpi_force_hot_remove) { | 242 | if (errdev && !acpi_force_hot_remove) { |
231 | dev_warn(errdev, "Offline failed.\n"); | 243 | dev_warn(errdev, "Offline failed.\n"); |
232 | acpi_bus_online_companions(handle, 0, NULL, NULL); | 244 | acpi_bus_online(handle, 0, NULL, NULL); |
233 | acpi_walk_namespace(ACPI_TYPE_ANY, handle, | 245 | acpi_walk_namespace(ACPI_TYPE_ANY, handle, |
234 | ACPI_UINT32_MAX, | 246 | ACPI_UINT32_MAX, acpi_bus_online, |
235 | acpi_bus_online_companions, NULL, | 247 | NULL, NULL, NULL); |
236 | NULL, NULL); | ||
237 | put_device(&device->dev); | 248 | put_device(&device->dev); |
238 | return -EBUSY; | 249 | return -EBUSY; |
239 | } | 250 | } |
@@ -274,49 +285,45 @@ static int acpi_scan_hot_remove(struct acpi_device *device) | |||
274 | return 0; | 285 | return 0; |
275 | } | 286 | } |
276 | 287 | ||
277 | static void acpi_bus_device_eject(void *context) | 288 | void acpi_bus_device_eject(void *data, u32 ost_src) |
278 | { | 289 | { |
279 | acpi_handle handle = context; | 290 | struct acpi_device *device = data; |
280 | struct acpi_device *device = NULL; | 291 | acpi_handle handle = device->handle; |
281 | struct acpi_scan_handler *handler; | ||
282 | u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; | 292 | u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; |
283 | int error; | 293 | int error; |
284 | 294 | ||
285 | lock_device_hotplug(); | 295 | lock_device_hotplug(); |
286 | mutex_lock(&acpi_scan_lock); | 296 | mutex_lock(&acpi_scan_lock); |
287 | 297 | ||
288 | acpi_bus_get_device(handle, &device); | 298 | if (ost_src == ACPI_NOTIFY_EJECT_REQUEST) |
289 | if (!device) | 299 | acpi_evaluate_hotplug_ost(handle, ACPI_NOTIFY_EJECT_REQUEST, |
290 | goto err_out; | 300 | ACPI_OST_SC_EJECT_IN_PROGRESS, NULL); |
291 | 301 | ||
292 | handler = device->handler; | 302 | if (device->handler && device->handler->hotplug.mode == AHM_CONTAINER) |
293 | if (!handler || !handler->hotplug.enabled) { | ||
294 | ost_code = ACPI_OST_SC_EJECT_NOT_SUPPORTED; | ||
295 | goto err_out; | ||
296 | } | ||
297 | acpi_evaluate_hotplug_ost(handle, ACPI_NOTIFY_EJECT_REQUEST, | ||
298 | ACPI_OST_SC_EJECT_IN_PROGRESS, NULL); | ||
299 | if (handler->hotplug.mode == AHM_CONTAINER) | ||
300 | kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE); | 303 | kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE); |
301 | 304 | ||
302 | get_device(&device->dev); | ||
303 | error = acpi_scan_hot_remove(device); | 305 | error = acpi_scan_hot_remove(device); |
304 | if (error) | 306 | if (error == -EPERM) { |
307 | goto err_support; | ||
308 | } else if (error) { | ||
305 | goto err_out; | 309 | goto err_out; |
310 | } | ||
306 | 311 | ||
307 | out: | 312 | out: |
308 | mutex_unlock(&acpi_scan_lock); | 313 | mutex_unlock(&acpi_scan_lock); |
309 | unlock_device_hotplug(); | 314 | unlock_device_hotplug(); |
310 | return; | 315 | return; |
311 | 316 | ||
317 | err_support: | ||
318 | ost_code = ACPI_OST_SC_EJECT_NOT_SUPPORTED; | ||
312 | err_out: | 319 | err_out: |
313 | acpi_evaluate_hotplug_ost(handle, ACPI_NOTIFY_EJECT_REQUEST, ost_code, | 320 | acpi_evaluate_hotplug_ost(handle, ost_src, ost_code, NULL); |
314 | NULL); | ||
315 | goto out; | 321 | goto out; |
316 | } | 322 | } |
317 | 323 | ||
318 | static void acpi_scan_bus_device_check(acpi_handle handle, u32 ost_source) | 324 | static void acpi_scan_bus_device_check(void *data, u32 ost_source) |
319 | { | 325 | { |
326 | acpi_handle handle = data; | ||
320 | struct acpi_device *device = NULL; | 327 | struct acpi_device *device = NULL; |
321 | u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; | 328 | u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; |
322 | int error; | 329 | int error; |
@@ -331,8 +338,6 @@ static void acpi_scan_bus_device_check(acpi_handle handle, u32 ost_source) | |||
331 | goto out; | 338 | goto out; |
332 | } | 339 | } |
333 | } | 340 | } |
334 | acpi_evaluate_hotplug_ost(handle, ost_source, | ||
335 | ACPI_OST_SC_INSERT_IN_PROGRESS, NULL); | ||
336 | error = acpi_bus_scan(handle); | 341 | error = acpi_bus_scan(handle); |
337 | if (error) { | 342 | if (error) { |
338 | acpi_handle_warn(handle, "Namespace scan failure\n"); | 343 | acpi_handle_warn(handle, "Namespace scan failure\n"); |
@@ -353,18 +358,6 @@ static void acpi_scan_bus_device_check(acpi_handle handle, u32 ost_source) | |||
353 | unlock_device_hotplug(); | 358 | unlock_device_hotplug(); |
354 | } | 359 | } |
355 | 360 | ||
356 | static void acpi_scan_bus_check(void *context) | ||
357 | { | ||
358 | acpi_scan_bus_device_check((acpi_handle)context, | ||
359 | ACPI_NOTIFY_BUS_CHECK); | ||
360 | } | ||
361 | |||
362 | static void acpi_scan_device_check(void *context) | ||
363 | { | ||
364 | acpi_scan_bus_device_check((acpi_handle)context, | ||
365 | ACPI_NOTIFY_DEVICE_CHECK); | ||
366 | } | ||
367 | |||
368 | static void acpi_hotplug_unsupported(acpi_handle handle, u32 type) | 361 | static void acpi_hotplug_unsupported(acpi_handle handle, u32 type) |
369 | { | 362 | { |
370 | u32 ost_status; | 363 | u32 ost_status; |
@@ -395,8 +388,8 @@ static void acpi_hotplug_unsupported(acpi_handle handle, u32 type) | |||
395 | 388 | ||
396 | static void acpi_hotplug_notify_cb(acpi_handle handle, u32 type, void *data) | 389 | static void acpi_hotplug_notify_cb(acpi_handle handle, u32 type, void *data) |
397 | { | 390 | { |
398 | acpi_osd_exec_callback callback; | ||
399 | struct acpi_scan_handler *handler = data; | 391 | struct acpi_scan_handler *handler = data; |
392 | struct acpi_device *adev; | ||
400 | acpi_status status; | 393 | acpi_status status; |
401 | 394 | ||
402 | if (!handler->hotplug.enabled) | 395 | if (!handler->hotplug.enabled) |
@@ -405,56 +398,34 @@ static void acpi_hotplug_notify_cb(acpi_handle handle, u32 type, void *data) | |||
405 | switch (type) { | 398 | switch (type) { |
406 | case ACPI_NOTIFY_BUS_CHECK: | 399 | case ACPI_NOTIFY_BUS_CHECK: |
407 | acpi_handle_debug(handle, "ACPI_NOTIFY_BUS_CHECK event\n"); | 400 | acpi_handle_debug(handle, "ACPI_NOTIFY_BUS_CHECK event\n"); |
408 | callback = acpi_scan_bus_check; | ||
409 | break; | 401 | break; |
410 | case ACPI_NOTIFY_DEVICE_CHECK: | 402 | case ACPI_NOTIFY_DEVICE_CHECK: |
411 | acpi_handle_debug(handle, "ACPI_NOTIFY_DEVICE_CHECK event\n"); | 403 | acpi_handle_debug(handle, "ACPI_NOTIFY_DEVICE_CHECK event\n"); |
412 | callback = acpi_scan_device_check; | ||
413 | break; | 404 | break; |
414 | case ACPI_NOTIFY_EJECT_REQUEST: | 405 | case ACPI_NOTIFY_EJECT_REQUEST: |
415 | acpi_handle_debug(handle, "ACPI_NOTIFY_EJECT_REQUEST event\n"); | 406 | acpi_handle_debug(handle, "ACPI_NOTIFY_EJECT_REQUEST event\n"); |
416 | callback = acpi_bus_device_eject; | 407 | if (acpi_bus_get_device(handle, &adev)) |
417 | break; | 408 | goto err_out; |
409 | |||
410 | get_device(&adev->dev); | ||
411 | status = acpi_hotplug_execute(acpi_bus_device_eject, adev, type); | ||
412 | if (ACPI_SUCCESS(status)) | ||
413 | return; | ||
414 | |||
415 | put_device(&adev->dev); | ||
416 | goto err_out; | ||
418 | default: | 417 | default: |
419 | /* non-hotplug event; possibly handled by other handler */ | 418 | /* non-hotplug event; possibly handled by other handler */ |
420 | return; | 419 | return; |
421 | } | 420 | } |
422 | status = acpi_os_hotplug_execute(callback, handle); | 421 | status = acpi_hotplug_execute(acpi_scan_bus_device_check, handle, type); |
423 | if (ACPI_FAILURE(status)) | 422 | if (ACPI_SUCCESS(status)) |
424 | acpi_evaluate_hotplug_ost(handle, type, | 423 | return; |
425 | ACPI_OST_SC_NON_SPECIFIC_FAILURE, | ||
426 | NULL); | ||
427 | } | ||
428 | |||
429 | /** | ||
430 | * acpi_bus_hot_remove_device: hot-remove a device and its children | ||
431 | * @context: struct acpi_eject_event pointer (freed in this func) | ||
432 | * | ||
433 | * Hot-remove a device and its children. This function frees up the | ||
434 | * memory space passed by arg context, so that the caller may call | ||
435 | * this function asynchronously through acpi_os_hotplug_execute(). | ||
436 | */ | ||
437 | void acpi_bus_hot_remove_device(void *context) | ||
438 | { | ||
439 | struct acpi_eject_event *ej_event = context; | ||
440 | struct acpi_device *device = ej_event->device; | ||
441 | acpi_handle handle = device->handle; | ||
442 | int error; | ||
443 | |||
444 | lock_device_hotplug(); | ||
445 | mutex_lock(&acpi_scan_lock); | ||
446 | |||
447 | error = acpi_scan_hot_remove(device); | ||
448 | if (error && handle) | ||
449 | acpi_evaluate_hotplug_ost(handle, ej_event->event, | ||
450 | ACPI_OST_SC_NON_SPECIFIC_FAILURE, | ||
451 | NULL); | ||
452 | 424 | ||
453 | mutex_unlock(&acpi_scan_lock); | 425 | err_out: |
454 | unlock_device_hotplug(); | 426 | acpi_evaluate_hotplug_ost(handle, type, |
455 | kfree(context); | 427 | ACPI_OST_SC_NON_SPECIFIC_FAILURE, NULL); |
456 | } | 428 | } |
457 | EXPORT_SYMBOL(acpi_bus_hot_remove_device); | ||
458 | 429 | ||
459 | static ssize_t real_power_state_show(struct device *dev, | 430 | static ssize_t real_power_state_show(struct device *dev, |
460 | struct device_attribute *attr, char *buf) | 431 | struct device_attribute *attr, char *buf) |
@@ -487,10 +458,8 @@ acpi_eject_store(struct device *d, struct device_attribute *attr, | |||
487 | const char *buf, size_t count) | 458 | const char *buf, size_t count) |
488 | { | 459 | { |
489 | struct acpi_device *acpi_device = to_acpi_device(d); | 460 | struct acpi_device *acpi_device = to_acpi_device(d); |
490 | struct acpi_eject_event *ej_event; | ||
491 | acpi_object_type not_used; | 461 | acpi_object_type not_used; |
492 | acpi_status status; | 462 | acpi_status status; |
493 | int ret; | ||
494 | 463 | ||
495 | if (!count || buf[0] != '1') | 464 | if (!count || buf[0] != '1') |
496 | return -EINVAL; | 465 | return -EINVAL; |
@@ -503,28 +472,18 @@ acpi_eject_store(struct device *d, struct device_attribute *attr, | |||
503 | if (ACPI_FAILURE(status) || !acpi_device->flags.ejectable) | 472 | if (ACPI_FAILURE(status) || !acpi_device->flags.ejectable) |
504 | return -ENODEV; | 473 | return -ENODEV; |
505 | 474 | ||
506 | ej_event = kmalloc(sizeof(*ej_event), GFP_KERNEL); | ||
507 | if (!ej_event) { | ||
508 | ret = -ENOMEM; | ||
509 | goto err_out; | ||
510 | } | ||
511 | acpi_evaluate_hotplug_ost(acpi_device->handle, ACPI_OST_EC_OSPM_EJECT, | 475 | acpi_evaluate_hotplug_ost(acpi_device->handle, ACPI_OST_EC_OSPM_EJECT, |
512 | ACPI_OST_SC_EJECT_IN_PROGRESS, NULL); | 476 | ACPI_OST_SC_EJECT_IN_PROGRESS, NULL); |
513 | ej_event->device = acpi_device; | ||
514 | ej_event->event = ACPI_OST_EC_OSPM_EJECT; | ||
515 | get_device(&acpi_device->dev); | 477 | get_device(&acpi_device->dev); |
516 | status = acpi_os_hotplug_execute(acpi_bus_hot_remove_device, ej_event); | 478 | status = acpi_hotplug_execute(acpi_bus_device_eject, acpi_device, |
479 | ACPI_OST_EC_OSPM_EJECT); | ||
517 | if (ACPI_SUCCESS(status)) | 480 | if (ACPI_SUCCESS(status)) |
518 | return count; | 481 | return count; |
519 | 482 | ||
520 | put_device(&acpi_device->dev); | 483 | put_device(&acpi_device->dev); |
521 | kfree(ej_event); | ||
522 | ret = status == AE_NO_MEMORY ? -ENOMEM : -EAGAIN; | ||
523 | |||
524 | err_out: | ||
525 | acpi_evaluate_hotplug_ost(acpi_device->handle, ACPI_OST_EC_OSPM_EJECT, | 484 | acpi_evaluate_hotplug_ost(acpi_device->handle, ACPI_OST_EC_OSPM_EJECT, |
526 | ACPI_OST_SC_NON_SPECIFIC_FAILURE, NULL); | 485 | ACPI_OST_SC_NON_SPECIFIC_FAILURE, NULL); |
527 | return ret; | 486 | return status == AE_NO_MEMORY ? -ENOMEM : -EAGAIN; |
528 | } | 487 | } |
529 | 488 | ||
530 | static DEVICE_ATTR(eject, 0200, NULL, acpi_eject_store); | 489 | static DEVICE_ATTR(eject, 0200, NULL, acpi_eject_store); |
@@ -1676,7 +1635,6 @@ void acpi_init_device_object(struct acpi_device *device, acpi_handle handle, | |||
1676 | 1635 | ||
1677 | void acpi_device_add_finalize(struct acpi_device *device) | 1636 | void acpi_device_add_finalize(struct acpi_device *device) |
1678 | { | 1637 | { |
1679 | device->flags.match_driver = true; | ||
1680 | dev_set_uevent_suppress(&device->dev, false); | 1638 | dev_set_uevent_suppress(&device->dev, false); |
1681 | kobject_uevent(&device->dev.kobj, KOBJ_ADD); | 1639 | kobject_uevent(&device->dev.kobj, KOBJ_ADD); |
1682 | } | 1640 | } |
@@ -1915,8 +1873,12 @@ static acpi_status acpi_bus_device_attach(acpi_handle handle, u32 lvl_not_used, | |||
1915 | return AE_OK; | 1873 | return AE_OK; |
1916 | 1874 | ||
1917 | ret = acpi_scan_attach_handler(device); | 1875 | ret = acpi_scan_attach_handler(device); |
1918 | if (ret) | 1876 | if (ret < 0) |
1919 | return ret > 0 ? AE_OK : AE_CTRL_DEPTH; | 1877 | return AE_CTRL_DEPTH; |
1878 | |||
1879 | device->flags.match_driver = true; | ||
1880 | if (ret > 0) | ||
1881 | return AE_OK; | ||
1920 | 1882 | ||
1921 | ret = device_attach(&device->dev); | 1883 | ret = device_attach(&device->dev); |
1922 | return ret >= 0 ? AE_OK : AE_CTRL_DEPTH; | 1884 | return ret >= 0 ? AE_OK : AE_CTRL_DEPTH; |
@@ -2027,6 +1989,7 @@ static int acpi_bus_scan_fixed(void) | |||
2027 | if (result) | 1989 | if (result) |
2028 | return result; | 1990 | return result; |
2029 | 1991 | ||
1992 | device->flags.match_driver = true; | ||
2030 | result = device_attach(&device->dev); | 1993 | result = device_attach(&device->dev); |
2031 | if (result < 0) | 1994 | if (result < 0) |
2032 | return result; | 1995 | return result; |
@@ -2043,6 +2006,7 @@ static int acpi_bus_scan_fixed(void) | |||
2043 | if (result) | 2006 | if (result) |
2044 | return result; | 2007 | return result; |
2045 | 2008 | ||
2009 | device->flags.match_driver = true; | ||
2046 | result = device_attach(&device->dev); | 2010 | result = device_attach(&device->dev); |
2047 | } | 2011 | } |
2048 | 2012 | ||
diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c index 05306a59aedc..db5293650f62 100644 --- a/drivers/acpi/sysfs.c +++ b/drivers/acpi/sysfs.c | |||
@@ -564,6 +564,7 @@ static ssize_t counter_set(struct kobject *kobj, | |||
564 | acpi_event_status status; | 564 | acpi_event_status status; |
565 | acpi_handle handle; | 565 | acpi_handle handle; |
566 | int result = 0; | 566 | int result = 0; |
567 | unsigned long tmp; | ||
567 | 568 | ||
568 | if (index == num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_SCI) { | 569 | if (index == num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_SCI) { |
569 | int i; | 570 | int i; |
@@ -596,8 +597,10 @@ static ssize_t counter_set(struct kobject *kobj, | |||
596 | else if (!strcmp(buf, "clear\n") && | 597 | else if (!strcmp(buf, "clear\n") && |
597 | (status & ACPI_EVENT_FLAG_SET)) | 598 | (status & ACPI_EVENT_FLAG_SET)) |
598 | result = acpi_clear_gpe(handle, index); | 599 | result = acpi_clear_gpe(handle, index); |
600 | else if (!kstrtoul(buf, 0, &tmp)) | ||
601 | all_counters[index].count = tmp; | ||
599 | else | 602 | else |
600 | all_counters[index].count = strtoul(buf, NULL, 0); | 603 | result = -EINVAL; |
601 | } else if (index < num_gpes + ACPI_NUM_FIXED_EVENTS) { | 604 | } else if (index < num_gpes + ACPI_NUM_FIXED_EVENTS) { |
602 | int event = index - num_gpes; | 605 | int event = index - num_gpes; |
603 | if (!strcmp(buf, "disable\n") && | 606 | if (!strcmp(buf, "disable\n") && |
@@ -609,8 +612,10 @@ static ssize_t counter_set(struct kobject *kobj, | |||
609 | else if (!strcmp(buf, "clear\n") && | 612 | else if (!strcmp(buf, "clear\n") && |
610 | (status & ACPI_EVENT_FLAG_SET)) | 613 | (status & ACPI_EVENT_FLAG_SET)) |
611 | result = acpi_clear_event(event); | 614 | result = acpi_clear_event(event); |
615 | else if (!kstrtoul(buf, 0, &tmp)) | ||
616 | all_counters[index].count = tmp; | ||
612 | else | 617 | else |
613 | all_counters[index].count = strtoul(buf, NULL, 0); | 618 | result = -EINVAL; |
614 | } else | 619 | } else |
615 | all_counters[index].count = strtoul(buf, NULL, 0); | 620 | all_counters[index].count = strtoul(buf, NULL, 0); |
616 | 621 | ||
@@ -762,13 +767,8 @@ void acpi_sysfs_add_hotplug_profile(struct acpi_hotplug_profile *hotplug, | |||
762 | if (!hotplug_kobj) | 767 | if (!hotplug_kobj) |
763 | goto err_out; | 768 | goto err_out; |
764 | 769 | ||
765 | kobject_init(&hotplug->kobj, &acpi_hotplug_profile_ktype); | 770 | error = kobject_init_and_add(&hotplug->kobj, |
766 | error = kobject_set_name(&hotplug->kobj, "%s", name); | 771 | &acpi_hotplug_profile_ktype, hotplug_kobj, "%s", name); |
767 | if (error) | ||
768 | goto err_out; | ||
769 | |||
770 | hotplug->kobj.parent = hotplug_kobj; | ||
771 | error = kobject_add(&hotplug->kobj, hotplug_kobj, NULL); | ||
772 | if (error) | 772 | if (error) |
773 | goto err_out; | 773 | goto err_out; |
774 | 774 | ||
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 6a0329340b42..e600b5dbfcb6 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c | |||
@@ -299,8 +299,8 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag) | |||
299 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 299 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
300 | "No critical threshold\n")); | 300 | "No critical threshold\n")); |
301 | } else if (tmp <= 2732) { | 301 | } else if (tmp <= 2732) { |
302 | printk(KERN_WARNING FW_BUG "Invalid critical threshold " | 302 | pr_warn(FW_BUG "Invalid critical threshold (%llu)\n", |
303 | "(%llu)\n", tmp); | 303 | tmp); |
304 | tz->trips.critical.flags.valid = 0; | 304 | tz->trips.critical.flags.valid = 0; |
305 | } else { | 305 | } else { |
306 | tz->trips.critical.flags.valid = 1; | 306 | tz->trips.critical.flags.valid = 1; |
@@ -317,8 +317,8 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag) | |||
317 | * Allow override critical threshold | 317 | * Allow override critical threshold |
318 | */ | 318 | */ |
319 | if (crt_k > tz->trips.critical.temperature) | 319 | if (crt_k > tz->trips.critical.temperature) |
320 | printk(KERN_WARNING PREFIX | 320 | pr_warn(PREFIX "Critical threshold %d C\n", |
321 | "Critical threshold %d C\n", crt); | 321 | crt); |
322 | tz->trips.critical.temperature = crt_k; | 322 | tz->trips.critical.temperature = crt_k; |
323 | } | 323 | } |
324 | } | 324 | } |
@@ -390,8 +390,7 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag) | |||
390 | status = acpi_evaluate_reference(tz->device->handle, "_PSL", | 390 | status = acpi_evaluate_reference(tz->device->handle, "_PSL", |
391 | NULL, &devices); | 391 | NULL, &devices); |
392 | if (ACPI_FAILURE(status)) { | 392 | if (ACPI_FAILURE(status)) { |
393 | printk(KERN_WARNING PREFIX | 393 | pr_warn(PREFIX "Invalid passive threshold\n"); |
394 | "Invalid passive threshold\n"); | ||
395 | tz->trips.passive.flags.valid = 0; | 394 | tz->trips.passive.flags.valid = 0; |
396 | } | 395 | } |
397 | else | 396 | else |
@@ -453,8 +452,8 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag) | |||
453 | status = acpi_evaluate_reference(tz->device->handle, | 452 | status = acpi_evaluate_reference(tz->device->handle, |
454 | name, NULL, &devices); | 453 | name, NULL, &devices); |
455 | if (ACPI_FAILURE(status)) { | 454 | if (ACPI_FAILURE(status)) { |
456 | printk(KERN_WARNING PREFIX | 455 | pr_warn(PREFIX "Invalid active%d threshold\n", |
457 | "Invalid active%d threshold\n", i); | 456 | i); |
458 | tz->trips.active[i].flags.valid = 0; | 457 | tz->trips.active[i].flags.valid = 0; |
459 | } | 458 | } |
460 | else | 459 | else |
@@ -505,7 +504,7 @@ static int acpi_thermal_get_trip_points(struct acpi_thermal *tz) | |||
505 | valid |= tz->trips.active[i].flags.valid; | 504 | valid |= tz->trips.active[i].flags.valid; |
506 | 505 | ||
507 | if (!valid) { | 506 | if (!valid) { |
508 | printk(KERN_WARNING FW_BUG "No valid trip found\n"); | 507 | pr_warn(FW_BUG "No valid trip found\n"); |
509 | return -ENODEV; | 508 | return -ENODEV; |
510 | } | 509 | } |
511 | return 0; | 510 | return 0; |
@@ -923,8 +922,7 @@ static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz) | |||
923 | acpi_bus_private_data_handler, | 922 | acpi_bus_private_data_handler, |
924 | tz->thermal_zone); | 923 | tz->thermal_zone); |
925 | if (ACPI_FAILURE(status)) { | 924 | if (ACPI_FAILURE(status)) { |
926 | printk(KERN_ERR PREFIX | 925 | pr_err(PREFIX "Error attaching device data\n"); |
927 | "Error attaching device data\n"); | ||
928 | return -ENODEV; | 926 | return -ENODEV; |
929 | } | 927 | } |
930 | 928 | ||
@@ -1094,9 +1092,8 @@ static int acpi_thermal_add(struct acpi_device *device) | |||
1094 | if (result) | 1092 | if (result) |
1095 | goto free_memory; | 1093 | goto free_memory; |
1096 | 1094 | ||
1097 | printk(KERN_INFO PREFIX "%s [%s] (%ld C)\n", | 1095 | pr_info(PREFIX "%s [%s] (%ld C)\n", acpi_device_name(device), |
1098 | acpi_device_name(device), acpi_device_bid(device), | 1096 | acpi_device_bid(device), KELVIN_TO_CELSIUS(tz->temperature)); |
1099 | KELVIN_TO_CELSIUS(tz->temperature)); | ||
1100 | goto end; | 1097 | goto end; |
1101 | 1098 | ||
1102 | free_memory: | 1099 | free_memory: |
@@ -1159,24 +1156,24 @@ static int acpi_thermal_resume(struct device *dev) | |||
1159 | static int thermal_act(const struct dmi_system_id *d) { | 1156 | static int thermal_act(const struct dmi_system_id *d) { |
1160 | 1157 | ||
1161 | if (act == 0) { | 1158 | if (act == 0) { |
1162 | printk(KERN_NOTICE "ACPI: %s detected: " | 1159 | pr_notice(PREFIX "%s detected: " |
1163 | "disabling all active thermal trip points\n", d->ident); | 1160 | "disabling all active thermal trip points\n", d->ident); |
1164 | act = -1; | 1161 | act = -1; |
1165 | } | 1162 | } |
1166 | return 0; | 1163 | return 0; |
1167 | } | 1164 | } |
1168 | static int thermal_nocrt(const struct dmi_system_id *d) { | 1165 | static int thermal_nocrt(const struct dmi_system_id *d) { |
1169 | 1166 | ||
1170 | printk(KERN_NOTICE "ACPI: %s detected: " | 1167 | pr_notice(PREFIX "%s detected: " |
1171 | "disabling all critical thermal trip point actions.\n", d->ident); | 1168 | "disabling all critical thermal trip point actions.\n", d->ident); |
1172 | nocrt = 1; | 1169 | nocrt = 1; |
1173 | return 0; | 1170 | return 0; |
1174 | } | 1171 | } |
1175 | static int thermal_tzp(const struct dmi_system_id *d) { | 1172 | static int thermal_tzp(const struct dmi_system_id *d) { |
1176 | 1173 | ||
1177 | if (tzp == 0) { | 1174 | if (tzp == 0) { |
1178 | printk(KERN_NOTICE "ACPI: %s detected: " | 1175 | pr_notice(PREFIX "%s detected: " |
1179 | "enabling thermal zone polling\n", d->ident); | 1176 | "enabling thermal zone polling\n", d->ident); |
1180 | tzp = 300; /* 300 dS = 30 Seconds */ | 1177 | tzp = 300; /* 300 dS = 30 Seconds */ |
1181 | } | 1178 | } |
1182 | return 0; | 1179 | return 0; |
@@ -1184,8 +1181,8 @@ static int thermal_tzp(const struct dmi_system_id *d) { | |||
1184 | static int thermal_psv(const struct dmi_system_id *d) { | 1181 | static int thermal_psv(const struct dmi_system_id *d) { |
1185 | 1182 | ||
1186 | if (psv == 0) { | 1183 | if (psv == 0) { |
1187 | printk(KERN_NOTICE "ACPI: %s detected: " | 1184 | pr_notice(PREFIX "%s detected: " |
1188 | "disabling all passive thermal trip points\n", d->ident); | 1185 | "disabling all passive thermal trip points\n", d->ident); |
1189 | psv = -1; | 1186 | psv = -1; |
1190 | } | 1187 | } |
1191 | return 0; | 1188 | return 0; |
@@ -1238,7 +1235,7 @@ static int __init acpi_thermal_init(void) | |||
1238 | dmi_check_system(thermal_dmi_table); | 1235 | dmi_check_system(thermal_dmi_table); |
1239 | 1236 | ||
1240 | if (off) { | 1237 | if (off) { |
1241 | printk(KERN_NOTICE "ACPI: thermal control disabled\n"); | 1238 | pr_notice(PREFIX "thermal control disabled\n"); |
1242 | return -ENODEV; | 1239 | return -ENODEV; |
1243 | } | 1240 | } |
1244 | 1241 | ||
diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c index 552248b0005b..6d408bfbbb1d 100644 --- a/drivers/acpi/utils.c +++ b/drivers/acpi/utils.c | |||
@@ -121,7 +121,7 @@ acpi_extract_package(union acpi_object *package, | |||
121 | break; | 121 | break; |
122 | default: | 122 | default: |
123 | printk(KERN_WARNING PREFIX "Invalid package element" | 123 | printk(KERN_WARNING PREFIX "Invalid package element" |
124 | " [%d]: got number, expecing" | 124 | " [%d]: got number, expecting" |
125 | " [%c]\n", | 125 | " [%c]\n", |
126 | i, format_string[i]); | 126 | i, format_string[i]); |
127 | return AE_BAD_DATA; | 127 | return AE_BAD_DATA; |
@@ -148,7 +148,7 @@ acpi_extract_package(union acpi_object *package, | |||
148 | default: | 148 | default: |
149 | printk(KERN_WARNING PREFIX "Invalid package element" | 149 | printk(KERN_WARNING PREFIX "Invalid package element" |
150 | " [%d] got string/buffer," | 150 | " [%d] got string/buffer," |
151 | " expecing [%c]\n", | 151 | " expecting [%c]\n", |
152 | i, format_string[i]); | 152 | i, format_string[i]); |
153 | return AE_BAD_DATA; | 153 | return AE_BAD_DATA; |
154 | break; | 154 | break; |
@@ -169,11 +169,20 @@ acpi_extract_package(union acpi_object *package, | |||
169 | /* | 169 | /* |
170 | * Validate output buffer. | 170 | * Validate output buffer. |
171 | */ | 171 | */ |
172 | if (buffer->length < size_required) { | 172 | if (buffer->length == ACPI_ALLOCATE_BUFFER) { |
173 | buffer->pointer = ACPI_ALLOCATE(size_required); | ||
174 | if (!buffer->pointer) | ||
175 | return AE_NO_MEMORY; | ||
173 | buffer->length = size_required; | 176 | buffer->length = size_required; |
174 | return AE_BUFFER_OVERFLOW; | 177 | memset(buffer->pointer, 0, size_required); |
175 | } else if (buffer->length != size_required || !buffer->pointer) { | 178 | } else { |
176 | return AE_BAD_PARAMETER; | 179 | if (buffer->length < size_required) { |
180 | buffer->length = size_required; | ||
181 | return AE_BUFFER_OVERFLOW; | ||
182 | } else if (buffer->length != size_required || | ||
183 | !buffer->pointer) { | ||
184 | return AE_BAD_PARAMETER; | ||
185 | } | ||
177 | } | 186 | } |
178 | 187 | ||
179 | head = buffer->pointer; | 188 | head = buffer->pointer; |
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index aebcf6355df4..18dbdff4656e 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c | |||
@@ -88,7 +88,16 @@ module_param(allow_duplicates, bool, 0644); | |||
88 | static bool use_bios_initial_backlight = 1; | 88 | static bool use_bios_initial_backlight = 1; |
89 | module_param(use_bios_initial_backlight, bool, 0644); | 89 | module_param(use_bios_initial_backlight, bool, 0644); |
90 | 90 | ||
91 | /* | ||
92 | * For Windows 8 systems: if set ture and the GPU driver has | ||
93 | * registered a backlight interface, skip registering ACPI video's. | ||
94 | */ | ||
95 | static bool use_native_backlight = false; | ||
96 | module_param(use_native_backlight, bool, 0644); | ||
97 | |||
91 | static int register_count; | 98 | static int register_count; |
99 | static struct mutex video_list_lock; | ||
100 | static struct list_head video_bus_head; | ||
92 | static int acpi_video_bus_add(struct acpi_device *device); | 101 | static int acpi_video_bus_add(struct acpi_device *device); |
93 | static int acpi_video_bus_remove(struct acpi_device *device); | 102 | static int acpi_video_bus_remove(struct acpi_device *device); |
94 | static void acpi_video_bus_notify(struct acpi_device *device, u32 event); | 103 | static void acpi_video_bus_notify(struct acpi_device *device, u32 event); |
@@ -157,6 +166,7 @@ struct acpi_video_bus { | |||
157 | struct acpi_video_bus_flags flags; | 166 | struct acpi_video_bus_flags flags; |
158 | struct list_head video_device_list; | 167 | struct list_head video_device_list; |
159 | struct mutex device_list_lock; /* protects video_device_list */ | 168 | struct mutex device_list_lock; /* protects video_device_list */ |
169 | struct list_head entry; | ||
160 | struct input_dev *input; | 170 | struct input_dev *input; |
161 | char phys[32]; /* for input device */ | 171 | char phys[32]; /* for input device */ |
162 | struct notifier_block pm_nb; | 172 | struct notifier_block pm_nb; |
@@ -229,6 +239,14 @@ static int acpi_video_get_next_level(struct acpi_video_device *device, | |||
229 | static int acpi_video_switch_brightness(struct acpi_video_device *device, | 239 | static int acpi_video_switch_brightness(struct acpi_video_device *device, |
230 | int event); | 240 | int event); |
231 | 241 | ||
242 | static bool acpi_video_verify_backlight_support(void) | ||
243 | { | ||
244 | if (acpi_osi_is_win8() && use_native_backlight && | ||
245 | backlight_device_registered(BACKLIGHT_RAW)) | ||
246 | return false; | ||
247 | return acpi_video_backlight_support(); | ||
248 | } | ||
249 | |||
232 | /* backlight device sysfs support */ | 250 | /* backlight device sysfs support */ |
233 | static int acpi_video_get_brightness(struct backlight_device *bd) | 251 | static int acpi_video_get_brightness(struct backlight_device *bd) |
234 | { | 252 | { |
@@ -830,9 +848,9 @@ acpi_video_init_brightness(struct acpi_video_device *device) | |||
830 | * or an index). Set the backlight to max_level in this case. | 848 | * or an index). Set the backlight to max_level in this case. |
831 | */ | 849 | */ |
832 | for (i = 2; i < br->count; i++) | 850 | for (i = 2; i < br->count; i++) |
833 | if (level_old == br->levels[i]) | 851 | if (level == br->levels[i]) |
834 | break; | 852 | break; |
835 | if (i == br->count) | 853 | if (i == br->count || !level) |
836 | level = max_level; | 854 | level = max_level; |
837 | } | 855 | } |
838 | 856 | ||
@@ -884,79 +902,6 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) | |||
884 | 902 | ||
885 | if (acpi_has_method(device->dev->handle, "_DDC")) | 903 | if (acpi_has_method(device->dev->handle, "_DDC")) |
886 | device->cap._DDC = 1; | 904 | device->cap._DDC = 1; |
887 | |||
888 | if (acpi_video_backlight_support()) { | ||
889 | struct backlight_properties props; | ||
890 | struct pci_dev *pdev; | ||
891 | acpi_handle acpi_parent; | ||
892 | struct device *parent = NULL; | ||
893 | int result; | ||
894 | static int count; | ||
895 | char *name; | ||
896 | |||
897 | result = acpi_video_init_brightness(device); | ||
898 | if (result) | ||
899 | return; | ||
900 | name = kasprintf(GFP_KERNEL, "acpi_video%d", count); | ||
901 | if (!name) | ||
902 | return; | ||
903 | count++; | ||
904 | |||
905 | acpi_get_parent(device->dev->handle, &acpi_parent); | ||
906 | |||
907 | pdev = acpi_get_pci_dev(acpi_parent); | ||
908 | if (pdev) { | ||
909 | parent = &pdev->dev; | ||
910 | pci_dev_put(pdev); | ||
911 | } | ||
912 | |||
913 | memset(&props, 0, sizeof(struct backlight_properties)); | ||
914 | props.type = BACKLIGHT_FIRMWARE; | ||
915 | props.max_brightness = device->brightness->count - 3; | ||
916 | device->backlight = backlight_device_register(name, | ||
917 | parent, | ||
918 | device, | ||
919 | &acpi_backlight_ops, | ||
920 | &props); | ||
921 | kfree(name); | ||
922 | if (IS_ERR(device->backlight)) | ||
923 | return; | ||
924 | |||
925 | /* | ||
926 | * Save current brightness level in case we have to restore it | ||
927 | * before acpi_video_device_lcd_set_level() is called next time. | ||
928 | */ | ||
929 | device->backlight->props.brightness = | ||
930 | acpi_video_get_brightness(device->backlight); | ||
931 | |||
932 | device->cooling_dev = thermal_cooling_device_register("LCD", | ||
933 | device->dev, &video_cooling_ops); | ||
934 | if (IS_ERR(device->cooling_dev)) { | ||
935 | /* | ||
936 | * Set cooling_dev to NULL so we don't crash trying to | ||
937 | * free it. | ||
938 | * Also, why the hell we are returning early and | ||
939 | * not attempt to register video output if cooling | ||
940 | * device registration failed? | ||
941 | * -- dtor | ||
942 | */ | ||
943 | device->cooling_dev = NULL; | ||
944 | return; | ||
945 | } | ||
946 | |||
947 | dev_info(&device->dev->dev, "registered as cooling_device%d\n", | ||
948 | device->cooling_dev->id); | ||
949 | result = sysfs_create_link(&device->dev->dev.kobj, | ||
950 | &device->cooling_dev->device.kobj, | ||
951 | "thermal_cooling"); | ||
952 | if (result) | ||
953 | printk(KERN_ERR PREFIX "Create sysfs link\n"); | ||
954 | result = sysfs_create_link(&device->cooling_dev->device.kobj, | ||
955 | &device->dev->dev.kobj, "device"); | ||
956 | if (result) | ||
957 | printk(KERN_ERR PREFIX "Create sysfs link\n"); | ||
958 | |||
959 | } | ||
960 | } | 905 | } |
961 | 906 | ||
962 | /* | 907 | /* |
@@ -1143,13 +1088,6 @@ acpi_video_bus_get_one_device(struct acpi_device *device, | |||
1143 | acpi_video_device_bind(video, data); | 1088 | acpi_video_device_bind(video, data); |
1144 | acpi_video_device_find_cap(data); | 1089 | acpi_video_device_find_cap(data); |
1145 | 1090 | ||
1146 | status = acpi_install_notify_handler(device->handle, ACPI_DEVICE_NOTIFY, | ||
1147 | acpi_video_device_notify, data); | ||
1148 | if (ACPI_FAILURE(status)) | ||
1149 | dev_err(&device->dev, "Error installing notify handler\n"); | ||
1150 | else | ||
1151 | data->flags.notify = 1; | ||
1152 | |||
1153 | mutex_lock(&video->device_list_lock); | 1091 | mutex_lock(&video->device_list_lock); |
1154 | list_add_tail(&data->entry, &video->video_device_list); | 1092 | list_add_tail(&data->entry, &video->video_device_list); |
1155 | mutex_unlock(&video->device_list_lock); | 1093 | mutex_unlock(&video->device_list_lock); |
@@ -1333,8 +1271,8 @@ acpi_video_switch_brightness(struct acpi_video_device *device, int event) | |||
1333 | unsigned long long level_current, level_next; | 1271 | unsigned long long level_current, level_next; |
1334 | int result = -EINVAL; | 1272 | int result = -EINVAL; |
1335 | 1273 | ||
1336 | /* no warning message if acpi_backlight=vendor is used */ | 1274 | /* no warning message if acpi_backlight=vendor or a quirk is used */ |
1337 | if (!acpi_video_backlight_support()) | 1275 | if (!acpi_video_verify_backlight_support()) |
1338 | return 0; | 1276 | return 0; |
1339 | 1277 | ||
1340 | if (!device->brightness) | 1278 | if (!device->brightness) |
@@ -1454,64 +1392,6 @@ acpi_video_bus_get_devices(struct acpi_video_bus *video, | |||
1454 | return status; | 1392 | return status; |
1455 | } | 1393 | } |
1456 | 1394 | ||
1457 | static int acpi_video_bus_put_one_device(struct acpi_video_device *device) | ||
1458 | { | ||
1459 | acpi_status status; | ||
1460 | |||
1461 | if (!device || !device->video) | ||
1462 | return -ENOENT; | ||
1463 | |||
1464 | if (device->flags.notify) { | ||
1465 | status = acpi_remove_notify_handler(device->dev->handle, | ||
1466 | ACPI_DEVICE_NOTIFY, acpi_video_device_notify); | ||
1467 | if (ACPI_FAILURE(status)) | ||
1468 | dev_err(&device->dev->dev, | ||
1469 | "Can't remove video notify handler\n"); | ||
1470 | } | ||
1471 | |||
1472 | if (device->backlight) { | ||
1473 | backlight_device_unregister(device->backlight); | ||
1474 | device->backlight = NULL; | ||
1475 | } | ||
1476 | if (device->cooling_dev) { | ||
1477 | sysfs_remove_link(&device->dev->dev.kobj, | ||
1478 | "thermal_cooling"); | ||
1479 | sysfs_remove_link(&device->cooling_dev->device.kobj, | ||
1480 | "device"); | ||
1481 | thermal_cooling_device_unregister(device->cooling_dev); | ||
1482 | device->cooling_dev = NULL; | ||
1483 | } | ||
1484 | |||
1485 | return 0; | ||
1486 | } | ||
1487 | |||
1488 | static int acpi_video_bus_put_devices(struct acpi_video_bus *video) | ||
1489 | { | ||
1490 | int status; | ||
1491 | struct acpi_video_device *dev, *next; | ||
1492 | |||
1493 | mutex_lock(&video->device_list_lock); | ||
1494 | |||
1495 | list_for_each_entry_safe(dev, next, &video->video_device_list, entry) { | ||
1496 | |||
1497 | status = acpi_video_bus_put_one_device(dev); | ||
1498 | if (ACPI_FAILURE(status)) | ||
1499 | printk(KERN_WARNING PREFIX | ||
1500 | "hhuuhhuu bug in acpi video driver.\n"); | ||
1501 | |||
1502 | if (dev->brightness) { | ||
1503 | kfree(dev->brightness->levels); | ||
1504 | kfree(dev->brightness); | ||
1505 | } | ||
1506 | list_del(&dev->entry); | ||
1507 | kfree(dev); | ||
1508 | } | ||
1509 | |||
1510 | mutex_unlock(&video->device_list_lock); | ||
1511 | |||
1512 | return 0; | ||
1513 | } | ||
1514 | |||
1515 | /* acpi_video interface */ | 1395 | /* acpi_video interface */ |
1516 | 1396 | ||
1517 | /* | 1397 | /* |
@@ -1521,13 +1401,13 @@ static int acpi_video_bus_put_devices(struct acpi_video_bus *video) | |||
1521 | static int acpi_video_bus_start_devices(struct acpi_video_bus *video) | 1401 | static int acpi_video_bus_start_devices(struct acpi_video_bus *video) |
1522 | { | 1402 | { |
1523 | return acpi_video_bus_DOS(video, 0, | 1403 | return acpi_video_bus_DOS(video, 0, |
1524 | acpi_video_backlight_quirks() ? 1 : 0); | 1404 | acpi_osi_is_win8() ? 1 : 0); |
1525 | } | 1405 | } |
1526 | 1406 | ||
1527 | static int acpi_video_bus_stop_devices(struct acpi_video_bus *video) | 1407 | static int acpi_video_bus_stop_devices(struct acpi_video_bus *video) |
1528 | { | 1408 | { |
1529 | return acpi_video_bus_DOS(video, 0, | 1409 | return acpi_video_bus_DOS(video, 0, |
1530 | acpi_video_backlight_quirks() ? 0 : 1); | 1410 | acpi_osi_is_win8() ? 0 : 1); |
1531 | } | 1411 | } |
1532 | 1412 | ||
1533 | static void acpi_video_bus_notify(struct acpi_device *device, u32 event) | 1413 | static void acpi_video_bus_notify(struct acpi_device *device, u32 event) |
@@ -1536,7 +1416,7 @@ static void acpi_video_bus_notify(struct acpi_device *device, u32 event) | |||
1536 | struct input_dev *input; | 1416 | struct input_dev *input; |
1537 | int keycode = 0; | 1417 | int keycode = 0; |
1538 | 1418 | ||
1539 | if (!video) | 1419 | if (!video || !video->input) |
1540 | return; | 1420 | return; |
1541 | 1421 | ||
1542 | input = video->input; | 1422 | input = video->input; |
@@ -1691,12 +1571,236 @@ acpi_video_bus_match(acpi_handle handle, u32 level, void *context, | |||
1691 | return AE_OK; | 1571 | return AE_OK; |
1692 | } | 1572 | } |
1693 | 1573 | ||
1574 | static void acpi_video_dev_register_backlight(struct acpi_video_device *device) | ||
1575 | { | ||
1576 | if (acpi_video_verify_backlight_support()) { | ||
1577 | struct backlight_properties props; | ||
1578 | struct pci_dev *pdev; | ||
1579 | acpi_handle acpi_parent; | ||
1580 | struct device *parent = NULL; | ||
1581 | int result; | ||
1582 | static int count; | ||
1583 | char *name; | ||
1584 | |||
1585 | result = acpi_video_init_brightness(device); | ||
1586 | if (result) | ||
1587 | return; | ||
1588 | name = kasprintf(GFP_KERNEL, "acpi_video%d", count); | ||
1589 | if (!name) | ||
1590 | return; | ||
1591 | count++; | ||
1592 | |||
1593 | acpi_get_parent(device->dev->handle, &acpi_parent); | ||
1594 | |||
1595 | pdev = acpi_get_pci_dev(acpi_parent); | ||
1596 | if (pdev) { | ||
1597 | parent = &pdev->dev; | ||
1598 | pci_dev_put(pdev); | ||
1599 | } | ||
1600 | |||
1601 | memset(&props, 0, sizeof(struct backlight_properties)); | ||
1602 | props.type = BACKLIGHT_FIRMWARE; | ||
1603 | props.max_brightness = device->brightness->count - 3; | ||
1604 | device->backlight = backlight_device_register(name, | ||
1605 | parent, | ||
1606 | device, | ||
1607 | &acpi_backlight_ops, | ||
1608 | &props); | ||
1609 | kfree(name); | ||
1610 | if (IS_ERR(device->backlight)) | ||
1611 | return; | ||
1612 | |||
1613 | /* | ||
1614 | * Save current brightness level in case we have to restore it | ||
1615 | * before acpi_video_device_lcd_set_level() is called next time. | ||
1616 | */ | ||
1617 | device->backlight->props.brightness = | ||
1618 | acpi_video_get_brightness(device->backlight); | ||
1619 | |||
1620 | device->cooling_dev = thermal_cooling_device_register("LCD", | ||
1621 | device->dev, &video_cooling_ops); | ||
1622 | if (IS_ERR(device->cooling_dev)) { | ||
1623 | /* | ||
1624 | * Set cooling_dev to NULL so we don't crash trying to | ||
1625 | * free it. | ||
1626 | * Also, why the hell we are returning early and | ||
1627 | * not attempt to register video output if cooling | ||
1628 | * device registration failed? | ||
1629 | * -- dtor | ||
1630 | */ | ||
1631 | device->cooling_dev = NULL; | ||
1632 | return; | ||
1633 | } | ||
1634 | |||
1635 | dev_info(&device->dev->dev, "registered as cooling_device%d\n", | ||
1636 | device->cooling_dev->id); | ||
1637 | result = sysfs_create_link(&device->dev->dev.kobj, | ||
1638 | &device->cooling_dev->device.kobj, | ||
1639 | "thermal_cooling"); | ||
1640 | if (result) | ||
1641 | printk(KERN_ERR PREFIX "Create sysfs link\n"); | ||
1642 | result = sysfs_create_link(&device->cooling_dev->device.kobj, | ||
1643 | &device->dev->dev.kobj, "device"); | ||
1644 | if (result) | ||
1645 | printk(KERN_ERR PREFIX "Create sysfs link\n"); | ||
1646 | } | ||
1647 | } | ||
1648 | |||
1649 | static int acpi_video_bus_register_backlight(struct acpi_video_bus *video) | ||
1650 | { | ||
1651 | struct acpi_video_device *dev; | ||
1652 | |||
1653 | mutex_lock(&video->device_list_lock); | ||
1654 | list_for_each_entry(dev, &video->video_device_list, entry) | ||
1655 | acpi_video_dev_register_backlight(dev); | ||
1656 | mutex_unlock(&video->device_list_lock); | ||
1657 | |||
1658 | video->pm_nb.notifier_call = acpi_video_resume; | ||
1659 | video->pm_nb.priority = 0; | ||
1660 | return register_pm_notifier(&video->pm_nb); | ||
1661 | } | ||
1662 | |||
1663 | static void acpi_video_dev_unregister_backlight(struct acpi_video_device *device) | ||
1664 | { | ||
1665 | if (device->backlight) { | ||
1666 | backlight_device_unregister(device->backlight); | ||
1667 | device->backlight = NULL; | ||
1668 | } | ||
1669 | if (device->brightness) { | ||
1670 | kfree(device->brightness->levels); | ||
1671 | kfree(device->brightness); | ||
1672 | device->brightness = NULL; | ||
1673 | } | ||
1674 | if (device->cooling_dev) { | ||
1675 | sysfs_remove_link(&device->dev->dev.kobj, "thermal_cooling"); | ||
1676 | sysfs_remove_link(&device->cooling_dev->device.kobj, "device"); | ||
1677 | thermal_cooling_device_unregister(device->cooling_dev); | ||
1678 | device->cooling_dev = NULL; | ||
1679 | } | ||
1680 | } | ||
1681 | |||
1682 | static int acpi_video_bus_unregister_backlight(struct acpi_video_bus *video) | ||
1683 | { | ||
1684 | struct acpi_video_device *dev; | ||
1685 | int error = unregister_pm_notifier(&video->pm_nb); | ||
1686 | |||
1687 | mutex_lock(&video->device_list_lock); | ||
1688 | list_for_each_entry(dev, &video->video_device_list, entry) | ||
1689 | acpi_video_dev_unregister_backlight(dev); | ||
1690 | mutex_unlock(&video->device_list_lock); | ||
1691 | |||
1692 | return error; | ||
1693 | } | ||
1694 | |||
1695 | static void acpi_video_dev_add_notify_handler(struct acpi_video_device *device) | ||
1696 | { | ||
1697 | acpi_status status; | ||
1698 | struct acpi_device *adev = device->dev; | ||
1699 | |||
1700 | status = acpi_install_notify_handler(adev->handle, ACPI_DEVICE_NOTIFY, | ||
1701 | acpi_video_device_notify, device); | ||
1702 | if (ACPI_FAILURE(status)) | ||
1703 | dev_err(&adev->dev, "Error installing notify handler\n"); | ||
1704 | else | ||
1705 | device->flags.notify = 1; | ||
1706 | } | ||
1707 | |||
1708 | static int acpi_video_bus_add_notify_handler(struct acpi_video_bus *video) | ||
1709 | { | ||
1710 | struct input_dev *input; | ||
1711 | struct acpi_video_device *dev; | ||
1712 | int error; | ||
1713 | |||
1714 | video->input = input = input_allocate_device(); | ||
1715 | if (!input) { | ||
1716 | error = -ENOMEM; | ||
1717 | goto out; | ||
1718 | } | ||
1719 | |||
1720 | error = acpi_video_bus_start_devices(video); | ||
1721 | if (error) | ||
1722 | goto err_free_input; | ||
1723 | |||
1724 | snprintf(video->phys, sizeof(video->phys), | ||
1725 | "%s/video/input0", acpi_device_hid(video->device)); | ||
1726 | |||
1727 | input->name = acpi_device_name(video->device); | ||
1728 | input->phys = video->phys; | ||
1729 | input->id.bustype = BUS_HOST; | ||
1730 | input->id.product = 0x06; | ||
1731 | input->dev.parent = &video->device->dev; | ||
1732 | input->evbit[0] = BIT(EV_KEY); | ||
1733 | set_bit(KEY_SWITCHVIDEOMODE, input->keybit); | ||
1734 | set_bit(KEY_VIDEO_NEXT, input->keybit); | ||
1735 | set_bit(KEY_VIDEO_PREV, input->keybit); | ||
1736 | set_bit(KEY_BRIGHTNESS_CYCLE, input->keybit); | ||
1737 | set_bit(KEY_BRIGHTNESSUP, input->keybit); | ||
1738 | set_bit(KEY_BRIGHTNESSDOWN, input->keybit); | ||
1739 | set_bit(KEY_BRIGHTNESS_ZERO, input->keybit); | ||
1740 | set_bit(KEY_DISPLAY_OFF, input->keybit); | ||
1741 | |||
1742 | error = input_register_device(input); | ||
1743 | if (error) | ||
1744 | goto err_stop_dev; | ||
1745 | |||
1746 | mutex_lock(&video->device_list_lock); | ||
1747 | list_for_each_entry(dev, &video->video_device_list, entry) | ||
1748 | acpi_video_dev_add_notify_handler(dev); | ||
1749 | mutex_unlock(&video->device_list_lock); | ||
1750 | |||
1751 | return 0; | ||
1752 | |||
1753 | err_stop_dev: | ||
1754 | acpi_video_bus_stop_devices(video); | ||
1755 | err_free_input: | ||
1756 | input_free_device(input); | ||
1757 | video->input = NULL; | ||
1758 | out: | ||
1759 | return error; | ||
1760 | } | ||
1761 | |||
1762 | static void acpi_video_dev_remove_notify_handler(struct acpi_video_device *dev) | ||
1763 | { | ||
1764 | if (dev->flags.notify) { | ||
1765 | acpi_remove_notify_handler(dev->dev->handle, ACPI_DEVICE_NOTIFY, | ||
1766 | acpi_video_device_notify); | ||
1767 | dev->flags.notify = 0; | ||
1768 | } | ||
1769 | } | ||
1770 | |||
1771 | static void acpi_video_bus_remove_notify_handler(struct acpi_video_bus *video) | ||
1772 | { | ||
1773 | struct acpi_video_device *dev; | ||
1774 | |||
1775 | mutex_lock(&video->device_list_lock); | ||
1776 | list_for_each_entry(dev, &video->video_device_list, entry) | ||
1777 | acpi_video_dev_remove_notify_handler(dev); | ||
1778 | mutex_unlock(&video->device_list_lock); | ||
1779 | |||
1780 | acpi_video_bus_stop_devices(video); | ||
1781 | input_unregister_device(video->input); | ||
1782 | video->input = NULL; | ||
1783 | } | ||
1784 | |||
1785 | static int acpi_video_bus_put_devices(struct acpi_video_bus *video) | ||
1786 | { | ||
1787 | struct acpi_video_device *dev, *next; | ||
1788 | |||
1789 | mutex_lock(&video->device_list_lock); | ||
1790 | list_for_each_entry_safe(dev, next, &video->video_device_list, entry) { | ||
1791 | list_del(&dev->entry); | ||
1792 | kfree(dev); | ||
1793 | } | ||
1794 | mutex_unlock(&video->device_list_lock); | ||
1795 | |||
1796 | return 0; | ||
1797 | } | ||
1798 | |||
1694 | static int instance; | 1799 | static int instance; |
1695 | 1800 | ||
1696 | static int acpi_video_bus_add(struct acpi_device *device) | 1801 | static int acpi_video_bus_add(struct acpi_device *device) |
1697 | { | 1802 | { |
1698 | struct acpi_video_bus *video; | 1803 | struct acpi_video_bus *video; |
1699 | struct input_dev *input; | ||
1700 | int error; | 1804 | int error; |
1701 | acpi_status status; | 1805 | acpi_status status; |
1702 | 1806 | ||
@@ -1748,62 +1852,24 @@ static int acpi_video_bus_add(struct acpi_device *device) | |||
1748 | if (error) | 1852 | if (error) |
1749 | goto err_put_video; | 1853 | goto err_put_video; |
1750 | 1854 | ||
1751 | video->input = input = input_allocate_device(); | ||
1752 | if (!input) { | ||
1753 | error = -ENOMEM; | ||
1754 | goto err_put_video; | ||
1755 | } | ||
1756 | |||
1757 | error = acpi_video_bus_start_devices(video); | ||
1758 | if (error) | ||
1759 | goto err_free_input_dev; | ||
1760 | |||
1761 | snprintf(video->phys, sizeof(video->phys), | ||
1762 | "%s/video/input0", acpi_device_hid(video->device)); | ||
1763 | |||
1764 | input->name = acpi_device_name(video->device); | ||
1765 | input->phys = video->phys; | ||
1766 | input->id.bustype = BUS_HOST; | ||
1767 | input->id.product = 0x06; | ||
1768 | input->dev.parent = &device->dev; | ||
1769 | input->evbit[0] = BIT(EV_KEY); | ||
1770 | set_bit(KEY_SWITCHVIDEOMODE, input->keybit); | ||
1771 | set_bit(KEY_VIDEO_NEXT, input->keybit); | ||
1772 | set_bit(KEY_VIDEO_PREV, input->keybit); | ||
1773 | set_bit(KEY_BRIGHTNESS_CYCLE, input->keybit); | ||
1774 | set_bit(KEY_BRIGHTNESSUP, input->keybit); | ||
1775 | set_bit(KEY_BRIGHTNESSDOWN, input->keybit); | ||
1776 | set_bit(KEY_BRIGHTNESS_ZERO, input->keybit); | ||
1777 | set_bit(KEY_DISPLAY_OFF, input->keybit); | ||
1778 | |||
1779 | printk(KERN_INFO PREFIX "%s [%s] (multi-head: %s rom: %s post: %s)\n", | 1855 | printk(KERN_INFO PREFIX "%s [%s] (multi-head: %s rom: %s post: %s)\n", |
1780 | ACPI_VIDEO_DEVICE_NAME, acpi_device_bid(device), | 1856 | ACPI_VIDEO_DEVICE_NAME, acpi_device_bid(device), |
1781 | video->flags.multihead ? "yes" : "no", | 1857 | video->flags.multihead ? "yes" : "no", |
1782 | video->flags.rom ? "yes" : "no", | 1858 | video->flags.rom ? "yes" : "no", |
1783 | video->flags.post ? "yes" : "no"); | 1859 | video->flags.post ? "yes" : "no"); |
1860 | mutex_lock(&video_list_lock); | ||
1861 | list_add_tail(&video->entry, &video_bus_head); | ||
1862 | mutex_unlock(&video_list_lock); | ||
1784 | 1863 | ||
1785 | video->pm_nb.notifier_call = acpi_video_resume; | 1864 | acpi_video_bus_register_backlight(video); |
1786 | video->pm_nb.priority = 0; | 1865 | acpi_video_bus_add_notify_handler(video); |
1787 | error = register_pm_notifier(&video->pm_nb); | ||
1788 | if (error) | ||
1789 | goto err_stop_video; | ||
1790 | |||
1791 | error = input_register_device(input); | ||
1792 | if (error) | ||
1793 | goto err_unregister_pm_notifier; | ||
1794 | 1866 | ||
1795 | return 0; | 1867 | return 0; |
1796 | 1868 | ||
1797 | err_unregister_pm_notifier: | 1869 | err_put_video: |
1798 | unregister_pm_notifier(&video->pm_nb); | ||
1799 | err_stop_video: | ||
1800 | acpi_video_bus_stop_devices(video); | ||
1801 | err_free_input_dev: | ||
1802 | input_free_device(input); | ||
1803 | err_put_video: | ||
1804 | acpi_video_bus_put_devices(video); | 1870 | acpi_video_bus_put_devices(video); |
1805 | kfree(video->attached_array); | 1871 | kfree(video->attached_array); |
1806 | err_free_video: | 1872 | err_free_video: |
1807 | kfree(video); | 1873 | kfree(video); |
1808 | device->driver_data = NULL; | 1874 | device->driver_data = NULL; |
1809 | 1875 | ||
@@ -1820,12 +1886,14 @@ static int acpi_video_bus_remove(struct acpi_device *device) | |||
1820 | 1886 | ||
1821 | video = acpi_driver_data(device); | 1887 | video = acpi_driver_data(device); |
1822 | 1888 | ||
1823 | unregister_pm_notifier(&video->pm_nb); | 1889 | acpi_video_bus_remove_notify_handler(video); |
1824 | 1890 | acpi_video_bus_unregister_backlight(video); | |
1825 | acpi_video_bus_stop_devices(video); | ||
1826 | acpi_video_bus_put_devices(video); | 1891 | acpi_video_bus_put_devices(video); |
1827 | 1892 | ||
1828 | input_unregister_device(video->input); | 1893 | mutex_lock(&video_list_lock); |
1894 | list_del(&video->entry); | ||
1895 | mutex_unlock(&video_list_lock); | ||
1896 | |||
1829 | kfree(video->attached_array); | 1897 | kfree(video->attached_array); |
1830 | kfree(video); | 1898 | kfree(video); |
1831 | 1899 | ||
@@ -1874,6 +1942,9 @@ int acpi_video_register(void) | |||
1874 | return 0; | 1942 | return 0; |
1875 | } | 1943 | } |
1876 | 1944 | ||
1945 | mutex_init(&video_list_lock); | ||
1946 | INIT_LIST_HEAD(&video_bus_head); | ||
1947 | |||
1877 | result = acpi_bus_register_driver(&acpi_video_bus); | 1948 | result = acpi_bus_register_driver(&acpi_video_bus); |
1878 | if (result < 0) | 1949 | if (result < 0) |
1879 | return -ENODEV; | 1950 | return -ENODEV; |
diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c index 940edbf2fe8f..84875fd4c74f 100644 --- a/drivers/acpi/video_detect.c +++ b/drivers/acpi/video_detect.c | |||
@@ -168,6 +168,14 @@ static struct dmi_system_id video_detect_dmi_table[] = { | |||
168 | DMI_MATCH(DMI_PRODUCT_NAME, "UL30A"), | 168 | DMI_MATCH(DMI_PRODUCT_NAME, "UL30A"), |
169 | }, | 169 | }, |
170 | }, | 170 | }, |
171 | { | ||
172 | .callback = video_detect_force_vendor, | ||
173 | .ident = "Lenovo Yoga 13", | ||
174 | .matches = { | ||
175 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
176 | DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo IdeaPad Yoga 13"), | ||
177 | }, | ||
178 | }, | ||
171 | { }, | 179 | { }, |
172 | }; | 180 | }; |
173 | 181 | ||
@@ -233,11 +241,11 @@ static void acpi_video_caps_check(void) | |||
233 | acpi_video_get_capabilities(NULL); | 241 | acpi_video_get_capabilities(NULL); |
234 | } | 242 | } |
235 | 243 | ||
236 | bool acpi_video_backlight_quirks(void) | 244 | bool acpi_osi_is_win8(void) |
237 | { | 245 | { |
238 | return acpi_gbl_osi_data >= ACPI_OSI_WIN_8; | 246 | return acpi_gbl_osi_data >= ACPI_OSI_WIN_8; |
239 | } | 247 | } |
240 | EXPORT_SYMBOL(acpi_video_backlight_quirks); | 248 | EXPORT_SYMBOL(acpi_osi_is_win8); |
241 | 249 | ||
242 | /* Promote the vendor interface instead of the generic video module. | 250 | /* Promote the vendor interface instead of the generic video module. |
243 | * This function allow DMI blacklists to be implemented by externals | 251 | * This function allow DMI blacklists to be implemented by externals |