diff options
Diffstat (limited to 'drivers/acpi')
114 files changed, 5370 insertions, 2661 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index f26db487752b..dd8729d674e5 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig | |||
@@ -86,6 +86,17 @@ config ACPI_PROCFS_POWER | |||
86 | 86 | ||
87 | Say N to delete power /proc/acpi/ directories that have moved to /sys/ | 87 | Say N to delete power /proc/acpi/ directories that have moved to /sys/ |
88 | 88 | ||
89 | config ACPI_POWER_METER | ||
90 | tristate "ACPI 4.0 power meter" | ||
91 | depends on HWMON | ||
92 | help | ||
93 | This driver exposes ACPI 4.0 power meters as hardware monitoring | ||
94 | devices. Say Y (or M) if you have a computer with ACPI 4.0 firmware | ||
95 | and a power meter. | ||
96 | |||
97 | To compile this driver as a module, choose M here: | ||
98 | the module will be called power-meter. | ||
99 | |||
89 | config ACPI_SYSFS_POWER | 100 | config ACPI_SYSFS_POWER |
90 | bool "Future power /sys interface" | 101 | bool "Future power /sys interface" |
91 | select POWER_SUPPLY | 102 | select POWER_SUPPLY |
@@ -270,6 +281,7 @@ config ACPI_DEBUG_FUNC_TRACE | |||
270 | 281 | ||
271 | config ACPI_PCI_SLOT | 282 | config ACPI_PCI_SLOT |
272 | tristate "PCI slot detection driver" | 283 | tristate "PCI slot detection driver" |
284 | depends on SYSFS | ||
273 | default n | 285 | default n |
274 | help | 286 | help |
275 | This driver creates entries in /sys/bus/pci/slots/ for all PCI | 287 | This driver creates entries in /sys/bus/pci/slots/ for all PCI |
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index 03a985be3fe3..82cd49dc603b 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile | |||
@@ -56,6 +56,7 @@ obj-$(CONFIG_ACPI_HOTPLUG_MEMORY) += acpi_memhotplug.o | |||
56 | obj-$(CONFIG_ACPI_BATTERY) += battery.o | 56 | obj-$(CONFIG_ACPI_BATTERY) += battery.o |
57 | obj-$(CONFIG_ACPI_SBS) += sbshc.o | 57 | obj-$(CONFIG_ACPI_SBS) += sbshc.o |
58 | obj-$(CONFIG_ACPI_SBS) += sbs.o | 58 | obj-$(CONFIG_ACPI_SBS) += sbs.o |
59 | obj-$(CONFIG_ACPI_POWER_METER) += power_meter.o | ||
59 | 60 | ||
60 | # processor has its own "processor." module_param namespace | 61 | # processor has its own "processor." module_param namespace |
61 | processor-y := processor_core.o processor_throttling.o | 62 | processor-y := processor_core.o processor_throttling.o |
diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c index 88e42abf5d88..98b9690b0159 100644 --- a/drivers/acpi/ac.c +++ b/drivers/acpi/ac.c | |||
@@ -37,6 +37,8 @@ | |||
37 | #include <acpi/acpi_bus.h> | 37 | #include <acpi/acpi_bus.h> |
38 | #include <acpi/acpi_drivers.h> | 38 | #include <acpi/acpi_drivers.h> |
39 | 39 | ||
40 | #define PREFIX "ACPI: " | ||
41 | |||
40 | #define ACPI_AC_CLASS "ac_adapter" | 42 | #define ACPI_AC_CLASS "ac_adapter" |
41 | #define ACPI_AC_DEVICE_NAME "AC Adapter" | 43 | #define ACPI_AC_DEVICE_NAME "AC Adapter" |
42 | #define ACPI_AC_FILE_STATE "state" | 44 | #define ACPI_AC_FILE_STATE "state" |
@@ -61,6 +63,7 @@ static int acpi_ac_open_fs(struct inode *inode, struct file *file); | |||
61 | static int acpi_ac_add(struct acpi_device *device); | 63 | static int acpi_ac_add(struct acpi_device *device); |
62 | static int acpi_ac_remove(struct acpi_device *device, int type); | 64 | static int acpi_ac_remove(struct acpi_device *device, int type); |
63 | static int acpi_ac_resume(struct acpi_device *device); | 65 | static int acpi_ac_resume(struct acpi_device *device); |
66 | static void acpi_ac_notify(struct acpi_device *device, u32 event); | ||
64 | 67 | ||
65 | static const struct acpi_device_id ac_device_ids[] = { | 68 | static const struct acpi_device_id ac_device_ids[] = { |
66 | {"ACPI0003", 0}, | 69 | {"ACPI0003", 0}, |
@@ -72,10 +75,12 @@ static struct acpi_driver acpi_ac_driver = { | |||
72 | .name = "ac", | 75 | .name = "ac", |
73 | .class = ACPI_AC_CLASS, | 76 | .class = ACPI_AC_CLASS, |
74 | .ids = ac_device_ids, | 77 | .ids = ac_device_ids, |
78 | .flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS, | ||
75 | .ops = { | 79 | .ops = { |
76 | .add = acpi_ac_add, | 80 | .add = acpi_ac_add, |
77 | .remove = acpi_ac_remove, | 81 | .remove = acpi_ac_remove, |
78 | .resume = acpi_ac_resume, | 82 | .resume = acpi_ac_resume, |
83 | .notify = acpi_ac_notify, | ||
79 | }, | 84 | }, |
80 | }; | 85 | }; |
81 | 86 | ||
@@ -220,16 +225,14 @@ static int acpi_ac_remove_fs(struct acpi_device *device) | |||
220 | Driver Model | 225 | Driver Model |
221 | -------------------------------------------------------------------------- */ | 226 | -------------------------------------------------------------------------- */ |
222 | 227 | ||
223 | static void acpi_ac_notify(acpi_handle handle, u32 event, void *data) | 228 | static void acpi_ac_notify(struct acpi_device *device, u32 event) |
224 | { | 229 | { |
225 | struct acpi_ac *ac = data; | 230 | struct acpi_ac *ac = acpi_driver_data(device); |
226 | struct acpi_device *device = NULL; | ||
227 | 231 | ||
228 | 232 | ||
229 | if (!ac) | 233 | if (!ac) |
230 | return; | 234 | return; |
231 | 235 | ||
232 | device = ac->device; | ||
233 | switch (event) { | 236 | switch (event) { |
234 | default: | 237 | default: |
235 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 238 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
@@ -253,7 +256,6 @@ static void acpi_ac_notify(acpi_handle handle, u32 event, void *data) | |||
253 | static int acpi_ac_add(struct acpi_device *device) | 256 | static int acpi_ac_add(struct acpi_device *device) |
254 | { | 257 | { |
255 | int result = 0; | 258 | int result = 0; |
256 | acpi_status status = AE_OK; | ||
257 | struct acpi_ac *ac = NULL; | 259 | struct acpi_ac *ac = NULL; |
258 | 260 | ||
259 | 261 | ||
@@ -286,13 +288,6 @@ static int acpi_ac_add(struct acpi_device *device) | |||
286 | ac->charger.get_property = get_ac_property; | 288 | ac->charger.get_property = get_ac_property; |
287 | power_supply_register(&ac->device->dev, &ac->charger); | 289 | power_supply_register(&ac->device->dev, &ac->charger); |
288 | #endif | 290 | #endif |
289 | status = acpi_install_notify_handler(device->handle, | ||
290 | ACPI_ALL_NOTIFY, acpi_ac_notify, | ||
291 | ac); | ||
292 | if (ACPI_FAILURE(status)) { | ||
293 | result = -ENODEV; | ||
294 | goto end; | ||
295 | } | ||
296 | 291 | ||
297 | printk(KERN_INFO PREFIX "%s [%s] (%s)\n", | 292 | printk(KERN_INFO PREFIX "%s [%s] (%s)\n", |
298 | acpi_device_name(device), acpi_device_bid(device), | 293 | acpi_device_name(device), acpi_device_bid(device), |
@@ -328,7 +323,6 @@ static int acpi_ac_resume(struct acpi_device *device) | |||
328 | 323 | ||
329 | static int acpi_ac_remove(struct acpi_device *device, int type) | 324 | static int acpi_ac_remove(struct acpi_device *device, int type) |
330 | { | 325 | { |
331 | acpi_status status = AE_OK; | ||
332 | struct acpi_ac *ac = NULL; | 326 | struct acpi_ac *ac = NULL; |
333 | 327 | ||
334 | 328 | ||
@@ -337,8 +331,6 @@ static int acpi_ac_remove(struct acpi_device *device, int type) | |||
337 | 331 | ||
338 | ac = acpi_driver_data(device); | 332 | ac = acpi_driver_data(device); |
339 | 333 | ||
340 | status = acpi_remove_notify_handler(device->handle, | ||
341 | ACPI_ALL_NOTIFY, acpi_ac_notify); | ||
342 | #ifdef CONFIG_ACPI_SYSFS_POWER | 334 | #ifdef CONFIG_ACPI_SYSFS_POWER |
343 | if (ac->charger.dev) | 335 | if (ac->charger.dev) |
344 | power_supply_unregister(&ac->charger); | 336 | power_supply_unregister(&ac->charger); |
diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c index 7a0f4aa4fa1e..28ccdbc05ac8 100644 --- a/drivers/acpi/acpi_memhotplug.c +++ b/drivers/acpi/acpi_memhotplug.c | |||
@@ -38,6 +38,9 @@ | |||
38 | 38 | ||
39 | #define _COMPONENT ACPI_MEMORY_DEVICE_COMPONENT | 39 | #define _COMPONENT ACPI_MEMORY_DEVICE_COMPONENT |
40 | 40 | ||
41 | #undef PREFIX | ||
42 | #define PREFIX "ACPI:memory_hp:" | ||
43 | |||
41 | ACPI_MODULE_NAME("acpi_memhotplug"); | 44 | ACPI_MODULE_NAME("acpi_memhotplug"); |
42 | MODULE_AUTHOR("Naveen B S <naveen.b.s@intel.com>"); | 45 | MODULE_AUTHOR("Naveen B S <naveen.b.s@intel.com>"); |
43 | MODULE_DESCRIPTION("Hotplug Mem Driver"); | 46 | MODULE_DESCRIPTION("Hotplug Mem Driver"); |
@@ -50,7 +53,6 @@ MODULE_LICENSE("GPL"); | |||
50 | 53 | ||
51 | static int acpi_memory_device_add(struct acpi_device *device); | 54 | static int acpi_memory_device_add(struct acpi_device *device); |
52 | static int acpi_memory_device_remove(struct acpi_device *device, int type); | 55 | static int acpi_memory_device_remove(struct acpi_device *device, int type); |
53 | static int acpi_memory_device_start(struct acpi_device *device); | ||
54 | 56 | ||
55 | static const struct acpi_device_id memory_device_ids[] = { | 57 | static const struct acpi_device_id memory_device_ids[] = { |
56 | {ACPI_MEMORY_DEVICE_HID, 0}, | 58 | {ACPI_MEMORY_DEVICE_HID, 0}, |
@@ -65,7 +67,6 @@ static struct acpi_driver acpi_memory_device_driver = { | |||
65 | .ops = { | 67 | .ops = { |
66 | .add = acpi_memory_device_add, | 68 | .add = acpi_memory_device_add, |
67 | .remove = acpi_memory_device_remove, | 69 | .remove = acpi_memory_device_remove, |
68 | .start = acpi_memory_device_start, | ||
69 | }, | 70 | }, |
70 | }; | 71 | }; |
71 | 72 | ||
@@ -153,6 +154,7 @@ acpi_memory_get_device(acpi_handle handle, | |||
153 | acpi_handle phandle; | 154 | acpi_handle phandle; |
154 | struct acpi_device *device = NULL; | 155 | struct acpi_device *device = NULL; |
155 | struct acpi_device *pdevice = NULL; | 156 | struct acpi_device *pdevice = NULL; |
157 | int result; | ||
156 | 158 | ||
157 | 159 | ||
158 | if (!acpi_bus_get_device(handle, &device) && device) | 160 | if (!acpi_bus_get_device(handle, &device) && device) |
@@ -165,9 +167,9 @@ acpi_memory_get_device(acpi_handle handle, | |||
165 | } | 167 | } |
166 | 168 | ||
167 | /* Get the parent device */ | 169 | /* Get the parent device */ |
168 | status = acpi_bus_get_device(phandle, &pdevice); | 170 | result = acpi_bus_get_device(phandle, &pdevice); |
169 | if (ACPI_FAILURE(status)) { | 171 | if (result) { |
170 | ACPI_EXCEPTION((AE_INFO, status, "Cannot get acpi bus device")); | 172 | printk(KERN_WARNING PREFIX "Cannot get acpi bus device"); |
171 | return -EINVAL; | 173 | return -EINVAL; |
172 | } | 174 | } |
173 | 175 | ||
@@ -175,9 +177,9 @@ acpi_memory_get_device(acpi_handle handle, | |||
175 | * Now add the notified device. This creates the acpi_device | 177 | * Now add the notified device. This creates the acpi_device |
176 | * and invokes .add function | 178 | * and invokes .add function |
177 | */ | 179 | */ |
178 | status = acpi_bus_add(&device, pdevice, handle, ACPI_BUS_TYPE_DEVICE); | 180 | result = acpi_bus_add(&device, pdevice, handle, ACPI_BUS_TYPE_DEVICE); |
179 | if (ACPI_FAILURE(status)) { | 181 | if (result) { |
180 | ACPI_EXCEPTION((AE_INFO, status, "Cannot add acpi bus")); | 182 | printk(KERN_WARNING PREFIX "Cannot add acpi bus"); |
181 | return -EINVAL; | 183 | return -EINVAL; |
182 | } | 184 | } |
183 | 185 | ||
@@ -238,7 +240,12 @@ static int acpi_memory_enable_device(struct acpi_memory_device *mem_device) | |||
238 | num_enabled++; | 240 | num_enabled++; |
239 | continue; | 241 | continue; |
240 | } | 242 | } |
241 | 243 | /* | |
244 | * If the memory block size is zero, please ignore it. | ||
245 | * Don't try to do the following memory hotplug flowchart. | ||
246 | */ | ||
247 | if (!info->length) | ||
248 | continue; | ||
242 | if (node < 0) | 249 | if (node < 0) |
243 | node = memory_add_physaddr_to_nid(info->start_addr); | 250 | node = memory_add_physaddr_to_nid(info->start_addr); |
244 | 251 | ||
@@ -253,8 +260,15 @@ static int acpi_memory_enable_device(struct acpi_memory_device *mem_device) | |||
253 | mem_device->state = MEMORY_INVALID_STATE; | 260 | mem_device->state = MEMORY_INVALID_STATE; |
254 | return -EINVAL; | 261 | return -EINVAL; |
255 | } | 262 | } |
256 | 263 | /* | |
257 | return result; | 264 | * Sometimes the memory device will contain several memory blocks. |
265 | * When one memory block is hot-added to the system memory, it will | ||
266 | * be regarded as a success. | ||
267 | * Otherwise if the last memory block can't be hot-added to the system | ||
268 | * memory, it will be failure and the memory device can't be bound with | ||
269 | * driver. | ||
270 | */ | ||
271 | return 0; | ||
258 | } | 272 | } |
259 | 273 | ||
260 | static int acpi_memory_powerdown_device(struct acpi_memory_device *mem_device) | 274 | static int acpi_memory_powerdown_device(struct acpi_memory_device *mem_device) |
@@ -415,28 +429,6 @@ static int acpi_memory_device_add(struct acpi_device *device) | |||
415 | 429 | ||
416 | printk(KERN_DEBUG "%s \n", acpi_device_name(device)); | 430 | printk(KERN_DEBUG "%s \n", acpi_device_name(device)); |
417 | 431 | ||
418 | return result; | ||
419 | } | ||
420 | |||
421 | static int acpi_memory_device_remove(struct acpi_device *device, int type) | ||
422 | { | ||
423 | struct acpi_memory_device *mem_device = NULL; | ||
424 | |||
425 | |||
426 | if (!device || !acpi_driver_data(device)) | ||
427 | return -EINVAL; | ||
428 | |||
429 | mem_device = acpi_driver_data(device); | ||
430 | kfree(mem_device); | ||
431 | |||
432 | return 0; | ||
433 | } | ||
434 | |||
435 | static int acpi_memory_device_start (struct acpi_device *device) | ||
436 | { | ||
437 | struct acpi_memory_device *mem_device; | ||
438 | int result = 0; | ||
439 | |||
440 | /* | 432 | /* |
441 | * Early boot code has recognized memory area by EFI/E820. | 433 | * Early boot code has recognized memory area by EFI/E820. |
442 | * If DSDT shows these memory devices on boot, hotplug is not necessary | 434 | * If DSDT shows these memory devices on boot, hotplug is not necessary |
@@ -446,8 +438,6 @@ static int acpi_memory_device_start (struct acpi_device *device) | |||
446 | if (!acpi_hotmem_initialized) | 438 | if (!acpi_hotmem_initialized) |
447 | return 0; | 439 | return 0; |
448 | 440 | ||
449 | mem_device = acpi_driver_data(device); | ||
450 | |||
451 | if (!acpi_memory_check_device(mem_device)) { | 441 | if (!acpi_memory_check_device(mem_device)) { |
452 | /* call add_memory func */ | 442 | /* call add_memory func */ |
453 | result = acpi_memory_enable_device(mem_device); | 443 | result = acpi_memory_enable_device(mem_device); |
@@ -458,6 +448,20 @@ static int acpi_memory_device_start (struct acpi_device *device) | |||
458 | return result; | 448 | return result; |
459 | } | 449 | } |
460 | 450 | ||
451 | static int acpi_memory_device_remove(struct acpi_device *device, int type) | ||
452 | { | ||
453 | struct acpi_memory_device *mem_device = NULL; | ||
454 | |||
455 | |||
456 | if (!device || !acpi_driver_data(device)) | ||
457 | return -EINVAL; | ||
458 | |||
459 | mem_device = acpi_driver_data(device); | ||
460 | kfree(mem_device); | ||
461 | |||
462 | return 0; | ||
463 | } | ||
464 | |||
461 | /* | 465 | /* |
462 | * Helper function to check for memory device | 466 | * Helper function to check for memory device |
463 | */ | 467 | */ |
@@ -465,26 +469,23 @@ static acpi_status is_memory_device(acpi_handle handle) | |||
465 | { | 469 | { |
466 | char *hardware_id; | 470 | char *hardware_id; |
467 | acpi_status status; | 471 | acpi_status status; |
468 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
469 | struct acpi_device_info *info; | 472 | struct acpi_device_info *info; |
470 | 473 | ||
471 | 474 | status = acpi_get_object_info(handle, &info); | |
472 | status = acpi_get_object_info(handle, &buffer); | ||
473 | if (ACPI_FAILURE(status)) | 475 | if (ACPI_FAILURE(status)) |
474 | return status; | 476 | return status; |
475 | 477 | ||
476 | info = buffer.pointer; | ||
477 | if (!(info->valid & ACPI_VALID_HID)) { | 478 | if (!(info->valid & ACPI_VALID_HID)) { |
478 | kfree(buffer.pointer); | 479 | kfree(info); |
479 | return AE_ERROR; | 480 | return AE_ERROR; |
480 | } | 481 | } |
481 | 482 | ||
482 | hardware_id = info->hardware_id.value; | 483 | hardware_id = info->hardware_id.string; |
483 | if ((hardware_id == NULL) || | 484 | if ((hardware_id == NULL) || |
484 | (strcmp(hardware_id, ACPI_MEMORY_DEVICE_HID))) | 485 | (strcmp(hardware_id, ACPI_MEMORY_DEVICE_HID))) |
485 | status = AE_ERROR; | 486 | status = AE_ERROR; |
486 | 487 | ||
487 | kfree(buffer.pointer); | 488 | kfree(info); |
488 | return status; | 489 | return status; |
489 | } | 490 | } |
490 | 491 | ||
diff --git a/drivers/acpi/acpica/Makefile b/drivers/acpi/acpica/Makefile index 72ac28da14e3..e7973bc16846 100644 --- a/drivers/acpi/acpica/Makefile +++ b/drivers/acpi/acpica/Makefile | |||
@@ -28,7 +28,7 @@ acpi-$(ACPI_FUTURE_USAGE) += hwtimer.o | |||
28 | acpi-y += nsaccess.o nsload.o nssearch.o nsxfeval.o \ | 28 | acpi-y += nsaccess.o nsload.o nssearch.o nsxfeval.o \ |
29 | nsalloc.o nseval.o nsnames.o nsutils.o nsxfname.o \ | 29 | nsalloc.o nseval.o nsnames.o nsutils.o nsxfname.o \ |
30 | nsdump.o nsinit.o nsobject.o nswalk.o nsxfobj.o \ | 30 | nsdump.o nsinit.o nsobject.o nswalk.o nsxfobj.o \ |
31 | nsparse.o nspredef.o | 31 | nsparse.o nspredef.o nsrepair.o |
32 | 32 | ||
33 | acpi-$(ACPI_FUTURE_USAGE) += nsdumpdv.o | 33 | acpi-$(ACPI_FUTURE_USAGE) += nsdumpdv.o |
34 | 34 | ||
@@ -44,4 +44,4 @@ acpi-y += tbxface.o tbinstal.o tbutils.o tbfind.o tbfadt.o tbxfroot.o | |||
44 | 44 | ||
45 | acpi-y += utalloc.o utdebug.o uteval.o utinit.o utmisc.o utxface.o \ | 45 | acpi-y += utalloc.o utdebug.o uteval.o utinit.o utmisc.o utxface.o \ |
46 | utcopy.o utdelete.o utglobal.o utmath.o utobject.o \ | 46 | utcopy.o utdelete.o utglobal.o utmath.o utobject.o \ |
47 | utstate.o utmutex.o utobject.o utresrc.o utlock.o | 47 | utstate.o utmutex.o utobject.o utresrc.o utlock.o utids.o |
diff --git a/drivers/acpi/acpica/acconfig.h b/drivers/acpi/acpica/acconfig.h index e6777fb883d2..8e679ef5b231 100644 --- a/drivers/acpi/acpica/acconfig.h +++ b/drivers/acpi/acpica/acconfig.h | |||
@@ -183,7 +183,7 @@ | |||
183 | 183 | ||
184 | /* Operation regions */ | 184 | /* Operation regions */ |
185 | 185 | ||
186 | #define ACPI_NUM_PREDEFINED_REGIONS 8 | 186 | #define ACPI_NUM_PREDEFINED_REGIONS 9 |
187 | #define ACPI_USER_REGION_BEGIN 0x80 | 187 | #define ACPI_USER_REGION_BEGIN 0x80 |
188 | 188 | ||
189 | /* Maximum space_ids for Operation Regions */ | 189 | /* Maximum space_ids for Operation Regions */ |
@@ -199,9 +199,15 @@ | |||
199 | #define ACPI_RSDP_CHECKSUM_LENGTH 20 | 199 | #define ACPI_RSDP_CHECKSUM_LENGTH 20 |
200 | #define ACPI_RSDP_XCHECKSUM_LENGTH 36 | 200 | #define ACPI_RSDP_XCHECKSUM_LENGTH 36 |
201 | 201 | ||
202 | /* SMBus bidirectional buffer size */ | 202 | /* SMBus and IPMI bidirectional buffer size */ |
203 | 203 | ||
204 | #define ACPI_SMBUS_BUFFER_SIZE 34 | 204 | #define ACPI_SMBUS_BUFFER_SIZE 34 |
205 | #define ACPI_IPMI_BUFFER_SIZE 66 | ||
206 | |||
207 | /* _sx_d and _sx_w control methods */ | ||
208 | |||
209 | #define ACPI_NUM_sx_d_METHODS 4 | ||
210 | #define ACPI_NUM_sx_w_METHODS 5 | ||
205 | 211 | ||
206 | /****************************************************************************** | 212 | /****************************************************************************** |
207 | * | 213 | * |
diff --git a/drivers/acpi/acpica/acdebug.h b/drivers/acpi/acpica/acdebug.h index 62c59df3b86c..a4fb001d96f1 100644 --- a/drivers/acpi/acpica/acdebug.h +++ b/drivers/acpi/acpica/acdebug.h | |||
@@ -154,10 +154,6 @@ void | |||
154 | acpi_db_display_argument_object(union acpi_operand_object *obj_desc, | 154 | acpi_db_display_argument_object(union acpi_operand_object *obj_desc, |
155 | struct acpi_walk_state *walk_state); | 155 | struct acpi_walk_state *walk_state); |
156 | 156 | ||
157 | void acpi_db_check_predefined_names(void); | ||
158 | |||
159 | void acpi_db_batch_execute(void); | ||
160 | |||
161 | /* | 157 | /* |
162 | * dbexec - debugger control method execution | 158 | * dbexec - debugger control method execution |
163 | */ | 159 | */ |
diff --git a/drivers/acpi/acpica/acevents.h b/drivers/acpi/acpica/acevents.h index 07e20135f01b..0bba148a2c61 100644 --- a/drivers/acpi/acpica/acevents.h +++ b/drivers/acpi/acpica/acevents.h | |||
@@ -139,7 +139,7 @@ acpi_status acpi_ev_initialize_op_regions(void); | |||
139 | acpi_status | 139 | acpi_status |
140 | acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, | 140 | acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, |
141 | u32 function, | 141 | u32 function, |
142 | acpi_physical_address address, | 142 | u32 region_offset, |
143 | u32 bit_width, acpi_integer * value); | 143 | u32 bit_width, acpi_integer * value); |
144 | 144 | ||
145 | acpi_status | 145 | acpi_status |
diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h index 16e5210ae936..29ba66d5a790 100644 --- a/drivers/acpi/acpica/acglobal.h +++ b/drivers/acpi/acpica/acglobal.h | |||
@@ -58,6 +58,10 @@ | |||
58 | #define ACPI_INIT_GLOBAL(a,b) a | 58 | #define ACPI_INIT_GLOBAL(a,b) a |
59 | #endif | 59 | #endif |
60 | 60 | ||
61 | #ifdef DEFINE_ACPI_GLOBALS | ||
62 | |||
63 | /* Public globals, available from outside ACPICA subsystem */ | ||
64 | |||
61 | /***************************************************************************** | 65 | /***************************************************************************** |
62 | * | 66 | * |
63 | * Runtime configuration (static defaults that can be overriden at runtime) | 67 | * Runtime configuration (static defaults that can be overriden at runtime) |
@@ -78,7 +82,7 @@ | |||
78 | * 5) Allow unresolved references (invalid target name) in package objects | 82 | * 5) Allow unresolved references (invalid target name) in package objects |
79 | * 6) Enable warning messages for behavior that is not ACPI spec compliant | 83 | * 6) Enable warning messages for behavior that is not ACPI spec compliant |
80 | */ | 84 | */ |
81 | ACPI_EXTERN u8 ACPI_INIT_GLOBAL(acpi_gbl_enable_interpreter_slack, FALSE); | 85 | u8 ACPI_INIT_GLOBAL(acpi_gbl_enable_interpreter_slack, FALSE); |
82 | 86 | ||
83 | /* | 87 | /* |
84 | * Automatically serialize ALL control methods? Default is FALSE, meaning | 88 | * Automatically serialize ALL control methods? Default is FALSE, meaning |
@@ -86,27 +90,36 @@ ACPI_EXTERN u8 ACPI_INIT_GLOBAL(acpi_gbl_enable_interpreter_slack, FALSE); | |||
86 | * Only change this if the ASL code is poorly written and cannot handle | 90 | * Only change this if the ASL code is poorly written and cannot handle |
87 | * reentrancy even though methods are marked "NotSerialized". | 91 | * reentrancy even though methods are marked "NotSerialized". |
88 | */ | 92 | */ |
89 | ACPI_EXTERN u8 ACPI_INIT_GLOBAL(acpi_gbl_all_methods_serialized, FALSE); | 93 | u8 ACPI_INIT_GLOBAL(acpi_gbl_all_methods_serialized, FALSE); |
90 | 94 | ||
91 | /* | 95 | /* |
92 | * Create the predefined _OSI method in the namespace? Default is TRUE | 96 | * Create the predefined _OSI method in the namespace? Default is TRUE |
93 | * because ACPI CA is fully compatible with other ACPI implementations. | 97 | * because ACPI CA is fully compatible with other ACPI implementations. |
94 | * Changing this will revert ACPI CA (and machine ASL) to pre-OSI behavior. | 98 | * Changing this will revert ACPI CA (and machine ASL) to pre-OSI behavior. |
95 | */ | 99 | */ |
96 | ACPI_EXTERN u8 ACPI_INIT_GLOBAL(acpi_gbl_create_osi_method, TRUE); | 100 | u8 ACPI_INIT_GLOBAL(acpi_gbl_create_osi_method, TRUE); |
97 | 101 | ||
98 | /* | 102 | /* |
99 | * Disable wakeup GPEs during runtime? Default is TRUE because WAKE and | 103 | * Disable wakeup GPEs during runtime? Default is TRUE because WAKE and |
100 | * RUNTIME GPEs should never be shared, and WAKE GPEs should typically only | 104 | * RUNTIME GPEs should never be shared, and WAKE GPEs should typically only |
101 | * be enabled just before going to sleep. | 105 | * be enabled just before going to sleep. |
102 | */ | 106 | */ |
103 | ACPI_EXTERN u8 ACPI_INIT_GLOBAL(acpi_gbl_leave_wake_gpes_disabled, TRUE); | 107 | u8 ACPI_INIT_GLOBAL(acpi_gbl_leave_wake_gpes_disabled, TRUE); |
104 | 108 | ||
105 | /* | 109 | /* |
106 | * Optionally use default values for the ACPI register widths. Set this to | 110 | * Optionally use default values for the ACPI register widths. Set this to |
107 | * TRUE to use the defaults, if an FADT contains incorrect widths/lengths. | 111 | * TRUE to use the defaults, if an FADT contains incorrect widths/lengths. |
108 | */ | 112 | */ |
109 | ACPI_EXTERN u8 ACPI_INIT_GLOBAL(acpi_gbl_use_default_register_widths, TRUE); | 113 | u8 ACPI_INIT_GLOBAL(acpi_gbl_use_default_register_widths, TRUE); |
114 | |||
115 | /* acpi_gbl_FADT is a local copy of the FADT, converted to a common format. */ | ||
116 | |||
117 | struct acpi_table_fadt acpi_gbl_FADT; | ||
118 | u32 acpi_current_gpe_count; | ||
119 | u32 acpi_gbl_trace_flags; | ||
120 | acpi_name acpi_gbl_trace_method_name; | ||
121 | |||
122 | #endif | ||
110 | 123 | ||
111 | /***************************************************************************** | 124 | /***************************************************************************** |
112 | * | 125 | * |
@@ -114,11 +127,6 @@ ACPI_EXTERN u8 ACPI_INIT_GLOBAL(acpi_gbl_use_default_register_widths, TRUE); | |||
114 | * | 127 | * |
115 | ****************************************************************************/ | 128 | ****************************************************************************/ |
116 | 129 | ||
117 | /* Runtime configuration of debug print levels */ | ||
118 | |||
119 | extern u32 acpi_dbg_level; | ||
120 | extern u32 acpi_dbg_layer; | ||
121 | |||
122 | /* Procedure nesting level for debug output */ | 130 | /* Procedure nesting level for debug output */ |
123 | 131 | ||
124 | extern u32 acpi_gbl_nesting_level; | 132 | extern u32 acpi_gbl_nesting_level; |
@@ -127,10 +135,8 @@ extern u32 acpi_gbl_nesting_level; | |||
127 | 135 | ||
128 | ACPI_EXTERN u32 acpi_gbl_original_dbg_level; | 136 | ACPI_EXTERN u32 acpi_gbl_original_dbg_level; |
129 | ACPI_EXTERN u32 acpi_gbl_original_dbg_layer; | 137 | ACPI_EXTERN u32 acpi_gbl_original_dbg_layer; |
130 | ACPI_EXTERN acpi_name acpi_gbl_trace_method_name; | ||
131 | ACPI_EXTERN u32 acpi_gbl_trace_dbg_level; | 138 | ACPI_EXTERN u32 acpi_gbl_trace_dbg_level; |
132 | ACPI_EXTERN u32 acpi_gbl_trace_dbg_layer; | 139 | ACPI_EXTERN u32 acpi_gbl_trace_dbg_layer; |
133 | ACPI_EXTERN u32 acpi_gbl_trace_flags; | ||
134 | 140 | ||
135 | /***************************************************************************** | 141 | /***************************************************************************** |
136 | * | 142 | * |
@@ -142,10 +148,8 @@ ACPI_EXTERN u32 acpi_gbl_trace_flags; | |||
142 | * acpi_gbl_root_table_list is the master list of ACPI tables found in the | 148 | * acpi_gbl_root_table_list is the master list of ACPI tables found in the |
143 | * RSDT/XSDT. | 149 | * RSDT/XSDT. |
144 | * | 150 | * |
145 | * acpi_gbl_FADT is a local copy of the FADT, converted to a common format. | ||
146 | */ | 151 | */ |
147 | ACPI_EXTERN struct acpi_internal_rsdt acpi_gbl_root_table_list; | 152 | ACPI_EXTERN struct acpi_internal_rsdt acpi_gbl_root_table_list; |
148 | ACPI_EXTERN struct acpi_table_fadt acpi_gbl_FADT; | ||
149 | ACPI_EXTERN struct acpi_table_facs *acpi_gbl_FACS; | 153 | ACPI_EXTERN struct acpi_table_facs *acpi_gbl_FACS; |
150 | 154 | ||
151 | /* These addresses are calculated from the FADT Event Block addresses */ | 155 | /* These addresses are calculated from the FADT Event Block addresses */ |
@@ -261,7 +265,8 @@ ACPI_EXTERN u8 acpi_gbl_osi_data; | |||
261 | extern u8 acpi_gbl_shutdown; | 265 | extern u8 acpi_gbl_shutdown; |
262 | extern u32 acpi_gbl_startup_flags; | 266 | extern u32 acpi_gbl_startup_flags; |
263 | extern const char *acpi_gbl_sleep_state_names[ACPI_S_STATE_COUNT]; | 267 | extern const char *acpi_gbl_sleep_state_names[ACPI_S_STATE_COUNT]; |
264 | extern const char *acpi_gbl_highest_dstate_names[4]; | 268 | extern const char *acpi_gbl_lowest_dstate_names[ACPI_NUM_sx_w_METHODS]; |
269 | extern const char *acpi_gbl_highest_dstate_names[ACPI_NUM_sx_d_METHODS]; | ||
265 | extern const struct acpi_opcode_info acpi_gbl_aml_op_info[AML_NUM_OPCODES]; | 270 | extern const struct acpi_opcode_info acpi_gbl_aml_op_info[AML_NUM_OPCODES]; |
266 | extern const char *acpi_gbl_region_types[ACPI_NUM_PREDEFINED_REGIONS]; | 271 | extern const char *acpi_gbl_region_types[ACPI_NUM_PREDEFINED_REGIONS]; |
267 | 272 | ||
@@ -290,6 +295,7 @@ extern char const *acpi_gbl_exception_names_ctrl[]; | |||
290 | ACPI_EXTERN struct acpi_namespace_node acpi_gbl_root_node_struct; | 295 | ACPI_EXTERN struct acpi_namespace_node acpi_gbl_root_node_struct; |
291 | ACPI_EXTERN struct acpi_namespace_node *acpi_gbl_root_node; | 296 | ACPI_EXTERN struct acpi_namespace_node *acpi_gbl_root_node; |
292 | ACPI_EXTERN struct acpi_namespace_node *acpi_gbl_fadt_gpe_device; | 297 | ACPI_EXTERN struct acpi_namespace_node *acpi_gbl_fadt_gpe_device; |
298 | ACPI_EXTERN union acpi_operand_object *acpi_gbl_module_code_list; | ||
293 | 299 | ||
294 | extern const u8 acpi_gbl_ns_properties[ACPI_NUM_NS_TYPES]; | 300 | extern const u8 acpi_gbl_ns_properties[ACPI_NUM_NS_TYPES]; |
295 | extern const struct acpi_predefined_names | 301 | extern const struct acpi_predefined_names |
@@ -340,7 +346,6 @@ ACPI_EXTERN struct acpi_fixed_event_handler | |||
340 | ACPI_EXTERN struct acpi_gpe_xrupt_info *acpi_gbl_gpe_xrupt_list_head; | 346 | ACPI_EXTERN struct acpi_gpe_xrupt_info *acpi_gbl_gpe_xrupt_list_head; |
341 | ACPI_EXTERN struct acpi_gpe_block_info | 347 | ACPI_EXTERN struct acpi_gpe_block_info |
342 | *acpi_gbl_gpe_fadt_blocks[ACPI_MAX_GPE_BLOCKS]; | 348 | *acpi_gbl_gpe_fadt_blocks[ACPI_MAX_GPE_BLOCKS]; |
343 | ACPI_EXTERN u32 acpi_current_gpe_count; | ||
344 | 349 | ||
345 | /***************************************************************************** | 350 | /***************************************************************************** |
346 | * | 351 | * |
@@ -362,9 +367,6 @@ extern u8 acpi_gbl_method_executing; | |||
362 | extern u8 acpi_gbl_abort_method; | 367 | extern u8 acpi_gbl_abort_method; |
363 | extern u8 acpi_gbl_db_terminate_threads; | 368 | extern u8 acpi_gbl_db_terminate_threads; |
364 | 369 | ||
365 | ACPI_EXTERN int optind; | ||
366 | ACPI_EXTERN char *optarg; | ||
367 | |||
368 | ACPI_EXTERN u8 acpi_gbl_db_opt_tables; | 370 | ACPI_EXTERN u8 acpi_gbl_db_opt_tables; |
369 | ACPI_EXTERN u8 acpi_gbl_db_opt_stats; | 371 | ACPI_EXTERN u8 acpi_gbl_db_opt_stats; |
370 | ACPI_EXTERN u8 acpi_gbl_db_opt_ini_methods; | 372 | ACPI_EXTERN u8 acpi_gbl_db_opt_ini_methods; |
diff --git a/drivers/acpi/acpica/achware.h b/drivers/acpi/acpica/achware.h index 4afa3d8e0efb..36192f142fbb 100644 --- a/drivers/acpi/acpica/achware.h +++ b/drivers/acpi/acpica/achware.h | |||
@@ -62,6 +62,14 @@ u32 acpi_hw_get_mode(void); | |||
62 | /* | 62 | /* |
63 | * hwregs - ACPI Register I/O | 63 | * hwregs - ACPI Register I/O |
64 | */ | 64 | */ |
65 | acpi_status | ||
66 | acpi_hw_validate_register(struct acpi_generic_address *reg, | ||
67 | u8 max_bit_width, u64 *address); | ||
68 | |||
69 | acpi_status acpi_hw_read(u32 *value, struct acpi_generic_address *reg); | ||
70 | |||
71 | acpi_status acpi_hw_write(u32 value, struct acpi_generic_address *reg); | ||
72 | |||
65 | struct acpi_bit_register_info *acpi_hw_get_bit_register_info(u32 register_id); | 73 | struct acpi_bit_register_info *acpi_hw_get_bit_register_info(u32 register_id); |
66 | 74 | ||
67 | acpi_status acpi_hw_write_pm1_control(u32 pm1a_control, u32 pm1b_control); | 75 | acpi_status acpi_hw_write_pm1_control(u32 pm1a_control, u32 pm1b_control); |
diff --git a/drivers/acpi/acpica/acinterp.h b/drivers/acpi/acpica/acinterp.h index e8db7a3143a5..5db9f2916f7c 100644 --- a/drivers/acpi/acpica/acinterp.h +++ b/drivers/acpi/acpica/acinterp.h | |||
@@ -461,9 +461,9 @@ void acpi_ex_acquire_global_lock(u32 rule); | |||
461 | 461 | ||
462 | void acpi_ex_release_global_lock(u32 rule); | 462 | void acpi_ex_release_global_lock(u32 rule); |
463 | 463 | ||
464 | void acpi_ex_eisa_id_to_string(u32 numeric_id, char *out_string); | 464 | void acpi_ex_eisa_id_to_string(char *dest, acpi_integer compressed_id); |
465 | 465 | ||
466 | void acpi_ex_unsigned_integer_to_string(acpi_integer value, char *out_string); | 466 | void acpi_ex_integer_to_string(char *dest, acpi_integer value); |
467 | 467 | ||
468 | /* | 468 | /* |
469 | * exregion - default op_region handlers | 469 | * exregion - default op_region handlers |
diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index 2ec394a328e9..81e64f478679 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h | |||
@@ -205,6 +205,7 @@ struct acpi_namespace_node { | |||
205 | #define ANOBJ_METHOD_LOCAL 0x08 /* Node is a method local */ | 205 | #define ANOBJ_METHOD_LOCAL 0x08 /* Node is a method local */ |
206 | #define ANOBJ_SUBTREE_HAS_INI 0x10 /* Used to optimize device initialization */ | 206 | #define ANOBJ_SUBTREE_HAS_INI 0x10 /* Used to optimize device initialization */ |
207 | #define ANOBJ_EVALUATED 0x20 /* Set on first evaluation of node */ | 207 | #define ANOBJ_EVALUATED 0x20 /* Set on first evaluation of node */ |
208 | #define ANOBJ_ALLOCATED_BUFFER 0x40 /* Method AML buffer is dynamic (install_method) */ | ||
208 | 209 | ||
209 | #define ANOBJ_IS_EXTERNAL 0x08 /* i_aSL only: This object created via External() */ | 210 | #define ANOBJ_IS_EXTERNAL 0x08 /* i_aSL only: This object created via External() */ |
210 | #define ANOBJ_METHOD_NO_RETVAL 0x10 /* i_aSL only: Method has no return value */ | 211 | #define ANOBJ_METHOD_NO_RETVAL 0x10 /* i_aSL only: Method has no return value */ |
@@ -368,6 +369,19 @@ union acpi_predefined_info { | |||
368 | struct acpi_package_info3 ret_info3; | 369 | struct acpi_package_info3 ret_info3; |
369 | }; | 370 | }; |
370 | 371 | ||
372 | /* Data block used during object validation */ | ||
373 | |||
374 | struct acpi_predefined_data { | ||
375 | char *pathname; | ||
376 | const union acpi_predefined_info *predefined; | ||
377 | u32 flags; | ||
378 | u8 node_flags; | ||
379 | }; | ||
380 | |||
381 | /* Defines for Flags field above */ | ||
382 | |||
383 | #define ACPI_OBJECT_REPAIRED 1 | ||
384 | |||
371 | /* | 385 | /* |
372 | * Bitmapped return value types | 386 | * Bitmapped return value types |
373 | * Note: the actual data types must be contiguous, a loop in nspredef.c | 387 | * Note: the actual data types must be contiguous, a loop in nspredef.c |
@@ -788,11 +802,14 @@ struct acpi_bit_register_info { | |||
788 | /* For control registers, both ignored and reserved bits must be preserved */ | 802 | /* For control registers, both ignored and reserved bits must be preserved */ |
789 | 803 | ||
790 | /* | 804 | /* |
791 | * The ACPI spec says to ignore PM1_CTL.SCI_EN (bit 0) | 805 | * For PM1 control, the SCI enable bit (bit 0, SCI_EN) is defined by the |
792 | * but we need to be able to write ACPI_BITREG_SCI_ENABLE directly | 806 | * ACPI specification to be a "preserved" bit - "OSPM always preserves this |
793 | * as a BIOS workaround on some machines. | 807 | * bit position", section 4.7.3.2.1. However, on some machines the OS must |
808 | * write a one to this bit after resume for the machine to work properly. | ||
809 | * To enable this, we no longer attempt to preserve this bit. No machines | ||
810 | * are known to fail if the bit is not preserved. (May 2009) | ||
794 | */ | 811 | */ |
795 | #define ACPI_PM1_CONTROL_IGNORED_BITS 0x0200 /* Bits 9 */ | 812 | #define ACPI_PM1_CONTROL_IGNORED_BITS 0x0200 /* Bit 9 */ |
796 | #define ACPI_PM1_CONTROL_RESERVED_BITS 0xC1F8 /* Bits 14-15, 3-8 */ | 813 | #define ACPI_PM1_CONTROL_RESERVED_BITS 0xC1F8 /* Bits 14-15, 3-8 */ |
797 | #define ACPI_PM1_CONTROL_PRESERVED_BITS \ | 814 | #define ACPI_PM1_CONTROL_PRESERVED_BITS \ |
798 | (ACPI_PM1_CONTROL_IGNORED_BITS | ACPI_PM1_CONTROL_RESERVED_BITS) | 815 | (ACPI_PM1_CONTROL_IGNORED_BITS | ACPI_PM1_CONTROL_RESERVED_BITS) |
@@ -881,6 +898,9 @@ struct acpi_bit_register_info { | |||
881 | #define ACPI_OSI_WIN_XP_SP2 0x05 | 898 | #define ACPI_OSI_WIN_XP_SP2 0x05 |
882 | #define ACPI_OSI_WINSRV_2003_SP1 0x06 | 899 | #define ACPI_OSI_WINSRV_2003_SP1 0x06 |
883 | #define ACPI_OSI_WIN_VISTA 0x07 | 900 | #define ACPI_OSI_WIN_VISTA 0x07 |
901 | #define ACPI_OSI_WINSRV_2008 0x08 | ||
902 | #define ACPI_OSI_WIN_VISTA_SP1 0x09 | ||
903 | #define ACPI_OSI_WIN_7 0x0A | ||
884 | 904 | ||
885 | #define ACPI_ALWAYS_ILLEGAL 0x00 | 905 | #define ACPI_ALWAYS_ILLEGAL 0x00 |
886 | 906 | ||
diff --git a/drivers/acpi/acpica/acmacros.h b/drivers/acpi/acpica/acmacros.h index 91ac7d7b4402..3acd9c6760ea 100644 --- a/drivers/acpi/acpica/acmacros.h +++ b/drivers/acpi/acpica/acmacros.h | |||
@@ -340,6 +340,7 @@ | |||
340 | */ | 340 | */ |
341 | #define ACPI_ERROR_NAMESPACE(s, e) acpi_ns_report_error (AE_INFO, s, e); | 341 | #define ACPI_ERROR_NAMESPACE(s, e) acpi_ns_report_error (AE_INFO, s, e); |
342 | #define ACPI_ERROR_METHOD(s, n, p, e) acpi_ns_report_method_error (AE_INFO, s, n, p, e); | 342 | #define ACPI_ERROR_METHOD(s, n, p, e) acpi_ns_report_method_error (AE_INFO, s, n, p, e); |
343 | #define ACPI_WARN_PREDEFINED(plist) acpi_ut_predefined_warning plist | ||
343 | 344 | ||
344 | #else | 345 | #else |
345 | 346 | ||
@@ -347,6 +348,7 @@ | |||
347 | 348 | ||
348 | #define ACPI_ERROR_NAMESPACE(s, e) | 349 | #define ACPI_ERROR_NAMESPACE(s, e) |
349 | #define ACPI_ERROR_METHOD(s, n, p, e) | 350 | #define ACPI_ERROR_METHOD(s, n, p, e) |
351 | #define ACPI_WARN_PREDEFINED(plist) | ||
350 | #endif /* ACPI_NO_ERROR_MESSAGES */ | 352 | #endif /* ACPI_NO_ERROR_MESSAGES */ |
351 | 353 | ||
352 | /* | 354 | /* |
diff --git a/drivers/acpi/acpica/acnamesp.h b/drivers/acpi/acpica/acnamesp.h index 46cb5b46d280..09a2764c734b 100644 --- a/drivers/acpi/acpica/acnamesp.h +++ b/drivers/acpi/acpica/acnamesp.h | |||
@@ -73,6 +73,14 @@ | |||
73 | #define ACPI_NS_WALK_UNLOCK 0x01 | 73 | #define ACPI_NS_WALK_UNLOCK 0x01 |
74 | #define ACPI_NS_WALK_TEMP_NODES 0x02 | 74 | #define ACPI_NS_WALK_TEMP_NODES 0x02 |
75 | 75 | ||
76 | /* Object is not a package element */ | ||
77 | |||
78 | #define ACPI_NOT_PACKAGE_ELEMENT ACPI_UINT32_MAX | ||
79 | |||
80 | /* Always emit warning message, not dependent on node flags */ | ||
81 | |||
82 | #define ACPI_WARN_ALWAYS 0 | ||
83 | |||
76 | /* | 84 | /* |
77 | * nsinit - Namespace initialization | 85 | * nsinit - Namespace initialization |
78 | */ | 86 | */ |
@@ -99,10 +107,19 @@ acpi_ns_walk_namespace(acpi_object_type type, | |||
99 | acpi_walk_callback user_function, | 107 | acpi_walk_callback user_function, |
100 | void *context, void **return_value); | 108 | void *context, void **return_value); |
101 | 109 | ||
102 | struct acpi_namespace_node *acpi_ns_get_next_node(acpi_object_type type, struct acpi_namespace_node | 110 | struct acpi_namespace_node *acpi_ns_get_next_node(struct acpi_namespace_node |
103 | *parent, struct acpi_namespace_node | 111 | *parent, |
112 | struct acpi_namespace_node | ||
104 | *child); | 113 | *child); |
105 | 114 | ||
115 | struct acpi_namespace_node *acpi_ns_get_next_node_typed(acpi_object_type type, | ||
116 | struct | ||
117 | acpi_namespace_node | ||
118 | *parent, | ||
119 | struct | ||
120 | acpi_namespace_node | ||
121 | *child); | ||
122 | |||
106 | /* | 123 | /* |
107 | * nsparse - table parsing | 124 | * nsparse - table parsing |
108 | */ | 125 | */ |
@@ -135,6 +152,8 @@ struct acpi_namespace_node *acpi_ns_create_node(u32 name); | |||
135 | 152 | ||
136 | void acpi_ns_delete_node(struct acpi_namespace_node *node); | 153 | void acpi_ns_delete_node(struct acpi_namespace_node *node); |
137 | 154 | ||
155 | void acpi_ns_remove_node(struct acpi_namespace_node *node); | ||
156 | |||
138 | void | 157 | void |
139 | acpi_ns_delete_namespace_subtree(struct acpi_namespace_node *parent_handle); | 158 | acpi_ns_delete_namespace_subtree(struct acpi_namespace_node *parent_handle); |
140 | 159 | ||
@@ -177,6 +196,8 @@ acpi_ns_dump_objects(acpi_object_type type, | |||
177 | */ | 196 | */ |
178 | acpi_status acpi_ns_evaluate(struct acpi_evaluate_info *info); | 197 | acpi_status acpi_ns_evaluate(struct acpi_evaluate_info *info); |
179 | 198 | ||
199 | void acpi_ns_exec_module_code_list(void); | ||
200 | |||
180 | /* | 201 | /* |
181 | * nspredef - Support for predefined/reserved names | 202 | * nspredef - Support for predefined/reserved names |
182 | */ | 203 | */ |
@@ -251,6 +272,19 @@ acpi_ns_get_attached_data(struct acpi_namespace_node *node, | |||
251 | acpi_object_handler handler, void **data); | 272 | acpi_object_handler handler, void **data); |
252 | 273 | ||
253 | /* | 274 | /* |
275 | * nsrepair - return object repair for predefined methods/objects | ||
276 | */ | ||
277 | acpi_status | ||
278 | acpi_ns_repair_object(struct acpi_predefined_data *data, | ||
279 | u32 expected_btypes, | ||
280 | u32 package_index, | ||
281 | union acpi_operand_object **return_object_ptr); | ||
282 | |||
283 | acpi_status | ||
284 | acpi_ns_repair_package_list(struct acpi_predefined_data *data, | ||
285 | union acpi_operand_object **obj_desc_ptr); | ||
286 | |||
287 | /* | ||
254 | * nssearch - Namespace searching and entry | 288 | * nssearch - Namespace searching and entry |
255 | */ | 289 | */ |
256 | acpi_status | 290 | acpi_status |
diff --git a/drivers/acpi/acpica/acobject.h b/drivers/acpi/acpica/acobject.h index 544dcf834922..b39d682a2140 100644 --- a/drivers/acpi/acpica/acobject.h +++ b/drivers/acpi/acpica/acobject.h | |||
@@ -97,6 +97,8 @@ | |||
97 | #define AOPOBJ_OBJECT_INITIALIZED 0x08 | 97 | #define AOPOBJ_OBJECT_INITIALIZED 0x08 |
98 | #define AOPOBJ_SETUP_COMPLETE 0x10 | 98 | #define AOPOBJ_SETUP_COMPLETE 0x10 |
99 | #define AOPOBJ_SINGLE_DATUM 0x20 | 99 | #define AOPOBJ_SINGLE_DATUM 0x20 |
100 | #define AOPOBJ_INVALID 0x40 /* Used if host OS won't allow an op_region address */ | ||
101 | #define AOPOBJ_MODULE_LEVEL 0x80 | ||
100 | 102 | ||
101 | /****************************************************************************** | 103 | /****************************************************************************** |
102 | * | 104 | * |
diff --git a/drivers/acpi/acpica/acparser.h b/drivers/acpi/acpica/acparser.h index 23ee0fbf5619..22881e8ce229 100644 --- a/drivers/acpi/acpica/acparser.h +++ b/drivers/acpi/acpica/acparser.h | |||
@@ -62,6 +62,8 @@ | |||
62 | #define ACPI_PARSE_DEFERRED_OP 0x0100 | 62 | #define ACPI_PARSE_DEFERRED_OP 0x0100 |
63 | #define ACPI_PARSE_DISASSEMBLE 0x0200 | 63 | #define ACPI_PARSE_DISASSEMBLE 0x0200 |
64 | 64 | ||
65 | #define ACPI_PARSE_MODULE_LEVEL 0x0400 | ||
66 | |||
65 | /****************************************************************************** | 67 | /****************************************************************************** |
66 | * | 68 | * |
67 | * Parser interfaces | 69 | * Parser interfaces |
diff --git a/drivers/acpi/acpica/acpredef.h b/drivers/acpi/acpica/acpredef.h index 63f656ae3604..cd80d1dd1950 100644 --- a/drivers/acpi/acpica/acpredef.h +++ b/drivers/acpi/acpica/acpredef.h | |||
@@ -64,8 +64,8 @@ | |||
64 | * (Used for _PRW) | 64 | * (Used for _PRW) |
65 | * | 65 | * |
66 | * | 66 | * |
67 | * 2) PTYPE2 packages contain a variable number of sub-packages. Each of the | 67 | * 2) PTYPE2 packages contain a Variable-length number of sub-packages. Each |
68 | * different types describe the contents of each of the sub-packages. | 68 | * of the different types describe the contents of each of the sub-packages. |
69 | * | 69 | * |
70 | * ACPI_PTYPE2: Each subpackage contains 1 or 2 object types: | 70 | * ACPI_PTYPE2: Each subpackage contains 1 or 2 object types: |
71 | * object type | 71 | * object type |
@@ -91,6 +91,9 @@ | |||
91 | * ACPI_PTYPE2_MIN: Each subpackage has a variable but minimum length | 91 | * ACPI_PTYPE2_MIN: Each subpackage has a variable but minimum length |
92 | * (Used for _HPX) | 92 | * (Used for _HPX) |
93 | * | 93 | * |
94 | * ACPI_PTYPE2_REV_FIXED: Revision at start, each subpackage is Fixed-length | ||
95 | * (Used for _ART, _FPS) | ||
96 | * | ||
94 | *****************************************************************************/ | 97 | *****************************************************************************/ |
95 | 98 | ||
96 | enum acpi_return_package_types { | 99 | enum acpi_return_package_types { |
@@ -101,9 +104,11 @@ enum acpi_return_package_types { | |||
101 | ACPI_PTYPE2_COUNT = 5, | 104 | ACPI_PTYPE2_COUNT = 5, |
102 | ACPI_PTYPE2_PKG_COUNT = 6, | 105 | ACPI_PTYPE2_PKG_COUNT = 6, |
103 | ACPI_PTYPE2_FIXED = 7, | 106 | ACPI_PTYPE2_FIXED = 7, |
104 | ACPI_PTYPE2_MIN = 8 | 107 | ACPI_PTYPE2_MIN = 8, |
108 | ACPI_PTYPE2_REV_FIXED = 9 | ||
105 | }; | 109 | }; |
106 | 110 | ||
111 | #ifdef ACPI_CREATE_PREDEFINED_TABLE | ||
107 | /* | 112 | /* |
108 | * Predefined method/object information table. | 113 | * Predefined method/object information table. |
109 | * | 114 | * |
@@ -136,239 +141,384 @@ enum acpi_return_package_types { | |||
136 | * is saved here (rather than in a separate table) in order to minimize the | 141 | * is saved here (rather than in a separate table) in order to minimize the |
137 | * overall size of the stored data. | 142 | * overall size of the stored data. |
138 | */ | 143 | */ |
139 | static const union acpi_predefined_info predefined_names[] = { | 144 | static const union acpi_predefined_info predefined_names[] = |
140 | {.info = {"_AC0", 0, ACPI_RTYPE_INTEGER}}, | 145 | { |
141 | {.info = {"_AC1", 0, ACPI_RTYPE_INTEGER}}, | 146 | {{"_AC0", 0, ACPI_RTYPE_INTEGER}}, |
142 | {.info = {"_AC2", 0, ACPI_RTYPE_INTEGER}}, | 147 | {{"_AC1", 0, ACPI_RTYPE_INTEGER}}, |
143 | {.info = {"_AC3", 0, ACPI_RTYPE_INTEGER}}, | 148 | {{"_AC2", 0, ACPI_RTYPE_INTEGER}}, |
144 | {.info = {"_AC4", 0, ACPI_RTYPE_INTEGER}}, | 149 | {{"_AC3", 0, ACPI_RTYPE_INTEGER}}, |
145 | {.info = {"_AC5", 0, ACPI_RTYPE_INTEGER}}, | 150 | {{"_AC4", 0, ACPI_RTYPE_INTEGER}}, |
146 | {.info = {"_AC6", 0, ACPI_RTYPE_INTEGER}}, | 151 | {{"_AC5", 0, ACPI_RTYPE_INTEGER}}, |
147 | {.info = {"_AC7", 0, ACPI_RTYPE_INTEGER}}, | 152 | {{"_AC6", 0, ACPI_RTYPE_INTEGER}}, |
148 | {.info = {"_AC8", 0, ACPI_RTYPE_INTEGER}}, | 153 | {{"_AC7", 0, ACPI_RTYPE_INTEGER}}, |
149 | {.info = {"_AC9", 0, ACPI_RTYPE_INTEGER}}, | 154 | {{"_AC8", 0, ACPI_RTYPE_INTEGER}}, |
150 | {.info = {"_ADR", 0, ACPI_RTYPE_INTEGER}}, | 155 | {{"_AC9", 0, ACPI_RTYPE_INTEGER}}, |
151 | {.info = {"_AL0", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0, 0, 0}}, /* variable (Refs) */ | 156 | {{"_ADR", 0, ACPI_RTYPE_INTEGER}}, |
152 | {.info = {"_AL1", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0, 0, 0}}, /* variable (Refs) */ | 157 | {{"_AL0", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs) */ |
153 | {.info = {"_AL2", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0, 0, 0}}, /* variable (Refs) */ | 158 | {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0}, 0,0}}, |
154 | {.info = {"_AL3", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0, 0, 0}}, /* variable (Refs) */ | 159 | |
155 | {.info = {"_AL4", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0, 0, 0}}, /* variable (Refs) */ | 160 | {{"_AL1", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs) */ |
156 | {.info = {"_AL5", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0, 0, 0}}, /* variable (Refs) */ | 161 | {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0}, 0,0}}, |
157 | {.info = {"_AL6", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0, 0, 0}}, /* variable (Refs) */ | 162 | |
158 | {.info = {"_AL7", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0, 0, 0}}, /* variable (Refs) */ | 163 | {{"_AL2", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs) */ |
159 | {.info = {"_AL8", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0, 0, 0}}, /* variable (Refs) */ | 164 | {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0}, 0,0}}, |
160 | {.info = {"_AL9", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0, 0, 0}}, /* variable (Refs) */ | 165 | |
161 | {.info = {"_ALC", 0, ACPI_RTYPE_INTEGER}}, | 166 | {{"_AL3", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs) */ |
162 | {.info = {"_ALI", 0, ACPI_RTYPE_INTEGER}}, | 167 | {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0}, 0,0}}, |
163 | {.info = {"_ALP", 0, ACPI_RTYPE_INTEGER}}, | 168 | |
164 | {.info = {"_ALR", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE2, ACPI_RTYPE_INTEGER, 2, 0, 0, 0}}, /* variable (Pkgs) each 2 (Ints) */ | 169 | {{"_AL4", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs) */ |
165 | {.info = {"_ALT", 0, ACPI_RTYPE_INTEGER}}, | 170 | {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0}, 0,0}}, |
166 | {.info = {"_BBN", 0, ACPI_RTYPE_INTEGER}}, | 171 | |
167 | {.info = {"_BCL", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 0, 0, 0, 0}}, /* variable (Ints) */ | 172 | {{"_AL5", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs) */ |
168 | {.info = {"_BCM", 1, 0}}, | 173 | {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0}, 0,0}}, |
169 | {.info = {"_BDN", 0, ACPI_RTYPE_INTEGER}}, | 174 | |
170 | {.info = {"_BFS", 1, 0}}, | 175 | {{"_AL6", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs) */ |
171 | {.info = {"_BIF", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, | 176 | {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0}, 0,0}}, |
172 | 9, | 177 | |
173 | ACPI_RTYPE_STRING | ACPI_RTYPE_BUFFER, 4, 0}}, /* fixed (9 Int),(4 Str) */ | 178 | {{"_AL7", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs) */ |
174 | {.info = {"_BLT", 3, 0}}, | 179 | {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0}, 0,0}}, |
175 | {.info = {"_BMC", 1, 0}}, | 180 | |
176 | {.info = {"_BMD", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 5, 0, 0, 0}}, /* fixed (5 Int) */ | 181 | {{"_AL8", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs) */ |
177 | {.info = {"_BQC", 0, ACPI_RTYPE_INTEGER}}, | 182 | {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0}, 0,0}}, |
178 | {.info = {"_BST", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 4, 0, 0, 0}}, /* fixed (4 Int) */ | 183 | |
179 | {.info = {"_BTM", 1, ACPI_RTYPE_INTEGER}}, | 184 | {{"_AL9", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs) */ |
180 | {.info = {"_BTP", 1, 0}}, | 185 | {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0}, 0,0}}, |
181 | {.info = {"_CBA", 0, ACPI_RTYPE_INTEGER}}, /* see PCI firmware spec 3.0 */ | 186 | |
182 | {.info = {"_CID", 0, | 187 | {{"_ALC", 0, ACPI_RTYPE_INTEGER}}, |
183 | ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING | ACPI_RTYPE_PACKAGE}}, | 188 | {{"_ALI", 0, ACPI_RTYPE_INTEGER}}, |
184 | {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING, 0, 0, 0, 0}}, /* variable (Ints/Strs) */ | 189 | {{"_ALP", 0, ACPI_RTYPE_INTEGER}}, |
185 | {.info = {"_CRS", 0, ACPI_RTYPE_BUFFER}}, | 190 | {{"_ALR", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Pkgs) each 2 (Ints) */ |
186 | {.info = {"_CRT", 0, ACPI_RTYPE_INTEGER}}, | 191 | {{{ACPI_PTYPE2, ACPI_RTYPE_INTEGER, 2,0}, 0,0}}, |
187 | {.info = {"_CSD", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE2_COUNT, ACPI_RTYPE_INTEGER, 0, 0, 0, 0}}, /* variable (1 Int(n), n-1 Int) */ | 192 | |
188 | {.info = {"_CST", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE2_PKG_COUNT, | 193 | {{"_ALT", 0, ACPI_RTYPE_INTEGER}}, |
189 | ACPI_RTYPE_BUFFER, 1, | 194 | {{"_ART", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (1 Int(rev), n Pkg (2 Ref/11 Int) */ |
190 | ACPI_RTYPE_INTEGER, 3, 0}}, /* variable (1 Int(n), n Pkg (1 Buf/3 Int) */ | 195 | {{{ACPI_PTYPE2_REV_FIXED, ACPI_RTYPE_REFERENCE, 2, ACPI_RTYPE_INTEGER}, |
191 | {.info = {"_DCK", 1, ACPI_RTYPE_INTEGER}}, | 196 | 11, 0}}, |
192 | {.info = {"_DCS", 0, ACPI_RTYPE_INTEGER}}, | 197 | |
193 | {.info = {"_DDC", 1, ACPI_RTYPE_INTEGER | ACPI_RTYPE_BUFFER}}, | 198 | {{"_BBN", 0, ACPI_RTYPE_INTEGER}}, |
194 | {.info = {"_DDN", 0, ACPI_RTYPE_STRING}}, | 199 | {{"_BCL", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Ints) */ |
195 | {.info = {"_DGS", 0, ACPI_RTYPE_INTEGER}}, | 200 | {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 0,0}, 0,0}}, |
196 | {.info = {"_DIS", 0, 0}}, | 201 | |
197 | {.info = {"_DMA", 0, ACPI_RTYPE_BUFFER}}, | 202 | {{"_BCM", 1, 0}}, |
198 | {.info = {"_DOD", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 0, 0, 0, 0}}, /* variable (Ints) */ | 203 | {{"_BCT", 1, ACPI_RTYPE_INTEGER}}, |
199 | {.info = {"_DOS", 1, 0}}, | 204 | {{"_BDN", 0, ACPI_RTYPE_INTEGER}}, |
200 | {.info = {"_DSM", 4, ACPI_RTYPE_ALL}}, /* Must return a type, but it can be of any type */ | 205 | {{"_BFS", 1, 0}}, |
201 | {.info = {"_DSS", 1, 0}}, | 206 | {{"_BIF", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (9 Int),(4 Str) */ |
202 | {.info = {"_DSW", 3, 0}}, | 207 | {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 9, ACPI_RTYPE_STRING}, 4,0}}, |
203 | {.info = {"_EC_", 0, ACPI_RTYPE_INTEGER}}, | 208 | |
204 | {.info = {"_EDL", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0, 0, 0}}, /* variable (Refs) */ | 209 | {{"_BIX", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (16 Int),(4 Str) */ |
205 | {.info = {"_EJ0", 1, 0}}, | 210 | {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 16, ACPI_RTYPE_STRING}, 4, |
206 | {.info = {"_EJ1", 1, 0}}, | 211 | 0}}, |
207 | {.info = {"_EJ2", 1, 0}}, | 212 | |
208 | {.info = {"_EJ3", 1, 0}}, | 213 | {{"_BLT", 3, 0}}, |
209 | {.info = {"_EJ4", 1, 0}}, | 214 | {{"_BMA", 1, ACPI_RTYPE_INTEGER}}, |
210 | {.info = {"_EJD", 0, ACPI_RTYPE_STRING}}, | 215 | {{"_BMC", 1, 0}}, |
211 | {.info = {"_FDE", 0, ACPI_RTYPE_BUFFER}}, | 216 | {{"_BMD", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (5 Int) */ |
212 | {.info = {"_FDI", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 16, 0, 0, 0}}, /* fixed (16 Int) */ | 217 | {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 5,0}, 0,0}}, |
213 | {.info = {"_FDM", 1, 0}}, | 218 | |
214 | {.info = {"_FIX", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 0, 0, 0, 0}}, /* variable (Ints) */ | 219 | {{"_BMS", 1, ACPI_RTYPE_INTEGER}}, |
215 | {.info = {"_GLK", 0, ACPI_RTYPE_INTEGER}}, | 220 | {{"_BQC", 0, ACPI_RTYPE_INTEGER}}, |
216 | {.info = {"_GPD", 0, ACPI_RTYPE_INTEGER}}, | 221 | {{"_BST", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (4 Int) */ |
217 | {.info = {"_GPE", 0, ACPI_RTYPE_INTEGER}}, /* _GPE method, not _GPE scope */ | 222 | {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 4,0}, 0,0}}, |
218 | {.info = {"_GSB", 0, ACPI_RTYPE_INTEGER}}, | 223 | |
219 | {.info = {"_GTF", 0, ACPI_RTYPE_BUFFER}}, | 224 | {{"_BTM", 1, ACPI_RTYPE_INTEGER}}, |
220 | {.info = {"_GTM", 0, ACPI_RTYPE_BUFFER}}, | 225 | {{"_BTP", 1, 0}}, |
221 | {.info = {"_GTS", 1, 0}}, | 226 | {{"_CBA", 0, ACPI_RTYPE_INTEGER}}, /* See PCI firmware spec 3.0 */ |
222 | {.info = {"_HID", 0, ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING}}, | 227 | {{"_CDM", 0, ACPI_RTYPE_INTEGER}}, |
223 | {.info = {"_HOT", 0, ACPI_RTYPE_INTEGER}}, | 228 | {{"_CID", 0, ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING | ACPI_RTYPE_PACKAGE}}, /* Variable-length (Ints/Strs) */ |
224 | {.info = {"_HPP", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 4, 0, 0, 0}}, /* fixed (4 Int) */ | 229 | {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING, 0,0}, 0,0}}, |
230 | |||
231 | {{"_CRS", 0, ACPI_RTYPE_BUFFER}}, | ||
232 | {{"_CRT", 0, ACPI_RTYPE_INTEGER}}, | ||
233 | {{"_CSD", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (1 Int(n), n-1 Int) */ | ||
234 | {{{ACPI_PTYPE2_COUNT, ACPI_RTYPE_INTEGER, 0,0}, 0,0}}, | ||
235 | |||
236 | {{"_CST", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (1 Int(n), n Pkg (1 Buf/3 Int) */ | ||
237 | {{{ACPI_PTYPE2_PKG_COUNT,ACPI_RTYPE_BUFFER, 1, ACPI_RTYPE_INTEGER}, 3,0}}, | ||
238 | |||
239 | {{"_DCK", 1, ACPI_RTYPE_INTEGER}}, | ||
240 | {{"_DCS", 0, ACPI_RTYPE_INTEGER}}, | ||
241 | {{"_DDC", 1, ACPI_RTYPE_INTEGER | ACPI_RTYPE_BUFFER}}, | ||
242 | {{"_DDN", 0, ACPI_RTYPE_STRING}}, | ||
243 | {{"_DGS", 0, ACPI_RTYPE_INTEGER}}, | ||
244 | {{"_DIS", 0, 0}}, | ||
245 | {{"_DMA", 0, ACPI_RTYPE_BUFFER}}, | ||
246 | {{"_DOD", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Ints) */ | ||
247 | {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 0,0}, 0,0}}, | ||
248 | |||
249 | {{"_DOS", 1, 0}}, | ||
250 | {{"_DSM", 4, ACPI_RTYPE_ALL}}, /* Must return a type, but it can be of any type */ | ||
251 | {{"_DSS", 1, 0}}, | ||
252 | {{"_DSW", 3, 0}}, | ||
253 | {{"_DTI", 1, 0}}, | ||
254 | {{"_EC_", 0, ACPI_RTYPE_INTEGER}}, | ||
255 | {{"_EDL", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs)*/ | ||
256 | {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0}, 0,0}}, | ||
257 | |||
258 | {{"_EJ0", 1, 0}}, | ||
259 | {{"_EJ1", 1, 0}}, | ||
260 | {{"_EJ2", 1, 0}}, | ||
261 | {{"_EJ3", 1, 0}}, | ||
262 | {{"_EJ4", 1, 0}}, | ||
263 | {{"_EJD", 0, ACPI_RTYPE_STRING}}, | ||
264 | {{"_FDE", 0, ACPI_RTYPE_BUFFER}}, | ||
265 | {{"_FDI", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (16 Int) */ | ||
266 | {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 16,0}, 0,0}}, | ||
267 | |||
268 | {{"_FDM", 1, 0}}, | ||
269 | {{"_FIF", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (4 Int) */ | ||
270 | {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 4, 0}, 0, 0}}, | ||
271 | |||
272 | {{"_FIX", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Ints) */ | ||
273 | {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 0,0}, 0,0}}, | ||
274 | |||
275 | {{"_FPS", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (1 Int(rev), n Pkg (5 Int) */ | ||
276 | {{{ACPI_PTYPE2_REV_FIXED, ACPI_RTYPE_INTEGER, 5, 0}, 0, 0}}, | ||
277 | |||
278 | {{"_FSL", 1, 0}}, | ||
279 | {{"_FST", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (3 Int) */ | ||
280 | {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 3, 0}, 0, 0}}, | ||
281 | |||
282 | {{"_GAI", 0, ACPI_RTYPE_INTEGER}}, | ||
283 | {{"_GHL", 0, ACPI_RTYPE_INTEGER}}, | ||
284 | {{"_GLK", 0, ACPI_RTYPE_INTEGER}}, | ||
285 | {{"_GPD", 0, ACPI_RTYPE_INTEGER}}, | ||
286 | {{"_GPE", 0, ACPI_RTYPE_INTEGER}}, /* _GPE method, not _GPE scope */ | ||
287 | {{"_GSB", 0, ACPI_RTYPE_INTEGER}}, | ||
288 | {{"_GTF", 0, ACPI_RTYPE_BUFFER}}, | ||
289 | {{"_GTM", 0, ACPI_RTYPE_BUFFER}}, | ||
290 | {{"_GTS", 1, 0}}, | ||
291 | {{"_HID", 0, ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING}}, | ||
292 | {{"_HOT", 0, ACPI_RTYPE_INTEGER}}, | ||
293 | {{"_HPP", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (4 Int) */ | ||
294 | {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 4,0}, 0,0}}, | ||
225 | 295 | ||
226 | /* | 296 | /* |
227 | * For _HPX, a single package is returned, containing a variable number of sub-packages. | 297 | * For _HPX, a single package is returned, containing a Variable-length number |
228 | * Each sub-package contains a PCI record setting. There are several different type of | 298 | * of sub-packages. Each sub-package contains a PCI record setting. |
229 | * record settings, of different lengths, but all elements of all settings are Integers. | 299 | * There are several different type of record settings, of different |
300 | * lengths, but all elements of all settings are Integers. | ||
230 | */ | 301 | */ |
231 | {.info = {"_HPX", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE2_MIN, ACPI_RTYPE_INTEGER, 5, 0, 0, 0}}, /* variable (Pkgs) each (var Ints) */ | 302 | {{"_HPX", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Pkgs) each (var Ints) */ |
232 | {.info = {"_IFT", 0, ACPI_RTYPE_INTEGER}}, /* see IPMI spec */ | 303 | {{{ACPI_PTYPE2_MIN, ACPI_RTYPE_INTEGER, 5,0}, 0,0}}, |
233 | {.info = {"_INI", 0, 0}}, | 304 | |
234 | {.info = {"_IRC", 0, 0}}, | 305 | {{"_IFT", 0, ACPI_RTYPE_INTEGER}}, /* See IPMI spec */ |
235 | {.info = {"_LCK", 1, 0}}, | 306 | {{"_INI", 0, 0}}, |
236 | {.info = {"_LID", 0, ACPI_RTYPE_INTEGER}}, | 307 | {{"_IRC", 0, 0}}, |
237 | {.info = {"_MAT", 0, ACPI_RTYPE_BUFFER}}, | 308 | {{"_LCK", 1, 0}}, |
238 | {.info = {"_MLS", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE2, ACPI_RTYPE_STRING, 2, 0, 0, 0}}, /* variable (Pkgs) each (2 Str) */ | 309 | {{"_LID", 0, ACPI_RTYPE_INTEGER}}, |
239 | {.info = {"_MSG", 1, 0}}, | 310 | {{"_MAT", 0, ACPI_RTYPE_BUFFER}}, |
240 | {.info = {"_OFF", 0, 0}}, | 311 | {{"_MBM", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (8 Int) */ |
241 | {.info = {"_ON_", 0, 0}}, | 312 | {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 8, 0}, 0, 0}}, |
242 | {.info = {"_OS_", 0, ACPI_RTYPE_STRING}}, | 313 | |
243 | {.info = {"_OSC", 4, ACPI_RTYPE_BUFFER}}, | 314 | {{"_MLS", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Pkgs) each (2 Str) */ |
244 | {.info = {"_OST", 3, 0}}, | 315 | {{{ACPI_PTYPE2, ACPI_RTYPE_STRING, 2,0}, 0,0}}, |
245 | {.info = {"_PCL", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0, 0, 0}}, /* variable (Refs) */ | 316 | |
246 | {.info = {"_PCT", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_FIXED, ACPI_RTYPE_BUFFER, 2, 0, 0, 0}}, /* fixed (2 Buf) */ | 317 | {{"_MSG", 1, 0}}, |
247 | {.info = {"_PDC", 1, 0}}, | 318 | {{"_MSM", 4, ACPI_RTYPE_INTEGER}}, |
248 | {.info = {"_PIC", 1, 0}}, | 319 | {{"_NTT", 0, ACPI_RTYPE_INTEGER}}, |
249 | {.info = {"_PLD", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_BUFFER, 0, 0, 0, 0}}, /* variable (Bufs) */ | 320 | {{"_OFF", 0, 0}}, |
250 | {.info = {"_PPC", 0, ACPI_RTYPE_INTEGER}}, | 321 | {{"_ON_", 0, 0}}, |
251 | {.info = {"_PPE", 0, ACPI_RTYPE_INTEGER}}, /* see dig64 spec */ | 322 | {{"_OS_", 0, ACPI_RTYPE_STRING}}, |
252 | {.info = {"_PR0", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0, 0, 0}}, /* variable (Refs) */ | 323 | {{"_OSC", 4, ACPI_RTYPE_BUFFER}}, |
253 | {.info = {"_PR1", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0, 0, 0}}, /* variable (Refs) */ | 324 | {{"_OST", 3, 0}}, |
254 | {.info = {"_PR2", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0, 0, 0}}, /* variable (Refs) */ | 325 | {{"_PAI", 1, ACPI_RTYPE_INTEGER}}, |
255 | {.info = {"_PRS", 0, ACPI_RTYPE_BUFFER}}, | 326 | {{"_PCL", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs) */ |
327 | {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0}, 0,0}}, | ||
328 | |||
329 | {{"_PCT", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (2 Buf) */ | ||
330 | {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_BUFFER, 2,0}, 0,0}}, | ||
331 | |||
332 | {{"_PDC", 1, 0}}, | ||
333 | {{"_PDL", 0, ACPI_RTYPE_INTEGER}}, | ||
334 | {{"_PIC", 1, 0}}, | ||
335 | {{"_PIF", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (3 Int),(3 Str) */ | ||
336 | {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 3, ACPI_RTYPE_STRING}, 3, 0}}, | ||
337 | |||
338 | {{"_PLD", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Bufs) */ | ||
339 | {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_BUFFER, 0,0}, 0,0}}, | ||
340 | |||
341 | {{"_PMC", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (11 Int),(3 Str) */ | ||
342 | {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 11, ACPI_RTYPE_STRING}, 3, | ||
343 | 0}}, | ||
344 | |||
345 | {{"_PMD", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs) */ | ||
346 | {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0}, 0, 0}}, | ||
347 | |||
348 | {{"_PMM", 0, ACPI_RTYPE_INTEGER}}, | ||
349 | {{"_PPC", 0, ACPI_RTYPE_INTEGER}}, | ||
350 | {{"_PPE", 0, ACPI_RTYPE_INTEGER}}, /* See dig64 spec */ | ||
351 | {{"_PR0", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs) */ | ||
352 | {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0}, 0,0}}, | ||
353 | |||
354 | {{"_PR1", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs) */ | ||
355 | {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0}, 0,0}}, | ||
356 | |||
357 | {{"_PR2", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs) */ | ||
358 | {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0}, 0,0}}, | ||
359 | |||
360 | {{"_PR3", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs) */ | ||
361 | {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0}, 0, 0}}, | ||
362 | |||
363 | {{"_PRL", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs) */ | ||
364 | {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0}, 0, 0}}, | ||
365 | |||
366 | {{"_PRS", 0, ACPI_RTYPE_BUFFER}}, | ||
256 | 367 | ||
257 | /* | 368 | /* |
258 | * For _PRT, many BIOSs reverse the 2nd and 3rd Package elements. This bug is so prevalent that there | 369 | * For _PRT, many BIOSs reverse the 3rd and 4th Package elements (Source |
259 | * is code in the ACPICA Resource Manager to detect this and switch them back. For now, do not allow | 370 | * and source_index). This bug is so prevalent that there is code in the |
260 | * and issue a warning. To allow this and eliminate the warning, add the ACPI_RTYPE_REFERENCE | 371 | * ACPICA Resource Manager to detect this and switch them back. For now, |
261 | * type to the 2nd element (index 1) in the statement below. | 372 | * do not allow and issue a warning. To allow this and eliminate the |
373 | * warning, add the ACPI_RTYPE_REFERENCE type to the 4th element (index 3) | ||
374 | * in the statement below. | ||
262 | */ | 375 | */ |
263 | {.info = {"_PRT", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE2_FIXED, 4, | 376 | {{"_PRT", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Pkgs) each (4): Int,Int,Int/Ref,Int */ |
264 | ACPI_RTYPE_INTEGER, | 377 | {{{ACPI_PTYPE2_FIXED, 4, ACPI_RTYPE_INTEGER,ACPI_RTYPE_INTEGER}, |
265 | ACPI_RTYPE_INTEGER, | 378 | ACPI_RTYPE_INTEGER | ACPI_RTYPE_REFERENCE, |
266 | ACPI_RTYPE_INTEGER | ACPI_RTYPE_REFERENCE, ACPI_RTYPE_INTEGER}}, /* variable (Pkgs) each (4): Int,Int,Int/Ref,Int */ | 379 | ACPI_RTYPE_INTEGER}}, |
267 | 380 | ||
268 | {.info = {"_PRW", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_OPTION, 2, | 381 | {{"_PRW", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Pkgs) each: Pkg/Int,Int,[Variable-length Refs] (Pkg is Ref/Int) */ |
269 | ACPI_RTYPE_INTEGER | | 382 | {{{ACPI_PTYPE1_OPTION, 2, ACPI_RTYPE_INTEGER | ACPI_RTYPE_PACKAGE, |
270 | ACPI_RTYPE_PACKAGE, | 383 | ACPI_RTYPE_INTEGER}, ACPI_RTYPE_REFERENCE,0}}, |
271 | ACPI_RTYPE_INTEGER, ACPI_RTYPE_REFERENCE, 0}}, /* variable (Pkgs) each: Pkg/Int,Int,[variable Refs] (Pkg is Ref/Int) */ | 384 | |
272 | 385 | {{"_PS0", 0, 0}}, | |
273 | {.info = {"_PS0", 0, 0}}, | 386 | {{"_PS1", 0, 0}}, |
274 | {.info = {"_PS1", 0, 0}}, | 387 | {{"_PS2", 0, 0}}, |
275 | {.info = {"_PS2", 0, 0}}, | 388 | {{"_PS3", 0, 0}}, |
276 | {.info = {"_PS3", 0, 0}}, | 389 | {{"_PSC", 0, ACPI_RTYPE_INTEGER}}, |
277 | {.info = {"_PSC", 0, ACPI_RTYPE_INTEGER}}, | 390 | {{"_PSD", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Pkgs) each (5 Int) with count */ |
278 | {.info = {"_PSD", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE2_COUNT, ACPI_RTYPE_INTEGER, 0, 0, 0, 0}}, /* variable (Pkgs) each (5 Int) with count */ | 391 | {{{ACPI_PTYPE2_COUNT, ACPI_RTYPE_INTEGER,0,0}, 0,0}}, |
279 | {.info = {"_PSL", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0, 0, 0}}, /* variable (Refs) */ | 392 | |
280 | {.info = {"_PSR", 0, ACPI_RTYPE_INTEGER}}, | 393 | {{"_PSL", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs) */ |
281 | {.info = {"_PSS", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE2, ACPI_RTYPE_INTEGER, 6, 0, 0, 0}}, /* variable (Pkgs) each (6 Int) */ | 394 | {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0}, 0,0}}, |
282 | {.info = {"_PSV", 0, ACPI_RTYPE_INTEGER}}, | 395 | |
283 | {.info = {"_PSW", 1, 0}}, | 396 | {{"_PSR", 0, ACPI_RTYPE_INTEGER}}, |
284 | {.info = {"_PTC", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_FIXED, ACPI_RTYPE_BUFFER, 2, 0, 0, 0}}, /* fixed (2 Buf) */ | 397 | {{"_PSS", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Pkgs) each (6 Int) */ |
285 | {.info = {"_PTS", 1, 0}}, | 398 | {{{ACPI_PTYPE2, ACPI_RTYPE_INTEGER, 6,0}, 0,0}}, |
286 | {.info = {"_PXM", 0, ACPI_RTYPE_INTEGER}}, | 399 | |
287 | {.info = {"_REG", 2, 0}}, | 400 | {{"_PSV", 0, ACPI_RTYPE_INTEGER}}, |
288 | {.info = {"_REV", 0, ACPI_RTYPE_INTEGER}}, | 401 | {{"_PSW", 1, 0}}, |
289 | {.info = {"_RMV", 0, ACPI_RTYPE_INTEGER}}, | 402 | {{"_PTC", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (2 Buf) */ |
290 | {.info = {"_ROM", 2, ACPI_RTYPE_BUFFER}}, | 403 | {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_BUFFER, 2,0}, 0,0}}, |
291 | {.info = {"_RTV", 0, ACPI_RTYPE_INTEGER}}, | 404 | |
405 | {{"_PTP", 2, ACPI_RTYPE_INTEGER}}, | ||
406 | {{"_PTS", 1, 0}}, | ||
407 | {{"_PUR", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (2 Int) */ | ||
408 | {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 2, 0}, 0, 0}}, | ||
409 | |||
410 | {{"_PXM", 0, ACPI_RTYPE_INTEGER}}, | ||
411 | {{"_REG", 2, 0}}, | ||
412 | {{"_REV", 0, ACPI_RTYPE_INTEGER}}, | ||
413 | {{"_RMV", 0, ACPI_RTYPE_INTEGER}}, | ||
414 | {{"_ROM", 2, ACPI_RTYPE_BUFFER}}, | ||
415 | {{"_RTV", 0, ACPI_RTYPE_INTEGER}}, | ||
292 | 416 | ||
293 | /* | 417 | /* |
294 | * For _S0_ through _S5_, the ACPI spec defines a return Package containing 1 Integer, | 418 | * For _S0_ through _S5_, the ACPI spec defines a return Package |
295 | * but most DSDTs have it wrong - 2,3, or 4 integers. Allow this by making the objects "variable length", | 419 | * containing 1 Integer, but most DSDTs have it wrong - 2,3, or 4 integers. |
296 | * but all elements must be Integers. | 420 | * Allow this by making the objects "Variable-length length", but all elements |
421 | * must be Integers. | ||
297 | */ | 422 | */ |
298 | {.info = {"_S0_", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 1, 0, 0, 0}}, /* fixed (1 Int) */ | 423 | {{"_S0_", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (1 Int) */ |
299 | {.info = {"_S1_", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 1, 0, 0, 0}}, /* fixed (1 Int) */ | 424 | {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 1,0}, 0,0}}, |
300 | {.info = {"_S2_", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 1, 0, 0, 0}}, /* fixed (1 Int) */ | 425 | |
301 | {.info = {"_S3_", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 1, 0, 0, 0}}, /* fixed (1 Int) */ | 426 | {{"_S1_", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (1 Int) */ |
302 | {.info = {"_S4_", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 1, 0, 0, 0}}, /* fixed (1 Int) */ | 427 | {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 1,0}, 0,0}}, |
303 | {.info = {"_S5_", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 1, 0, 0, 0}}, /* fixed (1 Int) */ | 428 | |
304 | 429 | {{"_S2_", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (1 Int) */ | |
305 | {.info = {"_S1D", 0, ACPI_RTYPE_INTEGER}}, | 430 | {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 1,0}, 0,0}}, |
306 | {.info = {"_S2D", 0, ACPI_RTYPE_INTEGER}}, | 431 | |
307 | {.info = {"_S3D", 0, ACPI_RTYPE_INTEGER}}, | 432 | {{"_S3_", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (1 Int) */ |
308 | {.info = {"_S4D", 0, ACPI_RTYPE_INTEGER}}, | 433 | {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 1,0}, 0,0}}, |
309 | {.info = {"_S0W", 0, ACPI_RTYPE_INTEGER}}, | 434 | |
310 | {.info = {"_S1W", 0, ACPI_RTYPE_INTEGER}}, | 435 | {{"_S4_", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (1 Int) */ |
311 | {.info = {"_S2W", 0, ACPI_RTYPE_INTEGER}}, | 436 | {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 1,0}, 0,0}}, |
312 | {.info = {"_S3W", 0, ACPI_RTYPE_INTEGER}}, | 437 | |
313 | {.info = {"_S4W", 0, ACPI_RTYPE_INTEGER}}, | 438 | {{"_S5_", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (1 Int) */ |
314 | {.info = {"_SBS", 0, ACPI_RTYPE_INTEGER}}, | 439 | {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 1,0}, 0,0}}, |
315 | {.info = {"_SCP", 0x13, 0}}, /* Acpi 1.0 allowed 1 arg. Acpi 3.0 expanded to 3 args. Allow both. */ | 440 | |
316 | /* Note: the 3-arg definition may be removed for ACPI 4.0 */ | 441 | {{"_S1D", 0, ACPI_RTYPE_INTEGER}}, |
317 | {.info = {"_SDD", 1, 0}}, | 442 | {{"_S2D", 0, ACPI_RTYPE_INTEGER}}, |
318 | {.info = {"_SEG", 0, ACPI_RTYPE_INTEGER}}, | 443 | {{"_S3D", 0, ACPI_RTYPE_INTEGER}}, |
319 | {.info = {"_SLI", 0, ACPI_RTYPE_BUFFER}}, | 444 | {{"_S4D", 0, ACPI_RTYPE_INTEGER}}, |
320 | {.info = {"_SPD", 1, ACPI_RTYPE_INTEGER}}, | 445 | {{"_S0W", 0, ACPI_RTYPE_INTEGER}}, |
321 | {.info = {"_SRS", 1, 0}}, | 446 | {{"_S1W", 0, ACPI_RTYPE_INTEGER}}, |
322 | {.info = {"_SRV", 0, ACPI_RTYPE_INTEGER}}, /* see IPMI spec */ | 447 | {{"_S2W", 0, ACPI_RTYPE_INTEGER}}, |
323 | {.info = {"_SST", 1, 0}}, | 448 | {{"_S3W", 0, ACPI_RTYPE_INTEGER}}, |
324 | {.info = {"_STA", 0, ACPI_RTYPE_INTEGER}}, | 449 | {{"_S4W", 0, ACPI_RTYPE_INTEGER}}, |
325 | {.info = {"_STM", 3, 0}}, | 450 | {{"_SBS", 0, ACPI_RTYPE_INTEGER}}, |
326 | {.info = {"_STR", 0, ACPI_RTYPE_BUFFER}}, | 451 | {{"_SCP", 0x13, 0}}, /* Acpi 1.0 allowed 1 arg. Acpi 3.0 expanded to 3 args. Allow both. */ |
327 | {.info = {"_SUN", 0, ACPI_RTYPE_INTEGER}}, | 452 | /* Note: the 3-arg definition may be removed for ACPI 4.0 */ |
328 | {.info = {"_SWS", 0, ACPI_RTYPE_INTEGER}}, | 453 | {{"_SDD", 1, 0}}, |
329 | {.info = {"_TC1", 0, ACPI_RTYPE_INTEGER}}, | 454 | {{"_SEG", 0, ACPI_RTYPE_INTEGER}}, |
330 | {.info = {"_TC2", 0, ACPI_RTYPE_INTEGER}}, | 455 | {{"_SHL", 1, ACPI_RTYPE_INTEGER}}, |
331 | {.info = {"_TMP", 0, ACPI_RTYPE_INTEGER}}, | 456 | {{"_SLI", 0, ACPI_RTYPE_BUFFER}}, |
332 | {.info = {"_TPC", 0, ACPI_RTYPE_INTEGER}}, | 457 | {{"_SPD", 1, ACPI_RTYPE_INTEGER}}, |
333 | {.info = {"_TPT", 1, 0}}, | 458 | {{"_SRS", 1, 0}}, |
334 | {.info = {"_TRT", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE2, ACPI_RTYPE_REFERENCE, 2, | 459 | {{"_SRV", 0, ACPI_RTYPE_INTEGER}}, /* See IPMI spec */ |
335 | ACPI_RTYPE_INTEGER, 6, 0}}, /* variable (Pkgs) each 2_ref/6_int */ | 460 | {{"_SST", 1, 0}}, |
336 | {.info = {"_TSD", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE2_COUNT, ACPI_RTYPE_INTEGER, 5, 0, 0, 0}}, /* variable (Pkgs) each 5_int with count */ | 461 | {{"_STA", 0, ACPI_RTYPE_INTEGER}}, |
337 | {.info = {"_TSP", 0, ACPI_RTYPE_INTEGER}}, | 462 | {{"_STM", 3, 0}}, |
338 | {.info = {"_TSS", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE2, ACPI_RTYPE_INTEGER, 5, 0, 0, 0}}, /* variable (Pkgs) each 5_int */ | 463 | {{"_STP", 2, ACPI_RTYPE_INTEGER}}, |
339 | {.info = {"_TST", 0, ACPI_RTYPE_INTEGER}}, | 464 | {{"_STR", 0, ACPI_RTYPE_BUFFER}}, |
340 | {.info = {"_TTS", 1, 0}}, | 465 | {{"_STV", 2, ACPI_RTYPE_INTEGER}}, |
341 | {.info = {"_TZD", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0, 0, 0}}, /* variable (Refs) */ | 466 | {{"_SUN", 0, ACPI_RTYPE_INTEGER}}, |
342 | {.info = {"_TZM", 0, ACPI_RTYPE_REFERENCE}}, | 467 | {{"_SWS", 0, ACPI_RTYPE_INTEGER}}, |
343 | {.info = {"_TZP", 0, ACPI_RTYPE_INTEGER}}, | 468 | {{"_TC1", 0, ACPI_RTYPE_INTEGER}}, |
344 | {.info = {"_UID", 0, ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING}}, | 469 | {{"_TC2", 0, ACPI_RTYPE_INTEGER}}, |
345 | {.info = {"_UPC", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 4, 0, 0, 0}}, /* fixed (4 Int) */ | 470 | {{"_TIP", 1, ACPI_RTYPE_INTEGER}}, |
346 | {.info = {"_UPD", 0, ACPI_RTYPE_INTEGER}}, | 471 | {{"_TIV", 1, ACPI_RTYPE_INTEGER}}, |
347 | {.info = {"_UPP", 0, ACPI_RTYPE_INTEGER}}, | 472 | {{"_TMP", 0, ACPI_RTYPE_INTEGER}}, |
348 | {.info = {"_VPO", 0, ACPI_RTYPE_INTEGER}}, | 473 | {{"_TPC", 0, ACPI_RTYPE_INTEGER}}, |
474 | {{"_TPT", 1, 0}}, | ||
475 | {{"_TRT", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Pkgs) each 2_ref/6_int */ | ||
476 | {{{ACPI_PTYPE2, ACPI_RTYPE_REFERENCE, 2, ACPI_RTYPE_INTEGER}, 6, 0}}, | ||
477 | |||
478 | {{"_TSD", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Pkgs) each 5_int with count */ | ||
479 | {{{ACPI_PTYPE2_COUNT,ACPI_RTYPE_INTEGER, 5,0}, 0,0}}, | ||
480 | |||
481 | {{"_TSP", 0, ACPI_RTYPE_INTEGER}}, | ||
482 | {{"_TSS", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Pkgs) each 5_int */ | ||
483 | {{{ACPI_PTYPE2, ACPI_RTYPE_INTEGER, 5,0}, 0,0}}, | ||
484 | |||
485 | {{"_TST", 0, ACPI_RTYPE_INTEGER}}, | ||
486 | {{"_TTS", 1, 0}}, | ||
487 | {{"_TZD", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs) */ | ||
488 | {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0}, 0,0}}, | ||
489 | |||
490 | {{"_TZM", 0, ACPI_RTYPE_REFERENCE}}, | ||
491 | {{"_TZP", 0, ACPI_RTYPE_INTEGER}}, | ||
492 | {{"_UID", 0, ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING}}, | ||
493 | {{"_UPC", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (4 Int) */ | ||
494 | {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 4,0}, 0,0}}, | ||
495 | |||
496 | {{"_UPD", 0, ACPI_RTYPE_INTEGER}}, | ||
497 | {{"_UPP", 0, ACPI_RTYPE_INTEGER}}, | ||
498 | {{"_VPO", 0, ACPI_RTYPE_INTEGER}}, | ||
349 | 499 | ||
350 | /* Acpi 1.0 defined _WAK with no return value. Later, it was changed to return a package */ | 500 | /* Acpi 1.0 defined _WAK with no return value. Later, it was changed to return a package */ |
351 | 501 | ||
352 | {.info = {"_WAK", 1, ACPI_RTYPE_NONE | ACPI_RTYPE_INTEGER | ACPI_RTYPE_PACKAGE}}, | 502 | {{"_WAK", 1, ACPI_RTYPE_NONE | ACPI_RTYPE_INTEGER | ACPI_RTYPE_PACKAGE}}, |
353 | {.ret_info = {ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 2, 0, 0, 0}}, /* fixed (2 Int), but is optional */ | 503 | {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 2,0}, 0,0}}, /* Fixed-length (2 Int), but is optional */ |
354 | {.ret_info = {0, 0, 0, 0, 0, 0}} /* Table terminator */ | 504 | |
505 | {{{0,0,0,0}, 0,0}} /* Table terminator */ | ||
355 | }; | 506 | }; |
356 | 507 | ||
357 | #if 0 | 508 | #if 0 |
358 | /* Not implemented */ | 509 | /* Not implemented */ |
359 | 510 | ||
360 | { | 511 | {{"_WDG", 0, ACPI_RTYPE_BUFFER}}, /* MS Extension */ |
361 | "_WDG", 0, ACPI_RTYPE_BUFFER}, /* MS Extension */ | 512 | {{"_WED", 1, ACPI_RTYPE_PACKAGE}}, /* MS Extension */ |
362 | 513 | ||
363 | { | 514 | /* This is an internally implemented control method, no need to check */ |
364 | "_WED", 1, ACPI_RTYPE_PACKAGE}, /* MS Extension */ | 515 | {{"_OSI", 1, ACPI_RTYPE_INTEGER}}, |
365 | 516 | ||
366 | /* This is an internally implemented control method, no need to check */ | 517 | /* TBD: */ |
367 | { | 518 | |
368 | "_OSI", 1, ACPI_RTYPE_INTEGER}, | 519 | _PRT - currently ignore reversed entries. attempt to fix here? |
520 | think about possibly fixing package elements like _BIF, etc. | ||
521 | #endif | ||
369 | 522 | ||
370 | /* TBD: */ | ||
371 | _PRT - currently ignore reversed entries.attempt to fix here ? | ||
372 | think about code that attempts to fix package elements like _BIF, etc. | ||
373 | #endif | 523 | #endif |
374 | #endif | 524 | #endif |
diff --git a/drivers/acpi/acpica/acutils.h b/drivers/acpi/acpica/acutils.h index 897810ba0ccc..863a264b829e 100644 --- a/drivers/acpi/acpica/acutils.h +++ b/drivers/acpi/acpica/acutils.h | |||
@@ -324,26 +324,30 @@ acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node, | |||
324 | acpi_status | 324 | acpi_status |
325 | acpi_ut_evaluate_numeric_object(char *object_name, | 325 | acpi_ut_evaluate_numeric_object(char *object_name, |
326 | struct acpi_namespace_node *device_node, | 326 | struct acpi_namespace_node *device_node, |
327 | acpi_integer * address); | 327 | acpi_integer *value); |
328 | 328 | ||
329 | acpi_status | 329 | acpi_status |
330 | acpi_ut_execute_HID(struct acpi_namespace_node *device_node, | 330 | acpi_ut_execute_STA(struct acpi_namespace_node *device_node, u32 *status_flags); |
331 | struct acpica_device_id *hid); | ||
332 | 331 | ||
333 | acpi_status | 332 | acpi_status |
334 | acpi_ut_execute_CID(struct acpi_namespace_node *device_node, | 333 | acpi_ut_execute_power_methods(struct acpi_namespace_node *device_node, |
335 | struct acpi_compatible_id_list **return_cid_list); | 334 | const char **method_names, |
335 | u8 method_count, u8 *out_values); | ||
336 | 336 | ||
337 | /* | ||
338 | * utids - device ID support | ||
339 | */ | ||
337 | acpi_status | 340 | acpi_status |
338 | acpi_ut_execute_STA(struct acpi_namespace_node *device_node, | 341 | acpi_ut_execute_HID(struct acpi_namespace_node *device_node, |
339 | u32 * status_flags); | 342 | struct acpica_device_id **return_id); |
340 | 343 | ||
341 | acpi_status | 344 | acpi_status |
342 | acpi_ut_execute_UID(struct acpi_namespace_node *device_node, | 345 | acpi_ut_execute_UID(struct acpi_namespace_node *device_node, |
343 | struct acpica_device_id *uid); | 346 | struct acpica_device_id **return_id); |
344 | 347 | ||
345 | acpi_status | 348 | acpi_status |
346 | acpi_ut_execute_sxds(struct acpi_namespace_node *device_node, u8 * highest); | 349 | acpi_ut_execute_CID(struct acpi_namespace_node *device_node, |
350 | struct acpica_device_id_list **return_cid_list); | ||
347 | 351 | ||
348 | /* | 352 | /* |
349 | * utlock - reader/writer locks | 353 | * utlock - reader/writer locks |
@@ -445,6 +449,8 @@ acpi_ut_short_divide(acpi_integer in_dividend, | |||
445 | */ | 449 | */ |
446 | const char *acpi_ut_validate_exception(acpi_status status); | 450 | const char *acpi_ut_validate_exception(acpi_status status); |
447 | 451 | ||
452 | u8 acpi_ut_is_pci_root_bridge(char *id); | ||
453 | |||
448 | u8 acpi_ut_is_aml_table(struct acpi_table_header *table); | 454 | u8 acpi_ut_is_aml_table(struct acpi_table_header *table); |
449 | 455 | ||
450 | acpi_status acpi_ut_allocate_owner_id(acpi_owner_id * owner_id); | 456 | acpi_status acpi_ut_allocate_owner_id(acpi_owner_id * owner_id); |
@@ -469,6 +475,12 @@ u8 acpi_ut_valid_acpi_char(char character, u32 position); | |||
469 | acpi_status | 475 | acpi_status |
470 | acpi_ut_strtoul64(char *string, u32 base, acpi_integer * ret_integer); | 476 | acpi_ut_strtoul64(char *string, u32 base, acpi_integer * ret_integer); |
471 | 477 | ||
478 | void ACPI_INTERNAL_VAR_XFACE | ||
479 | acpi_ut_predefined_warning(const char *module_name, | ||
480 | u32 line_number, | ||
481 | char *pathname, | ||
482 | u8 node_flags, const char *format, ...); | ||
483 | |||
472 | /* Values for Base above (16=Hex, 10=Decimal) */ | 484 | /* Values for Base above (16=Hex, 10=Decimal) */ |
473 | 485 | ||
474 | #define ACPI_ANY_BASE 0 | 486 | #define ACPI_ANY_BASE 0 |
diff --git a/drivers/acpi/acpica/amlcode.h b/drivers/acpi/acpica/amlcode.h index ff851c5df698..4940249f2524 100644 --- a/drivers/acpi/acpica/amlcode.h +++ b/drivers/acpi/acpica/amlcode.h | |||
@@ -404,6 +404,7 @@ typedef enum { | |||
404 | REGION_SMBUS, | 404 | REGION_SMBUS, |
405 | REGION_CMOS, | 405 | REGION_CMOS, |
406 | REGION_PCI_BAR, | 406 | REGION_PCI_BAR, |
407 | REGION_IPMI, | ||
407 | REGION_DATA_TABLE, /* Internal use only */ | 408 | REGION_DATA_TABLE, /* Internal use only */ |
408 | REGION_FIXED_HW = 0x7F | 409 | REGION_FIXED_HW = 0x7F |
409 | } AML_REGION_TYPES; | 410 | } AML_REGION_TYPES; |
@@ -483,7 +484,7 @@ typedef enum { | |||
483 | 484 | ||
484 | #define AML_METHOD_ARG_COUNT 0x07 | 485 | #define AML_METHOD_ARG_COUNT 0x07 |
485 | #define AML_METHOD_SERIALIZED 0x08 | 486 | #define AML_METHOD_SERIALIZED 0x08 |
486 | #define AML_METHOD_SYNCH_LEVEL 0xF0 | 487 | #define AML_METHOD_SYNC_LEVEL 0xF0 |
487 | 488 | ||
488 | /* METHOD_FLAGS_ARG_COUNT is not used internally, define additional flags */ | 489 | /* METHOD_FLAGS_ARG_COUNT is not used internally, define additional flags */ |
489 | 490 | ||
diff --git a/drivers/acpi/acpica/dsfield.c b/drivers/acpi/acpica/dsfield.c index 53e27bc5a734..54a225e56a64 100644 --- a/drivers/acpi/acpica/dsfield.c +++ b/drivers/acpi/acpica/dsfield.c | |||
@@ -123,9 +123,12 @@ acpi_ds_create_buffer_field(union acpi_parse_object *op, | |||
123 | flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | | 123 | flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | |
124 | ACPI_NS_ERROR_IF_FOUND; | 124 | ACPI_NS_ERROR_IF_FOUND; |
125 | 125 | ||
126 | /* Mark node temporary if we are executing a method */ | 126 | /* |
127 | 127 | * Mark node temporary if we are executing a normal control | |
128 | if (walk_state->method_node) { | 128 | * method. (Don't mark if this is a module-level code method) |
129 | */ | ||
130 | if (walk_state->method_node && | ||
131 | !(walk_state->parse_flags & ACPI_PARSE_MODULE_LEVEL)) { | ||
129 | flags |= ACPI_NS_TEMPORARY; | 132 | flags |= ACPI_NS_TEMPORARY; |
130 | } | 133 | } |
131 | 134 | ||
@@ -456,9 +459,12 @@ acpi_ds_init_field_objects(union acpi_parse_object *op, | |||
456 | flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | | 459 | flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | |
457 | ACPI_NS_ERROR_IF_FOUND; | 460 | ACPI_NS_ERROR_IF_FOUND; |
458 | 461 | ||
459 | /* Mark node(s) temporary if we are executing a method */ | 462 | /* |
460 | 463 | * Mark node(s) temporary if we are executing a normal control | |
461 | if (walk_state->method_node) { | 464 | * method. (Don't mark if this is a module-level code method) |
465 | */ | ||
466 | if (walk_state->method_node && | ||
467 | !(walk_state->parse_flags & ACPI_PARSE_MODULE_LEVEL)) { | ||
462 | flags |= ACPI_NS_TEMPORARY; | 468 | flags |= ACPI_NS_TEMPORARY; |
463 | } | 469 | } |
464 | 470 | ||
diff --git a/drivers/acpi/acpica/dsmethod.c b/drivers/acpi/acpica/dsmethod.c index 14b8b8ed8023..567a4899a018 100644 --- a/drivers/acpi/acpica/dsmethod.c +++ b/drivers/acpi/acpica/dsmethod.c | |||
@@ -578,10 +578,15 @@ acpi_ds_terminate_control_method(union acpi_operand_object *method_desc, | |||
578 | } | 578 | } |
579 | 579 | ||
580 | /* | 580 | /* |
581 | * Delete any namespace objects created anywhere within | 581 | * Delete any namespace objects created anywhere within the |
582 | * the namespace by the execution of this method | 582 | * namespace by the execution of this method. Unless this method |
583 | * is a module-level executable code method, in which case we | ||
584 | * want make the objects permanent. | ||
583 | */ | 585 | */ |
584 | acpi_ns_delete_namespace_by_owner(method_desc->method.owner_id); | 586 | if (!(method_desc->method.flags & AOPOBJ_MODULE_LEVEL)) { |
587 | acpi_ns_delete_namespace_by_owner(method_desc->method. | ||
588 | owner_id); | ||
589 | } | ||
585 | } | 590 | } |
586 | 591 | ||
587 | /* Decrement the thread count on the method */ | 592 | /* Decrement the thread count on the method */ |
@@ -622,7 +627,9 @@ acpi_ds_terminate_control_method(union acpi_operand_object *method_desc, | |||
622 | 627 | ||
623 | /* No more threads, we can free the owner_id */ | 628 | /* No more threads, we can free the owner_id */ |
624 | 629 | ||
625 | acpi_ut_release_owner_id(&method_desc->method.owner_id); | 630 | if (!(method_desc->method.flags & AOPOBJ_MODULE_LEVEL)) { |
631 | acpi_ut_release_owner_id(&method_desc->method.owner_id); | ||
632 | } | ||
626 | } | 633 | } |
627 | 634 | ||
628 | return_VOID; | 635 | return_VOID; |
diff --git a/drivers/acpi/acpica/dsmthdat.c b/drivers/acpi/acpica/dsmthdat.c index 22b1a3ce2c94..7d077bb2f525 100644 --- a/drivers/acpi/acpica/dsmthdat.c +++ b/drivers/acpi/acpica/dsmthdat.c | |||
@@ -433,10 +433,10 @@ acpi_ds_method_data_get_value(u8 type, | |||
433 | 433 | ||
434 | case ACPI_REFCLASS_LOCAL: | 434 | case ACPI_REFCLASS_LOCAL: |
435 | 435 | ||
436 | ACPI_ERROR((AE_INFO, | 436 | /* |
437 | "Uninitialized Local[%d] at node %p", | 437 | * No error message for this case, will be trapped again later to |
438 | index, node)); | 438 | * detect and ignore cases of Store(local_x,local_x) |
439 | 439 | */ | |
440 | return_ACPI_STATUS(AE_AML_UNINITIALIZED_LOCAL); | 440 | return_ACPI_STATUS(AE_AML_UNINITIALIZED_LOCAL); |
441 | 441 | ||
442 | default: | 442 | default: |
diff --git a/drivers/acpi/acpica/dsobject.c b/drivers/acpi/acpica/dsobject.c index dab3f48f0b42..507e1f0bbdfd 100644 --- a/drivers/acpi/acpica/dsobject.c +++ b/drivers/acpi/acpica/dsobject.c | |||
@@ -482,14 +482,27 @@ acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state, | |||
482 | if (arg) { | 482 | if (arg) { |
483 | /* | 483 | /* |
484 | * num_elements was exhausted, but there are remaining elements in the | 484 | * num_elements was exhausted, but there are remaining elements in the |
485 | * package_list. | 485 | * package_list. Truncate the package to num_elements. |
486 | * | 486 | * |
487 | * Note: technically, this is an error, from ACPI spec: "It is an error | 487 | * Note: technically, this is an error, from ACPI spec: "It is an error |
488 | * for NumElements to be less than the number of elements in the | 488 | * for NumElements to be less than the number of elements in the |
489 | * PackageList". However, for now, we just print an error message and | 489 | * PackageList". However, we just print an error message and |
490 | * no exception is returned. | 490 | * no exception is returned. This provides Windows compatibility. Some |
491 | * BIOSs will alter the num_elements on the fly, creating this type | ||
492 | * of ill-formed package object. | ||
491 | */ | 493 | */ |
492 | while (arg) { | 494 | while (arg) { |
495 | /* | ||
496 | * We must delete any package elements that were created earlier | ||
497 | * and are not going to be used because of the package truncation. | ||
498 | */ | ||
499 | if (arg->common.node) { | ||
500 | acpi_ut_remove_reference(ACPI_CAST_PTR | ||
501 | (union | ||
502 | acpi_operand_object, | ||
503 | arg->common.node)); | ||
504 | arg->common.node = NULL; | ||
505 | } | ||
493 | 506 | ||
494 | /* Find out how many elements there really are */ | 507 | /* Find out how many elements there really are */ |
495 | 508 | ||
@@ -498,7 +511,7 @@ acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state, | |||
498 | } | 511 | } |
499 | 512 | ||
500 | ACPI_WARNING((AE_INFO, | 513 | ACPI_WARNING((AE_INFO, |
501 | "Package List length (%X) larger than NumElements count (%X), truncated\n", | 514 | "Package List length (0x%X) larger than NumElements count (0x%X), truncated\n", |
502 | i, element_count)); | 515 | i, element_count)); |
503 | } else if (i < element_count) { | 516 | } else if (i < element_count) { |
504 | /* | 517 | /* |
@@ -506,7 +519,7 @@ acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state, | |||
506 | * Note: this is not an error, the package is padded out with NULLs. | 519 | * Note: this is not an error, the package is padded out with NULLs. |
507 | */ | 520 | */ |
508 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 521 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
509 | "Package List length (%X) smaller than NumElements count (%X), padded with null elements\n", | 522 | "Package List length (0x%X) smaller than NumElements count (0x%X), padded with null elements\n", |
510 | i, element_count)); | 523 | i, element_count)); |
511 | } | 524 | } |
512 | 525 | ||
@@ -734,7 +747,8 @@ acpi_ds_init_object_from_op(struct acpi_walk_state *walk_state, | |||
734 | 747 | ||
735 | /* Local ID (0-7) is (AML opcode - base AML_LOCAL_OP) */ | 748 | /* Local ID (0-7) is (AML opcode - base AML_LOCAL_OP) */ |
736 | 749 | ||
737 | obj_desc->reference.value = opcode - AML_LOCAL_OP; | 750 | obj_desc->reference.value = |
751 | ((u32)opcode) - AML_LOCAL_OP; | ||
738 | obj_desc->reference.class = ACPI_REFCLASS_LOCAL; | 752 | obj_desc->reference.class = ACPI_REFCLASS_LOCAL; |
739 | 753 | ||
740 | #ifndef ACPI_NO_METHOD_EXECUTION | 754 | #ifndef ACPI_NO_METHOD_EXECUTION |
@@ -754,7 +768,7 @@ acpi_ds_init_object_from_op(struct acpi_walk_state *walk_state, | |||
754 | 768 | ||
755 | /* Arg ID (0-6) is (AML opcode - base AML_ARG_OP) */ | 769 | /* Arg ID (0-6) is (AML opcode - base AML_ARG_OP) */ |
756 | 770 | ||
757 | obj_desc->reference.value = opcode - AML_ARG_OP; | 771 | obj_desc->reference.value = ((u32)opcode) - AML_ARG_OP; |
758 | obj_desc->reference.class = ACPI_REFCLASS_ARG; | 772 | obj_desc->reference.class = ACPI_REFCLASS_ARG; |
759 | 773 | ||
760 | #ifndef ACPI_NO_METHOD_EXECUTION | 774 | #ifndef ACPI_NO_METHOD_EXECUTION |
diff --git a/drivers/acpi/acpica/dsopcode.c b/drivers/acpi/acpica/dsopcode.c index b4c87b5053e6..b79978f7bc71 100644 --- a/drivers/acpi/acpica/dsopcode.c +++ b/drivers/acpi/acpica/dsopcode.c | |||
@@ -397,6 +397,30 @@ acpi_status acpi_ds_get_region_arguments(union acpi_operand_object *obj_desc) | |||
397 | status = acpi_ds_execute_arguments(node, acpi_ns_get_parent_node(node), | 397 | status = acpi_ds_execute_arguments(node, acpi_ns_get_parent_node(node), |
398 | extra_desc->extra.aml_length, | 398 | extra_desc->extra.aml_length, |
399 | extra_desc->extra.aml_start); | 399 | extra_desc->extra.aml_start); |
400 | if (ACPI_FAILURE(status)) { | ||
401 | return_ACPI_STATUS(status); | ||
402 | } | ||
403 | |||
404 | /* Validate the region address/length via the host OS */ | ||
405 | |||
406 | status = acpi_os_validate_address(obj_desc->region.space_id, | ||
407 | obj_desc->region.address, | ||
408 | (acpi_size) obj_desc->region.length, | ||
409 | acpi_ut_get_node_name(node)); | ||
410 | |||
411 | if (ACPI_FAILURE(status)) { | ||
412 | /* | ||
413 | * Invalid address/length. We will emit an error message and mark | ||
414 | * the region as invalid, so that it will cause an additional error if | ||
415 | * it is ever used. Then return AE_OK. | ||
416 | */ | ||
417 | ACPI_EXCEPTION((AE_INFO, status, | ||
418 | "During address validation of OpRegion [%4.4s]", | ||
419 | node->name.ascii)); | ||
420 | obj_desc->common.flags |= AOPOBJ_INVALID; | ||
421 | status = AE_OK; | ||
422 | } | ||
423 | |||
400 | return_ACPI_STATUS(status); | 424 | return_ACPI_STATUS(status); |
401 | } | 425 | } |
402 | 426 | ||
@@ -1386,14 +1410,19 @@ acpi_ds_exec_end_control_op(struct acpi_walk_state * walk_state, | |||
1386 | 1410 | ||
1387 | case AML_BREAK_POINT_OP: | 1411 | case AML_BREAK_POINT_OP: |
1388 | 1412 | ||
1389 | /* Call up to the OS service layer to handle this */ | 1413 | /* |
1390 | 1414 | * Set the single-step flag. This will cause the debugger (if present) | |
1391 | status = | 1415 | * to break to the console within the AML debugger at the start of the |
1392 | acpi_os_signal(ACPI_SIGNAL_BREAKPOINT, | 1416 | * next AML instruction. |
1393 | "Executed AML Breakpoint opcode"); | 1417 | */ |
1418 | ACPI_DEBUGGER_EXEC(acpi_gbl_cm_single_step = TRUE); | ||
1419 | ACPI_DEBUGGER_EXEC(acpi_os_printf | ||
1420 | ("**break** Executed AML BreakPoint opcode\n")); | ||
1394 | 1421 | ||
1395 | /* If and when it returns, all done. */ | 1422 | /* Call to the OSL in case OS wants a piece of the action */ |
1396 | 1423 | ||
1424 | status = acpi_os_signal(ACPI_SIGNAL_BREAKPOINT, | ||
1425 | "Executed AML Breakpoint opcode"); | ||
1397 | break; | 1426 | break; |
1398 | 1427 | ||
1399 | case AML_BREAK_OP: | 1428 | case AML_BREAK_OP: |
diff --git a/drivers/acpi/acpica/dswload.c b/drivers/acpi/acpica/dswload.c index 3023ceaa8d54..6de3a99d4cd4 100644 --- a/drivers/acpi/acpica/dswload.c +++ b/drivers/acpi/acpica/dswload.c | |||
@@ -581,21 +581,6 @@ acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state, | |||
581 | if ((!(walk_state->op_info->flags & AML_NSOPCODE) && | 581 | if ((!(walk_state->op_info->flags & AML_NSOPCODE) && |
582 | (walk_state->opcode != AML_INT_NAMEPATH_OP)) || | 582 | (walk_state->opcode != AML_INT_NAMEPATH_OP)) || |
583 | (!(walk_state->op_info->flags & AML_NAMED))) { | 583 | (!(walk_state->op_info->flags & AML_NAMED))) { |
584 | #ifdef ACPI_ENABLE_MODULE_LEVEL_CODE | ||
585 | if ((walk_state->op_info->class == AML_CLASS_EXECUTE) || | ||
586 | (walk_state->op_info->class == AML_CLASS_CONTROL)) { | ||
587 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, | ||
588 | "Begin/EXEC: %s (fl %8.8X)\n", | ||
589 | walk_state->op_info->name, | ||
590 | walk_state->op_info->flags)); | ||
591 | |||
592 | /* Executing a type1 or type2 opcode outside of a method */ | ||
593 | |||
594 | status = | ||
595 | acpi_ds_exec_begin_op(walk_state, out_op); | ||
596 | return_ACPI_STATUS(status); | ||
597 | } | ||
598 | #endif | ||
599 | return_ACPI_STATUS(AE_OK); | 584 | return_ACPI_STATUS(AE_OK); |
600 | } | 585 | } |
601 | 586 | ||
@@ -768,7 +753,13 @@ acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state, | |||
768 | 753 | ||
769 | /* Execution mode, node cannot already exist, node is temporary */ | 754 | /* Execution mode, node cannot already exist, node is temporary */ |
770 | 755 | ||
771 | flags |= (ACPI_NS_ERROR_IF_FOUND | ACPI_NS_TEMPORARY); | 756 | flags |= ACPI_NS_ERROR_IF_FOUND; |
757 | |||
758 | if (! | ||
759 | (walk_state-> | ||
760 | parse_flags & ACPI_PARSE_MODULE_LEVEL)) { | ||
761 | flags |= ACPI_NS_TEMPORARY; | ||
762 | } | ||
772 | } | 763 | } |
773 | 764 | ||
774 | /* Add new entry or lookup existing entry */ | 765 | /* Add new entry or lookup existing entry */ |
@@ -851,24 +842,6 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state) | |||
851 | /* Check if opcode had an associated namespace object */ | 842 | /* Check if opcode had an associated namespace object */ |
852 | 843 | ||
853 | if (!(walk_state->op_info->flags & AML_NSOBJECT)) { | 844 | if (!(walk_state->op_info->flags & AML_NSOBJECT)) { |
854 | #ifndef ACPI_NO_METHOD_EXECUTION | ||
855 | #ifdef ACPI_ENABLE_MODULE_LEVEL_CODE | ||
856 | /* No namespace object. Executable opcode? */ | ||
857 | |||
858 | if ((walk_state->op_info->class == AML_CLASS_EXECUTE) || | ||
859 | (walk_state->op_info->class == AML_CLASS_CONTROL)) { | ||
860 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, | ||
861 | "End/EXEC: %s (fl %8.8X)\n", | ||
862 | walk_state->op_info->name, | ||
863 | walk_state->op_info->flags)); | ||
864 | |||
865 | /* Executing a type1 or type2 opcode outside of a method */ | ||
866 | |||
867 | status = acpi_ds_exec_end_op(walk_state); | ||
868 | return_ACPI_STATUS(status); | ||
869 | } | ||
870 | #endif | ||
871 | #endif | ||
872 | return_ACPI_STATUS(AE_OK); | 845 | return_ACPI_STATUS(AE_OK); |
873 | } | 846 | } |
874 | 847 | ||
diff --git a/drivers/acpi/acpica/dswstate.c b/drivers/acpi/acpica/dswstate.c index 40f92bf7dce5..e46c821cf572 100644 --- a/drivers/acpi/acpica/dswstate.c +++ b/drivers/acpi/acpica/dswstate.c | |||
@@ -102,7 +102,7 @@ acpi_ds_result_pop(union acpi_operand_object **object, | |||
102 | /* Return object of the top element and clean that top element result stack */ | 102 | /* Return object of the top element and clean that top element result stack */ |
103 | 103 | ||
104 | walk_state->result_count--; | 104 | walk_state->result_count--; |
105 | index = walk_state->result_count % ACPI_RESULTS_FRAME_OBJ_NUM; | 105 | index = (u32)walk_state->result_count % ACPI_RESULTS_FRAME_OBJ_NUM; |
106 | 106 | ||
107 | *object = state->results.obj_desc[index]; | 107 | *object = state->results.obj_desc[index]; |
108 | if (!*object) { | 108 | if (!*object) { |
@@ -186,7 +186,7 @@ acpi_ds_result_push(union acpi_operand_object * object, | |||
186 | 186 | ||
187 | /* Assign the address of object to the top free element of result stack */ | 187 | /* Assign the address of object to the top free element of result stack */ |
188 | 188 | ||
189 | index = walk_state->result_count % ACPI_RESULTS_FRAME_OBJ_NUM; | 189 | index = (u32)walk_state->result_count % ACPI_RESULTS_FRAME_OBJ_NUM; |
190 | state->results.obj_desc[index] = object; | 190 | state->results.obj_desc[index] = object; |
191 | walk_state->result_count++; | 191 | walk_state->result_count++; |
192 | 192 | ||
diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c index b9d8ee69ca6c..afacf4416c73 100644 --- a/drivers/acpi/acpica/evgpe.c +++ b/drivers/acpi/acpica/evgpe.c | |||
@@ -424,8 +424,8 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list) | |||
424 | /* Read the Status Register */ | 424 | /* Read the Status Register */ |
425 | 425 | ||
426 | status = | 426 | status = |
427 | acpi_read(&status_reg, | 427 | acpi_hw_read(&status_reg, |
428 | &gpe_register_info->status_address); | 428 | &gpe_register_info->status_address); |
429 | if (ACPI_FAILURE(status)) { | 429 | if (ACPI_FAILURE(status)) { |
430 | goto unlock_and_exit; | 430 | goto unlock_and_exit; |
431 | } | 431 | } |
@@ -433,8 +433,8 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list) | |||
433 | /* Read the Enable Register */ | 433 | /* Read the Enable Register */ |
434 | 434 | ||
435 | status = | 435 | status = |
436 | acpi_read(&enable_reg, | 436 | acpi_hw_read(&enable_reg, |
437 | &gpe_register_info->enable_address); | 437 | &gpe_register_info->enable_address); |
438 | if (ACPI_FAILURE(status)) { | 438 | if (ACPI_FAILURE(status)) { |
439 | goto unlock_and_exit; | 439 | goto unlock_and_exit; |
440 | } | 440 | } |
diff --git a/drivers/acpi/acpica/evgpeblk.c b/drivers/acpi/acpica/evgpeblk.c index 7b3463639422..a60aaa7635f3 100644 --- a/drivers/acpi/acpica/evgpeblk.c +++ b/drivers/acpi/acpica/evgpeblk.c | |||
@@ -843,14 +843,14 @@ acpi_ev_create_gpe_info_blocks(struct acpi_gpe_block_info *gpe_block) | |||
843 | 843 | ||
844 | /* Disable all GPEs within this register */ | 844 | /* Disable all GPEs within this register */ |
845 | 845 | ||
846 | status = acpi_write(0x00, &this_register->enable_address); | 846 | status = acpi_hw_write(0x00, &this_register->enable_address); |
847 | if (ACPI_FAILURE(status)) { | 847 | if (ACPI_FAILURE(status)) { |
848 | goto error_exit; | 848 | goto error_exit; |
849 | } | 849 | } |
850 | 850 | ||
851 | /* Clear any pending GPE events within this register */ | 851 | /* Clear any pending GPE events within this register */ |
852 | 852 | ||
853 | status = acpi_write(0xFF, &this_register->status_address); | 853 | status = acpi_hw_write(0xFF, &this_register->status_address); |
854 | if (ACPI_FAILURE(status)) { | 854 | if (ACPI_FAILURE(status)) { |
855 | goto error_exit; | 855 | goto error_exit; |
856 | } | 856 | } |
diff --git a/drivers/acpi/acpica/evregion.c b/drivers/acpi/acpica/evregion.c index 538d63264555..98c7f9c62653 100644 --- a/drivers/acpi/acpica/evregion.c +++ b/drivers/acpi/acpica/evregion.c | |||
@@ -275,7 +275,7 @@ acpi_ev_execute_reg_method(union acpi_operand_object *region_obj, u32 function) | |||
275 | * | 275 | * |
276 | * PARAMETERS: region_obj - Internal region object | 276 | * PARAMETERS: region_obj - Internal region object |
277 | * Function - Read or Write operation | 277 | * Function - Read or Write operation |
278 | * Address - Where in the space to read or write | 278 | * region_offset - Where in the region to read or write |
279 | * bit_width - Field width in bits (8, 16, 32, or 64) | 279 | * bit_width - Field width in bits (8, 16, 32, or 64) |
280 | * Value - Pointer to in or out value, must be | 280 | * Value - Pointer to in or out value, must be |
281 | * full 64-bit acpi_integer | 281 | * full 64-bit acpi_integer |
@@ -290,7 +290,7 @@ acpi_ev_execute_reg_method(union acpi_operand_object *region_obj, u32 function) | |||
290 | acpi_status | 290 | acpi_status |
291 | acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, | 291 | acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, |
292 | u32 function, | 292 | u32 function, |
293 | acpi_physical_address address, | 293 | u32 region_offset, |
294 | u32 bit_width, acpi_integer * value) | 294 | u32 bit_width, acpi_integer * value) |
295 | { | 295 | { |
296 | acpi_status status; | 296 | acpi_status status; |
@@ -396,7 +396,8 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, | |||
396 | ACPI_DEBUG_PRINT((ACPI_DB_OPREGION, | 396 | ACPI_DEBUG_PRINT((ACPI_DB_OPREGION, |
397 | "Handler %p (@%p) Address %8.8X%8.8X [%s]\n", | 397 | "Handler %p (@%p) Address %8.8X%8.8X [%s]\n", |
398 | ®ion_obj->region.handler->address_space, handler, | 398 | ®ion_obj->region.handler->address_space, handler, |
399 | ACPI_FORMAT_NATIVE_UINT(address), | 399 | ACPI_FORMAT_NATIVE_UINT(region_obj->region.address + |
400 | region_offset), | ||
400 | acpi_ut_get_region_name(region_obj->region. | 401 | acpi_ut_get_region_name(region_obj->region. |
401 | space_id))); | 402 | space_id))); |
402 | 403 | ||
@@ -412,8 +413,9 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, | |||
412 | 413 | ||
413 | /* Call the handler */ | 414 | /* Call the handler */ |
414 | 415 | ||
415 | status = handler(function, address, bit_width, value, | 416 | status = handler(function, |
416 | handler_desc->address_space.context, | 417 | (region_obj->region.address + region_offset), |
418 | bit_width, value, handler_desc->address_space.context, | ||
417 | region_obj2->extra.region_context); | 419 | region_obj2->extra.region_context); |
418 | 420 | ||
419 | if (ACPI_FAILURE(status)) { | 421 | if (ACPI_FAILURE(status)) { |
diff --git a/drivers/acpi/acpica/evrgnini.c b/drivers/acpi/acpica/evrgnini.c index 284a7becbe96..cf29c4953028 100644 --- a/drivers/acpi/acpica/evrgnini.c +++ b/drivers/acpi/acpica/evrgnini.c | |||
@@ -50,8 +50,6 @@ | |||
50 | ACPI_MODULE_NAME("evrgnini") | 50 | ACPI_MODULE_NAME("evrgnini") |
51 | 51 | ||
52 | /* Local prototypes */ | 52 | /* Local prototypes */ |
53 | static u8 acpi_ev_match_pci_root_bridge(char *id); | ||
54 | |||
55 | static u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node); | 53 | static u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node); |
56 | 54 | ||
57 | /******************************************************************************* | 55 | /******************************************************************************* |
@@ -332,37 +330,6 @@ acpi_ev_pci_config_region_setup(acpi_handle handle, | |||
332 | 330 | ||
333 | /******************************************************************************* | 331 | /******************************************************************************* |
334 | * | 332 | * |
335 | * FUNCTION: acpi_ev_match_pci_root_bridge | ||
336 | * | ||
337 | * PARAMETERS: Id - The HID/CID in string format | ||
338 | * | ||
339 | * RETURN: TRUE if the Id is a match for a PCI/PCI-Express Root Bridge | ||
340 | * | ||
341 | * DESCRIPTION: Determine if the input ID is a PCI Root Bridge ID. | ||
342 | * | ||
343 | ******************************************************************************/ | ||
344 | |||
345 | static u8 acpi_ev_match_pci_root_bridge(char *id) | ||
346 | { | ||
347 | |||
348 | /* | ||
349 | * Check if this is a PCI root. | ||
350 | * ACPI 3.0+: check for a PCI Express root also. | ||
351 | */ | ||
352 | if (!(ACPI_STRNCMP(id, | ||
353 | PCI_ROOT_HID_STRING, | ||
354 | sizeof(PCI_ROOT_HID_STRING))) || | ||
355 | !(ACPI_STRNCMP(id, | ||
356 | PCI_EXPRESS_ROOT_HID_STRING, | ||
357 | sizeof(PCI_EXPRESS_ROOT_HID_STRING)))) { | ||
358 | return (TRUE); | ||
359 | } | ||
360 | |||
361 | return (FALSE); | ||
362 | } | ||
363 | |||
364 | /******************************************************************************* | ||
365 | * | ||
366 | * FUNCTION: acpi_ev_is_pci_root_bridge | 333 | * FUNCTION: acpi_ev_is_pci_root_bridge |
367 | * | 334 | * |
368 | * PARAMETERS: Node - Device node being examined | 335 | * PARAMETERS: Node - Device node being examined |
@@ -377,9 +344,10 @@ static u8 acpi_ev_match_pci_root_bridge(char *id) | |||
377 | static u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node) | 344 | static u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node) |
378 | { | 345 | { |
379 | acpi_status status; | 346 | acpi_status status; |
380 | struct acpica_device_id hid; | 347 | struct acpica_device_id *hid; |
381 | struct acpi_compatible_id_list *cid; | 348 | struct acpica_device_id_list *cid; |
382 | u32 i; | 349 | u32 i; |
350 | u8 match; | ||
383 | 351 | ||
384 | /* Get the _HID and check for a PCI Root Bridge */ | 352 | /* Get the _HID and check for a PCI Root Bridge */ |
385 | 353 | ||
@@ -388,7 +356,10 @@ static u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node) | |||
388 | return (FALSE); | 356 | return (FALSE); |
389 | } | 357 | } |
390 | 358 | ||
391 | if (acpi_ev_match_pci_root_bridge(hid.value)) { | 359 | match = acpi_ut_is_pci_root_bridge(hid->string); |
360 | ACPI_FREE(hid); | ||
361 | |||
362 | if (match) { | ||
392 | return (TRUE); | 363 | return (TRUE); |
393 | } | 364 | } |
394 | 365 | ||
@@ -402,7 +373,7 @@ static u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node) | |||
402 | /* Check all _CIDs in the returned list */ | 373 | /* Check all _CIDs in the returned list */ |
403 | 374 | ||
404 | for (i = 0; i < cid->count; i++) { | 375 | for (i = 0; i < cid->count; i++) { |
405 | if (acpi_ev_match_pci_root_bridge(cid->id[i].value)) { | 376 | if (acpi_ut_is_pci_root_bridge(cid->ids[i].string)) { |
406 | ACPI_FREE(cid); | 377 | ACPI_FREE(cid); |
407 | return (TRUE); | 378 | return (TRUE); |
408 | } | 379 | } |
diff --git a/drivers/acpi/acpica/evxfevnt.c b/drivers/acpi/acpica/evxfevnt.c index d0a080747ec3..4721f58fe42c 100644 --- a/drivers/acpi/acpica/evxfevnt.c +++ b/drivers/acpi/acpica/evxfevnt.c | |||
@@ -51,7 +51,7 @@ | |||
51 | ACPI_MODULE_NAME("evxfevnt") | 51 | ACPI_MODULE_NAME("evxfevnt") |
52 | 52 | ||
53 | /* Local prototypes */ | 53 | /* Local prototypes */ |
54 | acpi_status | 54 | static acpi_status |
55 | acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info, | 55 | acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info, |
56 | struct acpi_gpe_block_info *gpe_block, void *context); | 56 | struct acpi_gpe_block_info *gpe_block, void *context); |
57 | 57 | ||
@@ -785,7 +785,7 @@ ACPI_EXPORT_SYMBOL(acpi_get_gpe_device) | |||
785 | * block device. NULL if the GPE is one of the FADT-defined GPEs. | 785 | * block device. NULL if the GPE is one of the FADT-defined GPEs. |
786 | * | 786 | * |
787 | ******************************************************************************/ | 787 | ******************************************************************************/ |
788 | acpi_status | 788 | static acpi_status |
789 | acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info, | 789 | acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info, |
790 | struct acpi_gpe_block_info *gpe_block, void *context) | 790 | struct acpi_gpe_block_info *gpe_block, void *context) |
791 | { | 791 | { |
diff --git a/drivers/acpi/acpica/exconfig.c b/drivers/acpi/acpica/exconfig.c index 3deb20a126b2..24afef81af39 100644 --- a/drivers/acpi/acpica/exconfig.c +++ b/drivers/acpi/acpica/exconfig.c | |||
@@ -47,6 +47,7 @@ | |||
47 | #include "acnamesp.h" | 47 | #include "acnamesp.h" |
48 | #include "actables.h" | 48 | #include "actables.h" |
49 | #include "acdispat.h" | 49 | #include "acdispat.h" |
50 | #include "acevents.h" | ||
50 | 51 | ||
51 | #define _COMPONENT ACPI_EXECUTER | 52 | #define _COMPONENT ACPI_EXECUTER |
52 | ACPI_MODULE_NAME("exconfig") | 53 | ACPI_MODULE_NAME("exconfig") |
@@ -57,6 +58,10 @@ acpi_ex_add_table(u32 table_index, | |||
57 | struct acpi_namespace_node *parent_node, | 58 | struct acpi_namespace_node *parent_node, |
58 | union acpi_operand_object **ddb_handle); | 59 | union acpi_operand_object **ddb_handle); |
59 | 60 | ||
61 | static acpi_status | ||
62 | acpi_ex_region_read(union acpi_operand_object *obj_desc, | ||
63 | u32 length, u8 *buffer); | ||
64 | |||
60 | /******************************************************************************* | 65 | /******************************************************************************* |
61 | * | 66 | * |
62 | * FUNCTION: acpi_ex_add_table | 67 | * FUNCTION: acpi_ex_add_table |
@@ -91,6 +96,7 @@ acpi_ex_add_table(u32 table_index, | |||
91 | 96 | ||
92 | /* Init the table handle */ | 97 | /* Init the table handle */ |
93 | 98 | ||
99 | obj_desc->common.flags |= AOPOBJ_DATA_VALID; | ||
94 | obj_desc->reference.class = ACPI_REFCLASS_TABLE; | 100 | obj_desc->reference.class = ACPI_REFCLASS_TABLE; |
95 | *ddb_handle = obj_desc; | 101 | *ddb_handle = obj_desc; |
96 | 102 | ||
@@ -104,8 +110,15 @@ acpi_ex_add_table(u32 table_index, | |||
104 | if (ACPI_FAILURE(status)) { | 110 | if (ACPI_FAILURE(status)) { |
105 | acpi_ut_remove_reference(obj_desc); | 111 | acpi_ut_remove_reference(obj_desc); |
106 | *ddb_handle = NULL; | 112 | *ddb_handle = NULL; |
113 | return_ACPI_STATUS(status); | ||
107 | } | 114 | } |
108 | 115 | ||
116 | /* Execute any module-level code that was found in the table */ | ||
117 | |||
118 | acpi_ex_exit_interpreter(); | ||
119 | acpi_ns_exec_module_code_list(); | ||
120 | acpi_ex_enter_interpreter(); | ||
121 | |||
109 | return_ACPI_STATUS(status); | 122 | return_ACPI_STATUS(status); |
110 | } | 123 | } |
111 | 124 | ||
@@ -229,6 +242,8 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state, | |||
229 | walk_state); | 242 | walk_state); |
230 | if (ACPI_FAILURE(status)) { | 243 | if (ACPI_FAILURE(status)) { |
231 | (void)acpi_ex_unload_table(ddb_handle); | 244 | (void)acpi_ex_unload_table(ddb_handle); |
245 | |||
246 | acpi_ut_remove_reference(ddb_handle); | ||
232 | return_ACPI_STATUS(status); | 247 | return_ACPI_STATUS(status); |
233 | } | 248 | } |
234 | } | 249 | } |
@@ -254,6 +269,47 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state, | |||
254 | 269 | ||
255 | /******************************************************************************* | 270 | /******************************************************************************* |
256 | * | 271 | * |
272 | * FUNCTION: acpi_ex_region_read | ||
273 | * | ||
274 | * PARAMETERS: obj_desc - Region descriptor | ||
275 | * Length - Number of bytes to read | ||
276 | * Buffer - Pointer to where to put the data | ||
277 | * | ||
278 | * RETURN: Status | ||
279 | * | ||
280 | * DESCRIPTION: Read data from an operation region. The read starts from the | ||
281 | * beginning of the region. | ||
282 | * | ||
283 | ******************************************************************************/ | ||
284 | |||
285 | static acpi_status | ||
286 | acpi_ex_region_read(union acpi_operand_object *obj_desc, u32 length, u8 *buffer) | ||
287 | { | ||
288 | acpi_status status; | ||
289 | acpi_integer value; | ||
290 | u32 region_offset = 0; | ||
291 | u32 i; | ||
292 | |||
293 | /* Bytewise reads */ | ||
294 | |||
295 | for (i = 0; i < length; i++) { | ||
296 | status = acpi_ev_address_space_dispatch(obj_desc, ACPI_READ, | ||
297 | region_offset, 8, | ||
298 | &value); | ||
299 | if (ACPI_FAILURE(status)) { | ||
300 | return status; | ||
301 | } | ||
302 | |||
303 | *buffer = (u8)value; | ||
304 | buffer++; | ||
305 | region_offset++; | ||
306 | } | ||
307 | |||
308 | return AE_OK; | ||
309 | } | ||
310 | |||
311 | /******************************************************************************* | ||
312 | * | ||
257 | * FUNCTION: acpi_ex_load_op | 313 | * FUNCTION: acpi_ex_load_op |
258 | * | 314 | * |
259 | * PARAMETERS: obj_desc - Region or Buffer/Field where the table will be | 315 | * PARAMETERS: obj_desc - Region or Buffer/Field where the table will be |
@@ -314,18 +370,23 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, | |||
314 | } | 370 | } |
315 | } | 371 | } |
316 | 372 | ||
317 | /* | 373 | /* Get the table header first so we can get the table length */ |
318 | * Map the table header and get the actual table length. The region | 374 | |
319 | * length is not guaranteed to be the same as the table length. | 375 | table = ACPI_ALLOCATE(sizeof(struct acpi_table_header)); |
320 | */ | ||
321 | table = acpi_os_map_memory(obj_desc->region.address, | ||
322 | sizeof(struct acpi_table_header)); | ||
323 | if (!table) { | 376 | if (!table) { |
324 | return_ACPI_STATUS(AE_NO_MEMORY); | 377 | return_ACPI_STATUS(AE_NO_MEMORY); |
325 | } | 378 | } |
326 | 379 | ||
380 | status = | ||
381 | acpi_ex_region_read(obj_desc, | ||
382 | sizeof(struct acpi_table_header), | ||
383 | ACPI_CAST_PTR(u8, table)); | ||
327 | length = table->length; | 384 | length = table->length; |
328 | acpi_os_unmap_memory(table, sizeof(struct acpi_table_header)); | 385 | ACPI_FREE(table); |
386 | |||
387 | if (ACPI_FAILURE(status)) { | ||
388 | return_ACPI_STATUS(status); | ||
389 | } | ||
329 | 390 | ||
330 | /* Must have at least an ACPI table header */ | 391 | /* Must have at least an ACPI table header */ |
331 | 392 | ||
@@ -334,10 +395,19 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, | |||
334 | } | 395 | } |
335 | 396 | ||
336 | /* | 397 | /* |
337 | * The memory region is not guaranteed to remain stable and we must | 398 | * The original implementation simply mapped the table, with no copy. |
338 | * copy the table to a local buffer. For example, the memory region | 399 | * However, the memory region is not guaranteed to remain stable and |
339 | * is corrupted after suspend on some machines. Dynamically loaded | 400 | * we must copy the table to a local buffer. For example, the memory |
340 | * tables are usually small, so this overhead is minimal. | 401 | * region is corrupted after suspend on some machines. Dynamically |
402 | * loaded tables are usually small, so this overhead is minimal. | ||
403 | * | ||
404 | * The latest implementation (5/2009) does not use a mapping at all. | ||
405 | * We use the low-level operation region interface to read the table | ||
406 | * instead of the obvious optimization of using a direct mapping. | ||
407 | * This maintains a consistent use of operation regions across the | ||
408 | * entire subsystem. This is important if additional processing must | ||
409 | * be performed in the (possibly user-installed) operation region | ||
410 | * handler. For example, acpi_exec and ASLTS depend on this. | ||
341 | */ | 411 | */ |
342 | 412 | ||
343 | /* Allocate a buffer for the table */ | 413 | /* Allocate a buffer for the table */ |
@@ -347,17 +417,16 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, | |||
347 | return_ACPI_STATUS(AE_NO_MEMORY); | 417 | return_ACPI_STATUS(AE_NO_MEMORY); |
348 | } | 418 | } |
349 | 419 | ||
350 | /* Map the entire table and copy it */ | 420 | /* Read the entire table */ |
351 | 421 | ||
352 | table = acpi_os_map_memory(obj_desc->region.address, length); | 422 | status = acpi_ex_region_read(obj_desc, length, |
353 | if (!table) { | 423 | ACPI_CAST_PTR(u8, |
424 | table_desc.pointer)); | ||
425 | if (ACPI_FAILURE(status)) { | ||
354 | ACPI_FREE(table_desc.pointer); | 426 | ACPI_FREE(table_desc.pointer); |
355 | return_ACPI_STATUS(AE_NO_MEMORY); | 427 | return_ACPI_STATUS(status); |
356 | } | 428 | } |
357 | 429 | ||
358 | ACPI_MEMCPY(table_desc.pointer, table, length); | ||
359 | acpi_os_unmap_memory(table, length); | ||
360 | |||
361 | table_desc.address = obj_desc->region.address; | 430 | table_desc.address = obj_desc->region.address; |
362 | break; | 431 | break; |
363 | 432 | ||
@@ -454,6 +523,10 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, | |||
454 | return_ACPI_STATUS(status); | 523 | return_ACPI_STATUS(status); |
455 | } | 524 | } |
456 | 525 | ||
526 | /* Remove the reference by added by acpi_ex_store above */ | ||
527 | |||
528 | acpi_ut_remove_reference(ddb_handle); | ||
529 | |||
457 | /* Invoke table handler if present */ | 530 | /* Invoke table handler if present */ |
458 | 531 | ||
459 | if (acpi_gbl_table_handler) { | 532 | if (acpi_gbl_table_handler) { |
@@ -495,13 +568,18 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle) | |||
495 | 568 | ||
496 | /* | 569 | /* |
497 | * Validate the handle | 570 | * Validate the handle |
498 | * Although the handle is partially validated in acpi_ex_reconfiguration(), | 571 | * Although the handle is partially validated in acpi_ex_reconfiguration() |
499 | * when it calls acpi_ex_resolve_operands(), the handle is more completely | 572 | * when it calls acpi_ex_resolve_operands(), the handle is more completely |
500 | * validated here. | 573 | * validated here. |
574 | * | ||
575 | * Handle must be a valid operand object of type reference. Also, the | ||
576 | * ddb_handle must still be marked valid (table has not been previously | ||
577 | * unloaded) | ||
501 | */ | 578 | */ |
502 | if ((!ddb_handle) || | 579 | if ((!ddb_handle) || |
503 | (ACPI_GET_DESCRIPTOR_TYPE(ddb_handle) != ACPI_DESC_TYPE_OPERAND) || | 580 | (ACPI_GET_DESCRIPTOR_TYPE(ddb_handle) != ACPI_DESC_TYPE_OPERAND) || |
504 | (ddb_handle->common.type != ACPI_TYPE_LOCAL_REFERENCE)) { | 581 | (ddb_handle->common.type != ACPI_TYPE_LOCAL_REFERENCE) || |
582 | (!(ddb_handle->common.flags & AOPOBJ_DATA_VALID))) { | ||
505 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 583 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
506 | } | 584 | } |
507 | 585 | ||
@@ -509,6 +587,12 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle) | |||
509 | 587 | ||
510 | table_index = table_desc->reference.value; | 588 | table_index = table_desc->reference.value; |
511 | 589 | ||
590 | /* Ensure the table is still loaded */ | ||
591 | |||
592 | if (!acpi_tb_is_table_loaded(table_index)) { | ||
593 | return_ACPI_STATUS(AE_NOT_EXIST); | ||
594 | } | ||
595 | |||
512 | /* Invoke table handler if present */ | 596 | /* Invoke table handler if present */ |
513 | 597 | ||
514 | if (acpi_gbl_table_handler) { | 598 | if (acpi_gbl_table_handler) { |
@@ -530,8 +614,10 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle) | |||
530 | (void)acpi_tb_release_owner_id(table_index); | 614 | (void)acpi_tb_release_owner_id(table_index); |
531 | acpi_tb_set_table_loaded_flag(table_index, FALSE); | 615 | acpi_tb_set_table_loaded_flag(table_index, FALSE); |
532 | 616 | ||
533 | /* Table unloaded, remove a reference to the ddb_handle object */ | 617 | /* |
534 | 618 | * Invalidate the handle. We do this because the handle may be stored | |
535 | acpi_ut_remove_reference(ddb_handle); | 619 | * in a named object and may not be actually deleted until much later. |
620 | */ | ||
621 | ddb_handle->common.flags &= ~AOPOBJ_DATA_VALID; | ||
536 | return_ACPI_STATUS(AE_OK); | 622 | return_ACPI_STATUS(AE_OK); |
537 | } | 623 | } |
diff --git a/drivers/acpi/acpica/excreate.c b/drivers/acpi/acpica/excreate.c index a57ad2564ab0..02b25d233d99 100644 --- a/drivers/acpi/acpica/excreate.c +++ b/drivers/acpi/acpica/excreate.c | |||
@@ -502,7 +502,7 @@ acpi_ex_create_method(u8 * aml_start, | |||
502 | * ACPI 2.0: sync_level = sync_level in method declaration | 502 | * ACPI 2.0: sync_level = sync_level in method declaration |
503 | */ | 503 | */ |
504 | obj_desc->method.sync_level = (u8) | 504 | obj_desc->method.sync_level = (u8) |
505 | ((method_flags & AML_METHOD_SYNCH_LEVEL) >> 4); | 505 | ((method_flags & AML_METHOD_SYNC_LEVEL) >> 4); |
506 | } | 506 | } |
507 | 507 | ||
508 | /* Attach the new object to the method Node */ | 508 | /* Attach the new object to the method Node */ |
diff --git a/drivers/acpi/acpica/exdump.c b/drivers/acpi/acpica/exdump.c index 89d141fdae0b..de3446372ddc 100644 --- a/drivers/acpi/acpica/exdump.c +++ b/drivers/acpi/acpica/exdump.c | |||
@@ -120,9 +120,11 @@ static struct acpi_exdump_info acpi_ex_dump_event[2] = { | |||
120 | {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(event.os_semaphore), "OsSemaphore"} | 120 | {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(event.os_semaphore), "OsSemaphore"} |
121 | }; | 121 | }; |
122 | 122 | ||
123 | static struct acpi_exdump_info acpi_ex_dump_method[8] = { | 123 | static struct acpi_exdump_info acpi_ex_dump_method[9] = { |
124 | {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_method), NULL}, | 124 | {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_method), NULL}, |
125 | {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.param_count), "ParamCount"}, | 125 | {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.method_flags), "Method Flags"}, |
126 | {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.param_count), | ||
127 | "Parameter Count"}, | ||
126 | {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.sync_level), "Sync Level"}, | 128 | {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.sync_level), "Sync Level"}, |
127 | {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(method.mutex), "Mutex"}, | 129 | {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(method.mutex), "Mutex"}, |
128 | {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.owner_id), "Owner Id"}, | 130 | {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.owner_id), "Owner Id"}, |
@@ -416,9 +418,9 @@ acpi_ex_dump_object(union acpi_operand_object *obj_desc, | |||
416 | case ACPI_EXD_REFERENCE: | 418 | case ACPI_EXD_REFERENCE: |
417 | 419 | ||
418 | acpi_ex_out_string("Class Name", | 420 | acpi_ex_out_string("Class Name", |
419 | (char *) | 421 | ACPI_CAST_PTR(char, |
420 | acpi_ut_get_reference_name | 422 | acpi_ut_get_reference_name |
421 | (obj_desc)); | 423 | (obj_desc))); |
422 | acpi_ex_dump_reference_obj(obj_desc); | 424 | acpi_ex_dump_reference_obj(obj_desc); |
423 | break; | 425 | break; |
424 | 426 | ||
diff --git a/drivers/acpi/acpica/exfield.c b/drivers/acpi/acpica/exfield.c index 546dcdd86785..0b33d6c887b9 100644 --- a/drivers/acpi/acpica/exfield.c +++ b/drivers/acpi/acpica/exfield.c | |||
@@ -72,6 +72,7 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state, | |||
72 | union acpi_operand_object *buffer_desc; | 72 | union acpi_operand_object *buffer_desc; |
73 | acpi_size length; | 73 | acpi_size length; |
74 | void *buffer; | 74 | void *buffer; |
75 | u32 function; | ||
75 | 76 | ||
76 | ACPI_FUNCTION_TRACE_PTR(ex_read_data_from_field, obj_desc); | 77 | ACPI_FUNCTION_TRACE_PTR(ex_read_data_from_field, obj_desc); |
77 | 78 | ||
@@ -97,13 +98,27 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state, | |||
97 | } | 98 | } |
98 | } else if ((obj_desc->common.type == ACPI_TYPE_LOCAL_REGION_FIELD) && | 99 | } else if ((obj_desc->common.type == ACPI_TYPE_LOCAL_REGION_FIELD) && |
99 | (obj_desc->field.region_obj->region.space_id == | 100 | (obj_desc->field.region_obj->region.space_id == |
100 | ACPI_ADR_SPACE_SMBUS)) { | 101 | ACPI_ADR_SPACE_SMBUS |
102 | || obj_desc->field.region_obj->region.space_id == | ||
103 | ACPI_ADR_SPACE_IPMI)) { | ||
101 | /* | 104 | /* |
102 | * This is an SMBus read. We must create a buffer to hold the data | 105 | * This is an SMBus or IPMI read. We must create a buffer to hold |
103 | * and directly access the region handler. | 106 | * the data and then directly access the region handler. |
107 | * | ||
108 | * Note: Smbus protocol value is passed in upper 16-bits of Function | ||
104 | */ | 109 | */ |
105 | buffer_desc = | 110 | if (obj_desc->field.region_obj->region.space_id == |
106 | acpi_ut_create_buffer_object(ACPI_SMBUS_BUFFER_SIZE); | 111 | ACPI_ADR_SPACE_SMBUS) { |
112 | length = ACPI_SMBUS_BUFFER_SIZE; | ||
113 | function = | ||
114 | ACPI_READ | (obj_desc->field.attribute << 16); | ||
115 | } else { /* IPMI */ | ||
116 | |||
117 | length = ACPI_IPMI_BUFFER_SIZE; | ||
118 | function = ACPI_READ; | ||
119 | } | ||
120 | |||
121 | buffer_desc = acpi_ut_create_buffer_object(length); | ||
107 | if (!buffer_desc) { | 122 | if (!buffer_desc) { |
108 | return_ACPI_STATUS(AE_NO_MEMORY); | 123 | return_ACPI_STATUS(AE_NO_MEMORY); |
109 | } | 124 | } |
@@ -112,16 +127,13 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state, | |||
112 | 127 | ||
113 | acpi_ex_acquire_global_lock(obj_desc->common_field.field_flags); | 128 | acpi_ex_acquire_global_lock(obj_desc->common_field.field_flags); |
114 | 129 | ||
115 | /* | 130 | /* Call the region handler for the read */ |
116 | * Perform the read. | 131 | |
117 | * Note: Smbus protocol value is passed in upper 16-bits of Function | ||
118 | */ | ||
119 | status = acpi_ex_access_region(obj_desc, 0, | 132 | status = acpi_ex_access_region(obj_desc, 0, |
120 | ACPI_CAST_PTR(acpi_integer, | 133 | ACPI_CAST_PTR(acpi_integer, |
121 | buffer_desc-> | 134 | buffer_desc-> |
122 | buffer.pointer), | 135 | buffer.pointer), |
123 | ACPI_READ | (obj_desc->field. | 136 | function); |
124 | attribute << 16)); | ||
125 | acpi_ex_release_global_lock(obj_desc->common_field.field_flags); | 137 | acpi_ex_release_global_lock(obj_desc->common_field.field_flags); |
126 | goto exit; | 138 | goto exit; |
127 | } | 139 | } |
@@ -212,6 +224,7 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc, | |||
212 | u32 length; | 224 | u32 length; |
213 | void *buffer; | 225 | void *buffer; |
214 | union acpi_operand_object *buffer_desc; | 226 | union acpi_operand_object *buffer_desc; |
227 | u32 function; | ||
215 | 228 | ||
216 | ACPI_FUNCTION_TRACE_PTR(ex_write_data_to_field, obj_desc); | 229 | ACPI_FUNCTION_TRACE_PTR(ex_write_data_to_field, obj_desc); |
217 | 230 | ||
@@ -234,39 +247,56 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc, | |||
234 | } | 247 | } |
235 | } else if ((obj_desc->common.type == ACPI_TYPE_LOCAL_REGION_FIELD) && | 248 | } else if ((obj_desc->common.type == ACPI_TYPE_LOCAL_REGION_FIELD) && |
236 | (obj_desc->field.region_obj->region.space_id == | 249 | (obj_desc->field.region_obj->region.space_id == |
237 | ACPI_ADR_SPACE_SMBUS)) { | 250 | ACPI_ADR_SPACE_SMBUS |
251 | || obj_desc->field.region_obj->region.space_id == | ||
252 | ACPI_ADR_SPACE_IPMI)) { | ||
238 | /* | 253 | /* |
239 | * This is an SMBus write. We will bypass the entire field mechanism | 254 | * This is an SMBus or IPMI write. We will bypass the entire field |
240 | * and handoff the buffer directly to the handler. | 255 | * mechanism and handoff the buffer directly to the handler. For |
256 | * these address spaces, the buffer is bi-directional; on a write, | ||
257 | * return data is returned in the same buffer. | ||
258 | * | ||
259 | * Source must be a buffer of sufficient size: | ||
260 | * ACPI_SMBUS_BUFFER_SIZE or ACPI_IPMI_BUFFER_SIZE. | ||
241 | * | 261 | * |
242 | * Source must be a buffer of sufficient size (ACPI_SMBUS_BUFFER_SIZE). | 262 | * Note: SMBus protocol type is passed in upper 16-bits of Function |
243 | */ | 263 | */ |
244 | if (source_desc->common.type != ACPI_TYPE_BUFFER) { | 264 | if (source_desc->common.type != ACPI_TYPE_BUFFER) { |
245 | ACPI_ERROR((AE_INFO, | 265 | ACPI_ERROR((AE_INFO, |
246 | "SMBus write requires Buffer, found type %s", | 266 | "SMBus or IPMI write requires Buffer, found type %s", |
247 | acpi_ut_get_object_type_name(source_desc))); | 267 | acpi_ut_get_object_type_name(source_desc))); |
248 | 268 | ||
249 | return_ACPI_STATUS(AE_AML_OPERAND_TYPE); | 269 | return_ACPI_STATUS(AE_AML_OPERAND_TYPE); |
250 | } | 270 | } |
251 | 271 | ||
252 | if (source_desc->buffer.length < ACPI_SMBUS_BUFFER_SIZE) { | 272 | if (obj_desc->field.region_obj->region.space_id == |
273 | ACPI_ADR_SPACE_SMBUS) { | ||
274 | length = ACPI_SMBUS_BUFFER_SIZE; | ||
275 | function = | ||
276 | ACPI_WRITE | (obj_desc->field.attribute << 16); | ||
277 | } else { /* IPMI */ | ||
278 | |||
279 | length = ACPI_IPMI_BUFFER_SIZE; | ||
280 | function = ACPI_WRITE; | ||
281 | } | ||
282 | |||
283 | if (source_desc->buffer.length < length) { | ||
253 | ACPI_ERROR((AE_INFO, | 284 | ACPI_ERROR((AE_INFO, |
254 | "SMBus write requires Buffer of length %X, found length %X", | 285 | "SMBus or IPMI write requires Buffer of length %X, found length %X", |
255 | ACPI_SMBUS_BUFFER_SIZE, | 286 | length, source_desc->buffer.length)); |
256 | source_desc->buffer.length)); | ||
257 | 287 | ||
258 | return_ACPI_STATUS(AE_AML_BUFFER_LIMIT); | 288 | return_ACPI_STATUS(AE_AML_BUFFER_LIMIT); |
259 | } | 289 | } |
260 | 290 | ||
261 | buffer_desc = | 291 | /* Create the bi-directional buffer */ |
262 | acpi_ut_create_buffer_object(ACPI_SMBUS_BUFFER_SIZE); | 292 | |
293 | buffer_desc = acpi_ut_create_buffer_object(length); | ||
263 | if (!buffer_desc) { | 294 | if (!buffer_desc) { |
264 | return_ACPI_STATUS(AE_NO_MEMORY); | 295 | return_ACPI_STATUS(AE_NO_MEMORY); |
265 | } | 296 | } |
266 | 297 | ||
267 | buffer = buffer_desc->buffer.pointer; | 298 | buffer = buffer_desc->buffer.pointer; |
268 | ACPI_MEMCPY(buffer, source_desc->buffer.pointer, | 299 | ACPI_MEMCPY(buffer, source_desc->buffer.pointer, length); |
269 | ACPI_SMBUS_BUFFER_SIZE); | ||
270 | 300 | ||
271 | /* Lock entire transaction if requested */ | 301 | /* Lock entire transaction if requested */ |
272 | 302 | ||
@@ -275,12 +305,10 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc, | |||
275 | /* | 305 | /* |
276 | * Perform the write (returns status and perhaps data in the | 306 | * Perform the write (returns status and perhaps data in the |
277 | * same buffer) | 307 | * same buffer) |
278 | * Note: SMBus protocol type is passed in upper 16-bits of Function. | ||
279 | */ | 308 | */ |
280 | status = acpi_ex_access_region(obj_desc, 0, | 309 | status = acpi_ex_access_region(obj_desc, 0, |
281 | (acpi_integer *) buffer, | 310 | (acpi_integer *) buffer, |
282 | ACPI_WRITE | (obj_desc->field. | 311 | function); |
283 | attribute << 16)); | ||
284 | acpi_ex_release_global_lock(obj_desc->common_field.field_flags); | 312 | acpi_ex_release_global_lock(obj_desc->common_field.field_flags); |
285 | 313 | ||
286 | *result_desc = buffer_desc; | 314 | *result_desc = buffer_desc; |
diff --git a/drivers/acpi/acpica/exfldio.c b/drivers/acpi/acpica/exfldio.c index 99cee61e655d..d7b3b418fb45 100644 --- a/drivers/acpi/acpica/exfldio.c +++ b/drivers/acpi/acpica/exfldio.c | |||
@@ -113,13 +113,20 @@ acpi_ex_setup_region(union acpi_operand_object *obj_desc, | |||
113 | } | 113 | } |
114 | } | 114 | } |
115 | 115 | ||
116 | /* Exit if Address/Length have been disallowed by the host OS */ | ||
117 | |||
118 | if (rgn_desc->common.flags & AOPOBJ_INVALID) { | ||
119 | return_ACPI_STATUS(AE_AML_ILLEGAL_ADDRESS); | ||
120 | } | ||
121 | |||
116 | /* | 122 | /* |
117 | * Exit now for SMBus address space, it has a non-linear address space | 123 | * Exit now for SMBus or IPMI address space, it has a non-linear address space |
118 | * and the request cannot be directly validated | 124 | * and the request cannot be directly validated |
119 | */ | 125 | */ |
120 | if (rgn_desc->region.space_id == ACPI_ADR_SPACE_SMBUS) { | 126 | if (rgn_desc->region.space_id == ACPI_ADR_SPACE_SMBUS || |
127 | rgn_desc->region.space_id == ACPI_ADR_SPACE_IPMI) { | ||
121 | 128 | ||
122 | /* SMBus has a non-linear address space */ | 129 | /* SMBus or IPMI has a non-linear address space */ |
123 | 130 | ||
124 | return_ACPI_STATUS(AE_OK); | 131 | return_ACPI_STATUS(AE_OK); |
125 | } | 132 | } |
@@ -222,7 +229,7 @@ acpi_ex_access_region(union acpi_operand_object *obj_desc, | |||
222 | { | 229 | { |
223 | acpi_status status; | 230 | acpi_status status; |
224 | union acpi_operand_object *rgn_desc; | 231 | union acpi_operand_object *rgn_desc; |
225 | acpi_physical_address address; | 232 | u32 region_offset; |
226 | 233 | ||
227 | ACPI_FUNCTION_TRACE(ex_access_region); | 234 | ACPI_FUNCTION_TRACE(ex_access_region); |
228 | 235 | ||
@@ -243,7 +250,7 @@ acpi_ex_access_region(union acpi_operand_object *obj_desc, | |||
243 | * 3) The current offset into the field | 250 | * 3) The current offset into the field |
244 | */ | 251 | */ |
245 | rgn_desc = obj_desc->common_field.region_obj; | 252 | rgn_desc = obj_desc->common_field.region_obj; |
246 | address = rgn_desc->region.address + | 253 | region_offset = |
247 | obj_desc->common_field.base_byte_offset + field_datum_byte_offset; | 254 | obj_desc->common_field.base_byte_offset + field_datum_byte_offset; |
248 | 255 | ||
249 | if ((function & ACPI_IO_MASK) == ACPI_READ) { | 256 | if ((function & ACPI_IO_MASK) == ACPI_READ) { |
@@ -260,16 +267,18 @@ acpi_ex_access_region(union acpi_operand_object *obj_desc, | |||
260 | obj_desc->common_field.access_byte_width, | 267 | obj_desc->common_field.access_byte_width, |
261 | obj_desc->common_field.base_byte_offset, | 268 | obj_desc->common_field.base_byte_offset, |
262 | field_datum_byte_offset, ACPI_CAST_PTR(void, | 269 | field_datum_byte_offset, ACPI_CAST_PTR(void, |
263 | address))); | 270 | (rgn_desc-> |
271 | region. | ||
272 | address + | ||
273 | region_offset)))); | ||
264 | 274 | ||
265 | /* Invoke the appropriate address_space/op_region handler */ | 275 | /* Invoke the appropriate address_space/op_region handler */ |
266 | 276 | ||
267 | status = acpi_ev_address_space_dispatch(rgn_desc, function, | 277 | status = |
268 | address, | 278 | acpi_ev_address_space_dispatch(rgn_desc, function, region_offset, |
269 | ACPI_MUL_8(obj_desc-> | 279 | ACPI_MUL_8(obj_desc->common_field. |
270 | common_field. | 280 | access_byte_width), |
271 | access_byte_width), | 281 | value); |
272 | value); | ||
273 | 282 | ||
274 | if (ACPI_FAILURE(status)) { | 283 | if (ACPI_FAILURE(status)) { |
275 | if (status == AE_NOT_IMPLEMENTED) { | 284 | if (status == AE_NOT_IMPLEMENTED) { |
diff --git a/drivers/acpi/acpica/exmutex.c b/drivers/acpi/acpica/exmutex.c index d301c1f363ef..2f0114202b05 100644 --- a/drivers/acpi/acpica/exmutex.c +++ b/drivers/acpi/acpica/exmutex.c | |||
@@ -83,6 +83,15 @@ void acpi_ex_unlink_mutex(union acpi_operand_object *obj_desc) | |||
83 | 83 | ||
84 | if (obj_desc->mutex.prev) { | 84 | if (obj_desc->mutex.prev) { |
85 | (obj_desc->mutex.prev)->mutex.next = obj_desc->mutex.next; | 85 | (obj_desc->mutex.prev)->mutex.next = obj_desc->mutex.next; |
86 | |||
87 | /* | ||
88 | * Migrate the previous sync level associated with this mutex to the | ||
89 | * previous mutex on the list so that it may be preserved. This handles | ||
90 | * the case where several mutexes have been acquired at the same level, | ||
91 | * but are not released in opposite order. | ||
92 | */ | ||
93 | (obj_desc->mutex.prev)->mutex.original_sync_level = | ||
94 | obj_desc->mutex.original_sync_level; | ||
86 | } else { | 95 | } else { |
87 | thread->acquired_mutex_list = obj_desc->mutex.next; | 96 | thread->acquired_mutex_list = obj_desc->mutex.next; |
88 | } | 97 | } |
@@ -349,6 +358,7 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc, | |||
349 | struct acpi_walk_state *walk_state) | 358 | struct acpi_walk_state *walk_state) |
350 | { | 359 | { |
351 | acpi_status status = AE_OK; | 360 | acpi_status status = AE_OK; |
361 | u8 previous_sync_level; | ||
352 | 362 | ||
353 | ACPI_FUNCTION_TRACE(ex_release_mutex); | 363 | ACPI_FUNCTION_TRACE(ex_release_mutex); |
354 | 364 | ||
@@ -373,11 +383,12 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc, | |||
373 | walk_state->thread->thread_id) | 383 | walk_state->thread->thread_id) |
374 | && (obj_desc != acpi_gbl_global_lock_mutex)) { | 384 | && (obj_desc != acpi_gbl_global_lock_mutex)) { |
375 | ACPI_ERROR((AE_INFO, | 385 | ACPI_ERROR((AE_INFO, |
376 | "Thread %lX cannot release Mutex [%4.4s] acquired by thread %lX", | 386 | "Thread %p cannot release Mutex [%4.4s] acquired by thread %p", |
377 | (unsigned long)walk_state->thread->thread_id, | 387 | ACPI_CAST_PTR(void, walk_state->thread->thread_id), |
378 | acpi_ut_get_node_name(obj_desc->mutex.node), | 388 | acpi_ut_get_node_name(obj_desc->mutex.node), |
379 | (unsigned long)obj_desc->mutex.owner_thread-> | 389 | ACPI_CAST_PTR(void, |
380 | thread_id)); | 390 | obj_desc->mutex.owner_thread-> |
391 | thread_id))); | ||
381 | return_ACPI_STATUS(AE_AML_NOT_OWNER); | 392 | return_ACPI_STATUS(AE_AML_NOT_OWNER); |
382 | } | 393 | } |
383 | 394 | ||
@@ -391,10 +402,14 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc, | |||
391 | } | 402 | } |
392 | 403 | ||
393 | /* | 404 | /* |
394 | * The sync level of the mutex must be less than or equal to the current | 405 | * The sync level of the mutex must be equal to the current sync level. In |
395 | * sync level | 406 | * other words, the current level means that at least one mutex at that |
407 | * level is currently being held. Attempting to release a mutex of a | ||
408 | * different level can only mean that the mutex ordering rule is being | ||
409 | * violated. This behavior is clarified in ACPI 4.0 specification. | ||
396 | */ | 410 | */ |
397 | if (obj_desc->mutex.sync_level > walk_state->thread->current_sync_level) { | 411 | if (obj_desc->mutex.sync_level != |
412 | walk_state->thread->current_sync_level) { | ||
398 | ACPI_ERROR((AE_INFO, | 413 | ACPI_ERROR((AE_INFO, |
399 | "Cannot release Mutex [%4.4s], SyncLevel mismatch: mutex %d current %d", | 414 | "Cannot release Mutex [%4.4s], SyncLevel mismatch: mutex %d current %d", |
400 | acpi_ut_get_node_name(obj_desc->mutex.node), | 415 | acpi_ut_get_node_name(obj_desc->mutex.node), |
@@ -403,14 +418,24 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc, | |||
403 | return_ACPI_STATUS(AE_AML_MUTEX_ORDER); | 418 | return_ACPI_STATUS(AE_AML_MUTEX_ORDER); |
404 | } | 419 | } |
405 | 420 | ||
421 | /* | ||
422 | * Get the previous sync_level from the head of the acquired mutex list. | ||
423 | * This handles the case where several mutexes at the same level have been | ||
424 | * acquired, but are not released in reverse order. | ||
425 | */ | ||
426 | previous_sync_level = | ||
427 | walk_state->thread->acquired_mutex_list->mutex.original_sync_level; | ||
428 | |||
406 | status = acpi_ex_release_mutex_object(obj_desc); | 429 | status = acpi_ex_release_mutex_object(obj_desc); |
430 | if (ACPI_FAILURE(status)) { | ||
431 | return_ACPI_STATUS(status); | ||
432 | } | ||
407 | 433 | ||
408 | if (obj_desc->mutex.acquisition_depth == 0) { | 434 | if (obj_desc->mutex.acquisition_depth == 0) { |
409 | 435 | ||
410 | /* Restore the original sync_level */ | 436 | /* Restore the previous sync_level */ |
411 | 437 | ||
412 | walk_state->thread->current_sync_level = | 438 | walk_state->thread->current_sync_level = previous_sync_level; |
413 | obj_desc->mutex.original_sync_level; | ||
414 | } | 439 | } |
415 | return_ACPI_STATUS(status); | 440 | return_ACPI_STATUS(status); |
416 | } | 441 | } |
diff --git a/drivers/acpi/acpica/exstore.c b/drivers/acpi/acpica/exstore.c index 90d606196c99..6efd07a4f779 100644 --- a/drivers/acpi/acpica/exstore.c +++ b/drivers/acpi/acpica/exstore.c | |||
@@ -193,10 +193,12 @@ acpi_ex_do_debug_object(union acpi_operand_object *source_desc, | |||
193 | 193 | ||
194 | case ACPI_REFCLASS_TABLE: | 194 | case ACPI_REFCLASS_TABLE: |
195 | 195 | ||
196 | /* Case for ddb_handle */ | ||
197 | |||
196 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, | 198 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, |
197 | "Table Index 0x%X\n", | 199 | "Table Index 0x%X\n", |
198 | source_desc->reference.value)); | 200 | source_desc->reference.value)); |
199 | break; | 201 | return; |
200 | 202 | ||
201 | default: | 203 | default: |
202 | break; | 204 | break; |
diff --git a/drivers/acpi/acpica/exstorob.c b/drivers/acpi/acpica/exstorob.c index 67340cc70142..257706e7734f 100644 --- a/drivers/acpi/acpica/exstorob.c +++ b/drivers/acpi/acpica/exstorob.c | |||
@@ -70,6 +70,12 @@ acpi_ex_store_buffer_to_buffer(union acpi_operand_object *source_desc, | |||
70 | 70 | ||
71 | ACPI_FUNCTION_TRACE_PTR(ex_store_buffer_to_buffer, source_desc); | 71 | ACPI_FUNCTION_TRACE_PTR(ex_store_buffer_to_buffer, source_desc); |
72 | 72 | ||
73 | /* If Source and Target are the same, just return */ | ||
74 | |||
75 | if (source_desc == target_desc) { | ||
76 | return_ACPI_STATUS(AE_OK); | ||
77 | } | ||
78 | |||
73 | /* We know that source_desc is a buffer by now */ | 79 | /* We know that source_desc is a buffer by now */ |
74 | 80 | ||
75 | buffer = ACPI_CAST_PTR(u8, source_desc->buffer.pointer); | 81 | buffer = ACPI_CAST_PTR(u8, source_desc->buffer.pointer); |
@@ -161,6 +167,12 @@ acpi_ex_store_string_to_string(union acpi_operand_object *source_desc, | |||
161 | 167 | ||
162 | ACPI_FUNCTION_TRACE_PTR(ex_store_string_to_string, source_desc); | 168 | ACPI_FUNCTION_TRACE_PTR(ex_store_string_to_string, source_desc); |
163 | 169 | ||
170 | /* If Source and Target are the same, just return */ | ||
171 | |||
172 | if (source_desc == target_desc) { | ||
173 | return_ACPI_STATUS(AE_OK); | ||
174 | } | ||
175 | |||
164 | /* We know that source_desc is a string by now */ | 176 | /* We know that source_desc is a string by now */ |
165 | 177 | ||
166 | buffer = ACPI_CAST_PTR(u8, source_desc->string.pointer); | 178 | buffer = ACPI_CAST_PTR(u8, source_desc->string.pointer); |
diff --git a/drivers/acpi/acpica/exutils.c b/drivers/acpi/acpica/exutils.c index 87730e944132..7d41f99f7052 100644 --- a/drivers/acpi/acpica/exutils.c +++ b/drivers/acpi/acpica/exutils.c | |||
@@ -358,50 +358,67 @@ static u32 acpi_ex_digits_needed(acpi_integer value, u32 base) | |||
358 | * | 358 | * |
359 | * FUNCTION: acpi_ex_eisa_id_to_string | 359 | * FUNCTION: acpi_ex_eisa_id_to_string |
360 | * | 360 | * |
361 | * PARAMETERS: numeric_id - EISA ID to be converted | 361 | * PARAMETERS: compressed_id - EISAID to be converted |
362 | * out_string - Where to put the converted string (8 bytes) | 362 | * out_string - Where to put the converted string (8 bytes) |
363 | * | 363 | * |
364 | * RETURN: None | 364 | * RETURN: None |
365 | * | 365 | * |
366 | * DESCRIPTION: Convert a numeric EISA ID to string representation | 366 | * DESCRIPTION: Convert a numeric EISAID to string representation. Return |
367 | * buffer must be large enough to hold the string. The string | ||
368 | * returned is always exactly of length ACPI_EISAID_STRING_SIZE | ||
369 | * (includes null terminator). The EISAID is always 32 bits. | ||
367 | * | 370 | * |
368 | ******************************************************************************/ | 371 | ******************************************************************************/ |
369 | 372 | ||
370 | void acpi_ex_eisa_id_to_string(u32 numeric_id, char *out_string) | 373 | void acpi_ex_eisa_id_to_string(char *out_string, acpi_integer compressed_id) |
371 | { | 374 | { |
372 | u32 eisa_id; | 375 | u32 swapped_id; |
373 | 376 | ||
374 | ACPI_FUNCTION_ENTRY(); | 377 | ACPI_FUNCTION_ENTRY(); |
375 | 378 | ||
379 | /* The EISAID should be a 32-bit integer */ | ||
380 | |||
381 | if (compressed_id > ACPI_UINT32_MAX) { | ||
382 | ACPI_WARNING((AE_INFO, | ||
383 | "Expected EISAID is larger than 32 bits: 0x%8.8X%8.8X, truncating", | ||
384 | ACPI_FORMAT_UINT64(compressed_id))); | ||
385 | } | ||
386 | |||
376 | /* Swap ID to big-endian to get contiguous bits */ | 387 | /* Swap ID to big-endian to get contiguous bits */ |
377 | 388 | ||
378 | eisa_id = acpi_ut_dword_byte_swap(numeric_id); | 389 | swapped_id = acpi_ut_dword_byte_swap((u32)compressed_id); |
379 | 390 | ||
380 | out_string[0] = (char)('@' + (((unsigned long)eisa_id >> 26) & 0x1f)); | 391 | /* First 3 bytes are uppercase letters. Next 4 bytes are hexadecimal */ |
381 | out_string[1] = (char)('@' + ((eisa_id >> 21) & 0x1f)); | 392 | |
382 | out_string[2] = (char)('@' + ((eisa_id >> 16) & 0x1f)); | 393 | out_string[0] = |
383 | out_string[3] = acpi_ut_hex_to_ascii_char((acpi_integer) eisa_id, 12); | 394 | (char)(0x40 + (((unsigned long)swapped_id >> 26) & 0x1F)); |
384 | out_string[4] = acpi_ut_hex_to_ascii_char((acpi_integer) eisa_id, 8); | 395 | out_string[1] = (char)(0x40 + ((swapped_id >> 21) & 0x1F)); |
385 | out_string[5] = acpi_ut_hex_to_ascii_char((acpi_integer) eisa_id, 4); | 396 | out_string[2] = (char)(0x40 + ((swapped_id >> 16) & 0x1F)); |
386 | out_string[6] = acpi_ut_hex_to_ascii_char((acpi_integer) eisa_id, 0); | 397 | out_string[3] = acpi_ut_hex_to_ascii_char((acpi_integer)swapped_id, 12); |
398 | out_string[4] = acpi_ut_hex_to_ascii_char((acpi_integer)swapped_id, 8); | ||
399 | out_string[5] = acpi_ut_hex_to_ascii_char((acpi_integer)swapped_id, 4); | ||
400 | out_string[6] = acpi_ut_hex_to_ascii_char((acpi_integer)swapped_id, 0); | ||
387 | out_string[7] = 0; | 401 | out_string[7] = 0; |
388 | } | 402 | } |
389 | 403 | ||
390 | /******************************************************************************* | 404 | /******************************************************************************* |
391 | * | 405 | * |
392 | * FUNCTION: acpi_ex_unsigned_integer_to_string | 406 | * FUNCTION: acpi_ex_integer_to_string |
393 | * | 407 | * |
394 | * PARAMETERS: Value - Value to be converted | 408 | * PARAMETERS: out_string - Where to put the converted string. At least |
395 | * out_string - Where to put the converted string (8 bytes) | 409 | * 21 bytes are needed to hold the largest |
410 | * possible 64-bit integer. | ||
411 | * Value - Value to be converted | ||
396 | * | 412 | * |
397 | * RETURN: None, string | 413 | * RETURN: None, string |
398 | * | 414 | * |
399 | * DESCRIPTION: Convert a number to string representation. Assumes string | 415 | * DESCRIPTION: Convert a 64-bit integer to decimal string representation. |
400 | * buffer is large enough to hold the string. | 416 | * Assumes string buffer is large enough to hold the string. The |
417 | * largest string is (ACPI_MAX64_DECIMAL_DIGITS + 1). | ||
401 | * | 418 | * |
402 | ******************************************************************************/ | 419 | ******************************************************************************/ |
403 | 420 | ||
404 | void acpi_ex_unsigned_integer_to_string(acpi_integer value, char *out_string) | 421 | void acpi_ex_integer_to_string(char *out_string, acpi_integer value) |
405 | { | 422 | { |
406 | u32 count; | 423 | u32 count; |
407 | u32 digits_needed; | 424 | u32 digits_needed; |
diff --git a/drivers/acpi/acpica/hwgpe.c b/drivers/acpi/acpica/hwgpe.c index d3b7e37c9eed..c28c41b3180b 100644 --- a/drivers/acpi/acpica/hwgpe.c +++ b/drivers/acpi/acpica/hwgpe.c | |||
@@ -82,7 +82,7 @@ acpi_status acpi_hw_low_disable_gpe(struct acpi_gpe_event_info *gpe_event_info) | |||
82 | 82 | ||
83 | /* Get current value of the enable register that contains this GPE */ | 83 | /* Get current value of the enable register that contains this GPE */ |
84 | 84 | ||
85 | status = acpi_read(&enable_mask, &gpe_register_info->enable_address); | 85 | status = acpi_hw_read(&enable_mask, &gpe_register_info->enable_address); |
86 | if (ACPI_FAILURE(status)) { | 86 | if (ACPI_FAILURE(status)) { |
87 | return (status); | 87 | return (status); |
88 | } | 88 | } |
@@ -95,7 +95,7 @@ acpi_status acpi_hw_low_disable_gpe(struct acpi_gpe_event_info *gpe_event_info) | |||
95 | 95 | ||
96 | /* Write the updated enable mask */ | 96 | /* Write the updated enable mask */ |
97 | 97 | ||
98 | status = acpi_write(enable_mask, &gpe_register_info->enable_address); | 98 | status = acpi_hw_write(enable_mask, &gpe_register_info->enable_address); |
99 | return (status); | 99 | return (status); |
100 | } | 100 | } |
101 | 101 | ||
@@ -130,8 +130,8 @@ acpi_hw_write_gpe_enable_reg(struct acpi_gpe_event_info * gpe_event_info) | |||
130 | 130 | ||
131 | /* Write the entire GPE (runtime) enable register */ | 131 | /* Write the entire GPE (runtime) enable register */ |
132 | 132 | ||
133 | status = acpi_write(gpe_register_info->enable_for_run, | 133 | status = acpi_hw_write(gpe_register_info->enable_for_run, |
134 | &gpe_register_info->enable_address); | 134 | &gpe_register_info->enable_address); |
135 | 135 | ||
136 | return (status); | 136 | return (status); |
137 | } | 137 | } |
@@ -163,8 +163,8 @@ acpi_status acpi_hw_clear_gpe(struct acpi_gpe_event_info * gpe_event_info) | |||
163 | * Write a one to the appropriate bit in the status register to | 163 | * Write a one to the appropriate bit in the status register to |
164 | * clear this GPE. | 164 | * clear this GPE. |
165 | */ | 165 | */ |
166 | status = acpi_write(register_bit, | 166 | status = acpi_hw_write(register_bit, |
167 | &gpe_event_info->register_info->status_address); | 167 | &gpe_event_info->register_info->status_address); |
168 | 168 | ||
169 | return (status); | 169 | return (status); |
170 | } | 170 | } |
@@ -222,7 +222,7 @@ acpi_hw_get_gpe_status(struct acpi_gpe_event_info * gpe_event_info, | |||
222 | 222 | ||
223 | /* GPE currently active (status bit == 1)? */ | 223 | /* GPE currently active (status bit == 1)? */ |
224 | 224 | ||
225 | status = acpi_read(&in_byte, &gpe_register_info->status_address); | 225 | status = acpi_hw_read(&in_byte, &gpe_register_info->status_address); |
226 | if (ACPI_FAILURE(status)) { | 226 | if (ACPI_FAILURE(status)) { |
227 | goto unlock_and_exit; | 227 | goto unlock_and_exit; |
228 | } | 228 | } |
@@ -266,8 +266,8 @@ acpi_hw_disable_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, | |||
266 | /* Disable all GPEs in this register */ | 266 | /* Disable all GPEs in this register */ |
267 | 267 | ||
268 | status = | 268 | status = |
269 | acpi_write(0x00, | 269 | acpi_hw_write(0x00, |
270 | &gpe_block->register_info[i].enable_address); | 270 | &gpe_block->register_info[i].enable_address); |
271 | if (ACPI_FAILURE(status)) { | 271 | if (ACPI_FAILURE(status)) { |
272 | return (status); | 272 | return (status); |
273 | } | 273 | } |
@@ -303,8 +303,8 @@ acpi_hw_clear_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, | |||
303 | /* Clear status on all GPEs in this register */ | 303 | /* Clear status on all GPEs in this register */ |
304 | 304 | ||
305 | status = | 305 | status = |
306 | acpi_write(0xFF, | 306 | acpi_hw_write(0xFF, |
307 | &gpe_block->register_info[i].status_address); | 307 | &gpe_block->register_info[i].status_address); |
308 | if (ACPI_FAILURE(status)) { | 308 | if (ACPI_FAILURE(status)) { |
309 | return (status); | 309 | return (status); |
310 | } | 310 | } |
@@ -345,9 +345,9 @@ acpi_hw_enable_runtime_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, | |||
345 | 345 | ||
346 | /* Enable all "runtime" GPEs in this register */ | 346 | /* Enable all "runtime" GPEs in this register */ |
347 | 347 | ||
348 | status = acpi_write(gpe_block->register_info[i].enable_for_run, | 348 | status = |
349 | &gpe_block->register_info[i]. | 349 | acpi_hw_write(gpe_block->register_info[i].enable_for_run, |
350 | enable_address); | 350 | &gpe_block->register_info[i].enable_address); |
351 | if (ACPI_FAILURE(status)) { | 351 | if (ACPI_FAILURE(status)) { |
352 | return (status); | 352 | return (status); |
353 | } | 353 | } |
@@ -387,9 +387,9 @@ acpi_hw_enable_wakeup_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, | |||
387 | 387 | ||
388 | /* Enable all "wake" GPEs in this register */ | 388 | /* Enable all "wake" GPEs in this register */ |
389 | 389 | ||
390 | status = acpi_write(gpe_block->register_info[i].enable_for_wake, | 390 | status = |
391 | &gpe_block->register_info[i]. | 391 | acpi_hw_write(gpe_block->register_info[i].enable_for_wake, |
392 | enable_address); | 392 | &gpe_block->register_info[i].enable_address); |
393 | if (ACPI_FAILURE(status)) { | 393 | if (ACPI_FAILURE(status)) { |
394 | return (status); | 394 | return (status); |
395 | } | 395 | } |
diff --git a/drivers/acpi/acpica/hwregs.c b/drivers/acpi/acpica/hwregs.c index 7b2fb602b5cb..15c9ed2be853 100644 --- a/drivers/acpi/acpica/hwregs.c +++ b/drivers/acpi/acpica/hwregs.c | |||
@@ -62,6 +62,184 @@ acpi_hw_write_multiple(u32 value, | |||
62 | struct acpi_generic_address *register_a, | 62 | struct acpi_generic_address *register_a, |
63 | struct acpi_generic_address *register_b); | 63 | struct acpi_generic_address *register_b); |
64 | 64 | ||
65 | /****************************************************************************** | ||
66 | * | ||
67 | * FUNCTION: acpi_hw_validate_register | ||
68 | * | ||
69 | * PARAMETERS: Reg - GAS register structure | ||
70 | * max_bit_width - Max bit_width supported (32 or 64) | ||
71 | * Address - Pointer to where the gas->address | ||
72 | * is returned | ||
73 | * | ||
74 | * RETURN: Status | ||
75 | * | ||
76 | * DESCRIPTION: Validate the contents of a GAS register. Checks the GAS | ||
77 | * pointer, Address, space_id, bit_width, and bit_offset. | ||
78 | * | ||
79 | ******************************************************************************/ | ||
80 | |||
81 | acpi_status | ||
82 | acpi_hw_validate_register(struct acpi_generic_address *reg, | ||
83 | u8 max_bit_width, u64 *address) | ||
84 | { | ||
85 | |||
86 | /* Must have a valid pointer to a GAS structure */ | ||
87 | |||
88 | if (!reg) { | ||
89 | return (AE_BAD_PARAMETER); | ||
90 | } | ||
91 | |||
92 | /* | ||
93 | * Copy the target address. This handles possible alignment issues. | ||
94 | * Address must not be null. A null address also indicates an optional | ||
95 | * ACPI register that is not supported, so no error message. | ||
96 | */ | ||
97 | ACPI_MOVE_64_TO_64(address, ®->address); | ||
98 | if (!(*address)) { | ||
99 | return (AE_BAD_ADDRESS); | ||
100 | } | ||
101 | |||
102 | /* Validate the space_iD */ | ||
103 | |||
104 | if ((reg->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) && | ||
105 | (reg->space_id != ACPI_ADR_SPACE_SYSTEM_IO)) { | ||
106 | ACPI_ERROR((AE_INFO, | ||
107 | "Unsupported address space: 0x%X", reg->space_id)); | ||
108 | return (AE_SUPPORT); | ||
109 | } | ||
110 | |||
111 | /* Validate the bit_width */ | ||
112 | |||
113 | if ((reg->bit_width != 8) && | ||
114 | (reg->bit_width != 16) && | ||
115 | (reg->bit_width != 32) && (reg->bit_width != max_bit_width)) { | ||
116 | ACPI_ERROR((AE_INFO, | ||
117 | "Unsupported register bit width: 0x%X", | ||
118 | reg->bit_width)); | ||
119 | return (AE_SUPPORT); | ||
120 | } | ||
121 | |||
122 | /* Validate the bit_offset. Just a warning for now. */ | ||
123 | |||
124 | if (reg->bit_offset != 0) { | ||
125 | ACPI_WARNING((AE_INFO, | ||
126 | "Unsupported register bit offset: 0x%X", | ||
127 | reg->bit_offset)); | ||
128 | } | ||
129 | |||
130 | return (AE_OK); | ||
131 | } | ||
132 | |||
133 | /****************************************************************************** | ||
134 | * | ||
135 | * FUNCTION: acpi_hw_read | ||
136 | * | ||
137 | * PARAMETERS: Value - Where the value is returned | ||
138 | * Reg - GAS register structure | ||
139 | * | ||
140 | * RETURN: Status | ||
141 | * | ||
142 | * DESCRIPTION: Read from either memory or IO space. This is a 32-bit max | ||
143 | * version of acpi_read, used internally since the overhead of | ||
144 | * 64-bit values is not needed. | ||
145 | * | ||
146 | * LIMITATIONS: <These limitations also apply to acpi_hw_write> | ||
147 | * bit_width must be exactly 8, 16, or 32. | ||
148 | * space_iD must be system_memory or system_iO. | ||
149 | * bit_offset and access_width are currently ignored, as there has | ||
150 | * not been a need to implement these. | ||
151 | * | ||
152 | ******************************************************************************/ | ||
153 | |||
154 | acpi_status acpi_hw_read(u32 *value, struct acpi_generic_address *reg) | ||
155 | { | ||
156 | u64 address; | ||
157 | acpi_status status; | ||
158 | |||
159 | ACPI_FUNCTION_NAME(hw_read); | ||
160 | |||
161 | /* Validate contents of the GAS register */ | ||
162 | |||
163 | status = acpi_hw_validate_register(reg, 32, &address); | ||
164 | if (ACPI_FAILURE(status)) { | ||
165 | return (status); | ||
166 | } | ||
167 | |||
168 | /* Initialize entire 32-bit return value to zero */ | ||
169 | |||
170 | *value = 0; | ||
171 | |||
172 | /* | ||
173 | * Two address spaces supported: Memory or IO. PCI_Config is | ||
174 | * not supported here because the GAS structure is insufficient | ||
175 | */ | ||
176 | if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { | ||
177 | status = acpi_os_read_memory((acpi_physical_address) | ||
178 | address, value, reg->bit_width); | ||
179 | } else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */ | ||
180 | |||
181 | status = acpi_hw_read_port((acpi_io_address) | ||
182 | address, value, reg->bit_width); | ||
183 | } | ||
184 | |||
185 | ACPI_DEBUG_PRINT((ACPI_DB_IO, | ||
186 | "Read: %8.8X width %2d from %8.8X%8.8X (%s)\n", | ||
187 | *value, reg->bit_width, ACPI_FORMAT_UINT64(address), | ||
188 | acpi_ut_get_region_name(reg->space_id))); | ||
189 | |||
190 | return (status); | ||
191 | } | ||
192 | |||
193 | /****************************************************************************** | ||
194 | * | ||
195 | * FUNCTION: acpi_hw_write | ||
196 | * | ||
197 | * PARAMETERS: Value - Value to be written | ||
198 | * Reg - GAS register structure | ||
199 | * | ||
200 | * RETURN: Status | ||
201 | * | ||
202 | * DESCRIPTION: Write to either memory or IO space. This is a 32-bit max | ||
203 | * version of acpi_write, used internally since the overhead of | ||
204 | * 64-bit values is not needed. | ||
205 | * | ||
206 | ******************************************************************************/ | ||
207 | |||
208 | acpi_status acpi_hw_write(u32 value, struct acpi_generic_address *reg) | ||
209 | { | ||
210 | u64 address; | ||
211 | acpi_status status; | ||
212 | |||
213 | ACPI_FUNCTION_NAME(hw_write); | ||
214 | |||
215 | /* Validate contents of the GAS register */ | ||
216 | |||
217 | status = acpi_hw_validate_register(reg, 32, &address); | ||
218 | if (ACPI_FAILURE(status)) { | ||
219 | return (status); | ||
220 | } | ||
221 | |||
222 | /* | ||
223 | * Two address spaces supported: Memory or IO. PCI_Config is | ||
224 | * not supported here because the GAS structure is insufficient | ||
225 | */ | ||
226 | if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { | ||
227 | status = acpi_os_write_memory((acpi_physical_address) | ||
228 | address, value, reg->bit_width); | ||
229 | } else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */ | ||
230 | |||
231 | status = acpi_hw_write_port((acpi_io_address) | ||
232 | address, value, reg->bit_width); | ||
233 | } | ||
234 | |||
235 | ACPI_DEBUG_PRINT((ACPI_DB_IO, | ||
236 | "Wrote: %8.8X width %2d to %8.8X%8.8X (%s)\n", | ||
237 | value, reg->bit_width, ACPI_FORMAT_UINT64(address), | ||
238 | acpi_ut_get_region_name(reg->space_id))); | ||
239 | |||
240 | return (status); | ||
241 | } | ||
242 | |||
65 | /******************************************************************************* | 243 | /******************************************************************************* |
66 | * | 244 | * |
67 | * FUNCTION: acpi_hw_clear_acpi_status | 245 | * FUNCTION: acpi_hw_clear_acpi_status |
@@ -81,9 +259,9 @@ acpi_status acpi_hw_clear_acpi_status(void) | |||
81 | 259 | ||
82 | ACPI_FUNCTION_TRACE(hw_clear_acpi_status); | 260 | ACPI_FUNCTION_TRACE(hw_clear_acpi_status); |
83 | 261 | ||
84 | ACPI_DEBUG_PRINT((ACPI_DB_IO, "About to write %04X to %0llX\n", | 262 | ACPI_DEBUG_PRINT((ACPI_DB_IO, "About to write %04X to %8.8X%8.8X\n", |
85 | ACPI_BITMASK_ALL_FIXED_STATUS, | 263 | ACPI_BITMASK_ALL_FIXED_STATUS, |
86 | acpi_gbl_xpm1a_status.address)); | 264 | ACPI_FORMAT_UINT64(acpi_gbl_xpm1a_status.address))); |
87 | 265 | ||
88 | lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock); | 266 | lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock); |
89 | 267 | ||
@@ -152,15 +330,16 @@ acpi_status acpi_hw_write_pm1_control(u32 pm1a_control, u32 pm1b_control) | |||
152 | 330 | ||
153 | ACPI_FUNCTION_TRACE(hw_write_pm1_control); | 331 | ACPI_FUNCTION_TRACE(hw_write_pm1_control); |
154 | 332 | ||
155 | status = acpi_write(pm1a_control, &acpi_gbl_FADT.xpm1a_control_block); | 333 | status = |
334 | acpi_hw_write(pm1a_control, &acpi_gbl_FADT.xpm1a_control_block); | ||
156 | if (ACPI_FAILURE(status)) { | 335 | if (ACPI_FAILURE(status)) { |
157 | return_ACPI_STATUS(status); | 336 | return_ACPI_STATUS(status); |
158 | } | 337 | } |
159 | 338 | ||
160 | if (acpi_gbl_FADT.xpm1b_control_block.address) { | 339 | if (acpi_gbl_FADT.xpm1b_control_block.address) { |
161 | status = | 340 | status = |
162 | acpi_write(pm1b_control, | 341 | acpi_hw_write(pm1b_control, |
163 | &acpi_gbl_FADT.xpm1b_control_block); | 342 | &acpi_gbl_FADT.xpm1b_control_block); |
164 | } | 343 | } |
165 | return_ACPI_STATUS(status); | 344 | return_ACPI_STATUS(status); |
166 | } | 345 | } |
@@ -218,12 +397,13 @@ acpi_hw_register_read(u32 register_id, u32 * return_value) | |||
218 | 397 | ||
219 | case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */ | 398 | case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */ |
220 | 399 | ||
221 | status = acpi_read(&value, &acpi_gbl_FADT.xpm2_control_block); | 400 | status = |
401 | acpi_hw_read(&value, &acpi_gbl_FADT.xpm2_control_block); | ||
222 | break; | 402 | break; |
223 | 403 | ||
224 | case ACPI_REGISTER_PM_TIMER: /* 32-bit access */ | 404 | case ACPI_REGISTER_PM_TIMER: /* 32-bit access */ |
225 | 405 | ||
226 | status = acpi_read(&value, &acpi_gbl_FADT.xpm_timer_block); | 406 | status = acpi_hw_read(&value, &acpi_gbl_FADT.xpm_timer_block); |
227 | break; | 407 | break; |
228 | 408 | ||
229 | case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */ | 409 | case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */ |
@@ -340,7 +520,8 @@ acpi_status acpi_hw_register_write(u32 register_id, u32 value) | |||
340 | * as per the ACPI spec. | 520 | * as per the ACPI spec. |
341 | */ | 521 | */ |
342 | status = | 522 | status = |
343 | acpi_read(&read_value, &acpi_gbl_FADT.xpm2_control_block); | 523 | acpi_hw_read(&read_value, |
524 | &acpi_gbl_FADT.xpm2_control_block); | ||
344 | if (ACPI_FAILURE(status)) { | 525 | if (ACPI_FAILURE(status)) { |
345 | goto exit; | 526 | goto exit; |
346 | } | 527 | } |
@@ -350,12 +531,13 @@ acpi_status acpi_hw_register_write(u32 register_id, u32 value) | |||
350 | ACPI_INSERT_BITS(value, ACPI_PM2_CONTROL_PRESERVED_BITS, | 531 | ACPI_INSERT_BITS(value, ACPI_PM2_CONTROL_PRESERVED_BITS, |
351 | read_value); | 532 | read_value); |
352 | 533 | ||
353 | status = acpi_write(value, &acpi_gbl_FADT.xpm2_control_block); | 534 | status = |
535 | acpi_hw_write(value, &acpi_gbl_FADT.xpm2_control_block); | ||
354 | break; | 536 | break; |
355 | 537 | ||
356 | case ACPI_REGISTER_PM_TIMER: /* 32-bit access */ | 538 | case ACPI_REGISTER_PM_TIMER: /* 32-bit access */ |
357 | 539 | ||
358 | status = acpi_write(value, &acpi_gbl_FADT.xpm_timer_block); | 540 | status = acpi_hw_write(value, &acpi_gbl_FADT.xpm_timer_block); |
359 | break; | 541 | break; |
360 | 542 | ||
361 | case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */ | 543 | case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */ |
@@ -401,7 +583,7 @@ acpi_hw_read_multiple(u32 *value, | |||
401 | 583 | ||
402 | /* The first register is always required */ | 584 | /* The first register is always required */ |
403 | 585 | ||
404 | status = acpi_read(&value_a, register_a); | 586 | status = acpi_hw_read(&value_a, register_a); |
405 | if (ACPI_FAILURE(status)) { | 587 | if (ACPI_FAILURE(status)) { |
406 | return (status); | 588 | return (status); |
407 | } | 589 | } |
@@ -409,7 +591,7 @@ acpi_hw_read_multiple(u32 *value, | |||
409 | /* Second register is optional */ | 591 | /* Second register is optional */ |
410 | 592 | ||
411 | if (register_b->address) { | 593 | if (register_b->address) { |
412 | status = acpi_read(&value_b, register_b); | 594 | status = acpi_hw_read(&value_b, register_b); |
413 | if (ACPI_FAILURE(status)) { | 595 | if (ACPI_FAILURE(status)) { |
414 | return (status); | 596 | return (status); |
415 | } | 597 | } |
@@ -452,7 +634,7 @@ acpi_hw_write_multiple(u32 value, | |||
452 | 634 | ||
453 | /* The first register is always required */ | 635 | /* The first register is always required */ |
454 | 636 | ||
455 | status = acpi_write(value, register_a); | 637 | status = acpi_hw_write(value, register_a); |
456 | if (ACPI_FAILURE(status)) { | 638 | if (ACPI_FAILURE(status)) { |
457 | return (status); | 639 | return (status); |
458 | } | 640 | } |
@@ -470,7 +652,7 @@ acpi_hw_write_multiple(u32 value, | |||
470 | * and writes have no side effects" | 652 | * and writes have no side effects" |
471 | */ | 653 | */ |
472 | if (register_b->address) { | 654 | if (register_b->address) { |
473 | status = acpi_write(value, register_b); | 655 | status = acpi_hw_write(value, register_b); |
474 | } | 656 | } |
475 | 657 | ||
476 | return (status); | 658 | return (status); |
diff --git a/drivers/acpi/acpica/hwsleep.c b/drivers/acpi/acpica/hwsleep.c index db307a356f08..cc22f9a585b0 100644 --- a/drivers/acpi/acpica/hwsleep.c +++ b/drivers/acpi/acpica/hwsleep.c | |||
@@ -45,6 +45,7 @@ | |||
45 | #include <acpi/acpi.h> | 45 | #include <acpi/acpi.h> |
46 | #include "accommon.h" | 46 | #include "accommon.h" |
47 | #include "actables.h" | 47 | #include "actables.h" |
48 | #include <linux/tboot.h> | ||
48 | 49 | ||
49 | #define _COMPONENT ACPI_HARDWARE | 50 | #define _COMPONENT ACPI_HARDWARE |
50 | ACPI_MODULE_NAME("hwsleep") | 51 | ACPI_MODULE_NAME("hwsleep") |
@@ -342,6 +343,8 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state) | |||
342 | 343 | ||
343 | ACPI_FLUSH_CPU_CACHE(); | 344 | ACPI_FLUSH_CPU_CACHE(); |
344 | 345 | ||
346 | tboot_sleep(sleep_state, pm1a_control, pm1b_control); | ||
347 | |||
345 | /* Write #2: Write both SLP_TYP + SLP_EN */ | 348 | /* Write #2: Write both SLP_TYP + SLP_EN */ |
346 | 349 | ||
347 | status = acpi_hw_write_pm1_control(pm1a_control, pm1b_control); | 350 | status = acpi_hw_write_pm1_control(pm1a_control, pm1b_control); |
diff --git a/drivers/acpi/acpica/hwtimer.c b/drivers/acpi/acpica/hwtimer.c index b7f522c8f023..6b282e85d039 100644 --- a/drivers/acpi/acpica/hwtimer.c +++ b/drivers/acpi/acpica/hwtimer.c | |||
@@ -100,7 +100,7 @@ acpi_status acpi_get_timer(u32 * ticks) | |||
100 | } | 100 | } |
101 | 101 | ||
102 | status = | 102 | status = |
103 | acpi_hw_low_level_read(32, ticks, &acpi_gbl_FADT.xpm_timer_block); | 103 | acpi_hw_read(ticks, &acpi_gbl_FADT.xpm_timer_block); |
104 | 104 | ||
105 | return_ACPI_STATUS(status); | 105 | return_ACPI_STATUS(status); |
106 | } | 106 | } |
diff --git a/drivers/acpi/acpica/hwxface.c b/drivers/acpi/acpica/hwxface.c index 9829979f2bdd..647c7b6e6756 100644 --- a/drivers/acpi/acpica/hwxface.c +++ b/drivers/acpi/acpica/hwxface.c | |||
@@ -78,9 +78,22 @@ acpi_status acpi_reset(void) | |||
78 | return_ACPI_STATUS(AE_NOT_EXIST); | 78 | return_ACPI_STATUS(AE_NOT_EXIST); |
79 | } | 79 | } |
80 | 80 | ||
81 | /* Write the reset value to the reset register */ | 81 | if (reset_reg->space_id == ACPI_ADR_SPACE_SYSTEM_IO) { |
82 | /* | ||
83 | * 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 | * register. | ||
86 | */ | ||
87 | status = | ||
88 | acpi_os_write_port((acpi_io_address) reset_reg->address, | ||
89 | acpi_gbl_FADT.reset_value, | ||
90 | reset_reg->bit_width); | ||
91 | } else { | ||
92 | /* Write the reset value to the reset register */ | ||
93 | |||
94 | status = acpi_hw_write(acpi_gbl_FADT.reset_value, reset_reg); | ||
95 | } | ||
82 | 96 | ||
83 | status = acpi_write(acpi_gbl_FADT.reset_value, reset_reg); | ||
84 | return_ACPI_STATUS(status); | 97 | return_ACPI_STATUS(status); |
85 | } | 98 | } |
86 | 99 | ||
@@ -97,67 +110,92 @@ ACPI_EXPORT_SYMBOL(acpi_reset) | |||
97 | * | 110 | * |
98 | * DESCRIPTION: Read from either memory or IO space. | 111 | * DESCRIPTION: Read from either memory or IO space. |
99 | * | 112 | * |
113 | * LIMITATIONS: <These limitations also apply to acpi_write> | ||
114 | * bit_width must be exactly 8, 16, 32, or 64. | ||
115 | * space_iD must be system_memory or system_iO. | ||
116 | * bit_offset and access_width are currently ignored, as there has | ||
117 | * not been a need to implement these. | ||
118 | * | ||
100 | ******************************************************************************/ | 119 | ******************************************************************************/ |
101 | acpi_status acpi_read(u32 *value, struct acpi_generic_address *reg) | 120 | acpi_status acpi_read(u64 *return_value, struct acpi_generic_address *reg) |
102 | { | 121 | { |
122 | u32 value; | ||
103 | u32 width; | 123 | u32 width; |
104 | u64 address; | 124 | u64 address; |
105 | acpi_status status; | 125 | acpi_status status; |
106 | 126 | ||
107 | ACPI_FUNCTION_NAME(acpi_read); | 127 | ACPI_FUNCTION_NAME(acpi_read); |
108 | 128 | ||
109 | /* | 129 | if (!return_value) { |
110 | * Must have a valid pointer to a GAS structure, and a non-zero address | ||
111 | * within. | ||
112 | */ | ||
113 | if (!reg) { | ||
114 | return (AE_BAD_PARAMETER); | 130 | return (AE_BAD_PARAMETER); |
115 | } | 131 | } |
116 | 132 | ||
117 | /* Get a local copy of the address. Handles possible alignment issues */ | 133 | /* Validate contents of the GAS register. Allow 64-bit transfers */ |
118 | 134 | ||
119 | ACPI_MOVE_64_TO_64(&address, ®->address); | 135 | status = acpi_hw_validate_register(reg, 64, &address); |
120 | if (!address) { | 136 | if (ACPI_FAILURE(status)) { |
121 | return (AE_BAD_ADDRESS); | 137 | return (status); |
122 | } | 138 | } |
123 | 139 | ||
124 | /* Supported widths are 8/16/32 */ | ||
125 | |||
126 | width = reg->bit_width; | 140 | width = reg->bit_width; |
127 | if ((width != 8) && (width != 16) && (width != 32)) { | 141 | if (width == 64) { |
128 | return (AE_SUPPORT); | 142 | width = 32; /* Break into two 32-bit transfers */ |
129 | } | 143 | } |
130 | 144 | ||
131 | /* Initialize entire 32-bit return value to zero */ | 145 | /* Initialize entire 64-bit return value to zero */ |
132 | 146 | ||
133 | *value = 0; | 147 | *return_value = 0; |
148 | value = 0; | ||
134 | 149 | ||
135 | /* | 150 | /* |
136 | * Two address spaces supported: Memory or IO. PCI_Config is | 151 | * Two address spaces supported: Memory or IO. PCI_Config is |
137 | * not supported here because the GAS structure is insufficient | 152 | * not supported here because the GAS structure is insufficient |
138 | */ | 153 | */ |
139 | switch (reg->space_id) { | 154 | if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { |
140 | case ACPI_ADR_SPACE_SYSTEM_MEMORY: | 155 | status = acpi_os_read_memory((acpi_physical_address) |
156 | address, &value, width); | ||
157 | if (ACPI_FAILURE(status)) { | ||
158 | return (status); | ||
159 | } | ||
160 | *return_value = value; | ||
141 | 161 | ||
142 | status = acpi_os_read_memory((acpi_physical_address) address, | 162 | if (reg->bit_width == 64) { |
143 | value, width); | ||
144 | break; | ||
145 | 163 | ||
146 | case ACPI_ADR_SPACE_SYSTEM_IO: | 164 | /* Read the top 32 bits */ |
147 | 165 | ||
148 | status = | 166 | status = acpi_os_read_memory((acpi_physical_address) |
149 | acpi_hw_read_port((acpi_io_address) address, value, width); | 167 | (address + 4), &value, 32); |
150 | break; | 168 | if (ACPI_FAILURE(status)) { |
169 | return (status); | ||
170 | } | ||
171 | *return_value |= ((u64)value << 32); | ||
172 | } | ||
173 | } else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */ | ||
151 | 174 | ||
152 | default: | 175 | status = acpi_hw_read_port((acpi_io_address) |
153 | ACPI_ERROR((AE_INFO, | 176 | address, &value, width); |
154 | "Unsupported address space: %X", reg->space_id)); | 177 | if (ACPI_FAILURE(status)) { |
155 | return (AE_BAD_PARAMETER); | 178 | return (status); |
179 | } | ||
180 | *return_value = value; | ||
181 | |||
182 | if (reg->bit_width == 64) { | ||
183 | |||
184 | /* Read the top 32 bits */ | ||
185 | |||
186 | status = acpi_hw_read_port((acpi_io_address) | ||
187 | (address + 4), &value, 32); | ||
188 | if (ACPI_FAILURE(status)) { | ||
189 | return (status); | ||
190 | } | ||
191 | *return_value |= ((u64)value << 32); | ||
192 | } | ||
156 | } | 193 | } |
157 | 194 | ||
158 | ACPI_DEBUG_PRINT((ACPI_DB_IO, | 195 | ACPI_DEBUG_PRINT((ACPI_DB_IO, |
159 | "Read: %8.8X width %2d from %8.8X%8.8X (%s)\n", | 196 | "Read: %8.8X%8.8X width %2d from %8.8X%8.8X (%s)\n", |
160 | *value, width, ACPI_FORMAT_UINT64(address), | 197 | ACPI_FORMAT_UINT64(*return_value), reg->bit_width, |
198 | ACPI_FORMAT_UINT64(address), | ||
161 | acpi_ut_get_region_name(reg->space_id))); | 199 | acpi_ut_get_region_name(reg->space_id))); |
162 | 200 | ||
163 | return (status); | 201 | return (status); |
@@ -169,7 +207,7 @@ ACPI_EXPORT_SYMBOL(acpi_read) | |||
169 | * | 207 | * |
170 | * FUNCTION: acpi_write | 208 | * FUNCTION: acpi_write |
171 | * | 209 | * |
172 | * PARAMETERS: Value - To be written | 210 | * PARAMETERS: Value - Value to be written |
173 | * Reg - GAS register structure | 211 | * Reg - GAS register structure |
174 | * | 212 | * |
175 | * RETURN: Status | 213 | * RETURN: Status |
@@ -177,7 +215,7 @@ ACPI_EXPORT_SYMBOL(acpi_read) | |||
177 | * DESCRIPTION: Write to either memory or IO space. | 215 | * DESCRIPTION: Write to either memory or IO space. |
178 | * | 216 | * |
179 | ******************************************************************************/ | 217 | ******************************************************************************/ |
180 | acpi_status acpi_write(u32 value, struct acpi_generic_address *reg) | 218 | acpi_status acpi_write(u64 value, struct acpi_generic_address *reg) |
181 | { | 219 | { |
182 | u32 width; | 220 | u32 width; |
183 | u64 address; | 221 | u64 address; |
@@ -185,54 +223,61 @@ acpi_status acpi_write(u32 value, struct acpi_generic_address *reg) | |||
185 | 223 | ||
186 | ACPI_FUNCTION_NAME(acpi_write); | 224 | ACPI_FUNCTION_NAME(acpi_write); |
187 | 225 | ||
188 | /* | 226 | /* Validate contents of the GAS register. Allow 64-bit transfers */ |
189 | * Must have a valid pointer to a GAS structure, and a non-zero address | ||
190 | * within. | ||
191 | */ | ||
192 | if (!reg) { | ||
193 | return (AE_BAD_PARAMETER); | ||
194 | } | ||
195 | |||
196 | /* Get a local copy of the address. Handles possible alignment issues */ | ||
197 | 227 | ||
198 | ACPI_MOVE_64_TO_64(&address, ®->address); | 228 | status = acpi_hw_validate_register(reg, 64, &address); |
199 | if (!address) { | 229 | if (ACPI_FAILURE(status)) { |
200 | return (AE_BAD_ADDRESS); | 230 | return (status); |
201 | } | 231 | } |
202 | 232 | ||
203 | /* Supported widths are 8/16/32 */ | ||
204 | |||
205 | width = reg->bit_width; | 233 | width = reg->bit_width; |
206 | if ((width != 8) && (width != 16) && (width != 32)) { | 234 | if (width == 64) { |
207 | return (AE_SUPPORT); | 235 | width = 32; /* Break into two 32-bit transfers */ |
208 | } | 236 | } |
209 | 237 | ||
210 | /* | 238 | /* |
211 | * Two address spaces supported: Memory or IO. | 239 | * Two address spaces supported: Memory or IO. PCI_Config is |
212 | * PCI_Config is not supported here because the GAS struct is insufficient | 240 | * not supported here because the GAS structure is insufficient |
213 | */ | 241 | */ |
214 | switch (reg->space_id) { | 242 | if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { |
215 | case ACPI_ADR_SPACE_SYSTEM_MEMORY: | 243 | status = acpi_os_write_memory((acpi_physical_address) |
216 | 244 | address, ACPI_LODWORD(value), | |
217 | status = acpi_os_write_memory((acpi_physical_address) address, | 245 | width); |
218 | value, width); | 246 | if (ACPI_FAILURE(status)) { |
219 | break; | 247 | return (status); |
248 | } | ||
220 | 249 | ||
221 | case ACPI_ADR_SPACE_SYSTEM_IO: | 250 | if (reg->bit_width == 64) { |
251 | status = acpi_os_write_memory((acpi_physical_address) | ||
252 | (address + 4), | ||
253 | ACPI_HIDWORD(value), 32); | ||
254 | if (ACPI_FAILURE(status)) { | ||
255 | return (status); | ||
256 | } | ||
257 | } | ||
258 | } else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */ | ||
222 | 259 | ||
223 | status = acpi_hw_write_port((acpi_io_address) address, value, | 260 | status = acpi_hw_write_port((acpi_io_address) |
261 | address, ACPI_LODWORD(value), | ||
224 | width); | 262 | width); |
225 | break; | 263 | if (ACPI_FAILURE(status)) { |
264 | return (status); | ||
265 | } | ||
226 | 266 | ||
227 | default: | 267 | if (reg->bit_width == 64) { |
228 | ACPI_ERROR((AE_INFO, | 268 | status = acpi_hw_write_port((acpi_io_address) |
229 | "Unsupported address space: %X", reg->space_id)); | 269 | (address + 4), |
230 | return (AE_BAD_PARAMETER); | 270 | ACPI_HIDWORD(value), 32); |
271 | if (ACPI_FAILURE(status)) { | ||
272 | return (status); | ||
273 | } | ||
274 | } | ||
231 | } | 275 | } |
232 | 276 | ||
233 | ACPI_DEBUG_PRINT((ACPI_DB_IO, | 277 | ACPI_DEBUG_PRINT((ACPI_DB_IO, |
234 | "Wrote: %8.8X width %2d to %8.8X%8.8X (%s)\n", | 278 | "Wrote: %8.8X%8.8X width %2d to %8.8X%8.8X (%s)\n", |
235 | value, width, ACPI_FORMAT_UINT64(address), | 279 | ACPI_FORMAT_UINT64(value), reg->bit_width, |
280 | ACPI_FORMAT_UINT64(address), | ||
236 | acpi_ut_get_region_name(reg->space_id))); | 281 | acpi_ut_get_region_name(reg->space_id))); |
237 | 282 | ||
238 | return (status); | 283 | return (status); |
diff --git a/drivers/acpi/acpica/nsalloc.c b/drivers/acpi/acpica/nsalloc.c index aceb93111967..8a58a1b85aa0 100644 --- a/drivers/acpi/acpica/nsalloc.c +++ b/drivers/acpi/acpica/nsalloc.c | |||
@@ -96,17 +96,68 @@ struct acpi_namespace_node *acpi_ns_create_node(u32 name) | |||
96 | * | 96 | * |
97 | * RETURN: None | 97 | * RETURN: None |
98 | * | 98 | * |
99 | * DESCRIPTION: Delete a namespace node | 99 | * DESCRIPTION: Delete a namespace node. All node deletions must come through |
100 | * here. Detaches any attached objects, including any attached | ||
101 | * data. If a handler is associated with attached data, it is | ||
102 | * invoked before the node is deleted. | ||
100 | * | 103 | * |
101 | ******************************************************************************/ | 104 | ******************************************************************************/ |
102 | 105 | ||
103 | void acpi_ns_delete_node(struct acpi_namespace_node *node) | 106 | void acpi_ns_delete_node(struct acpi_namespace_node *node) |
104 | { | 107 | { |
108 | union acpi_operand_object *obj_desc; | ||
109 | |||
110 | ACPI_FUNCTION_NAME(ns_delete_node); | ||
111 | |||
112 | /* Detach an object if there is one */ | ||
113 | |||
114 | acpi_ns_detach_object(node); | ||
115 | |||
116 | /* | ||
117 | * Delete an attached data object if present (an object that was created | ||
118 | * and attached via acpi_attach_data). Note: After any normal object is | ||
119 | * detached above, the only possible remaining object is a data object. | ||
120 | */ | ||
121 | obj_desc = node->object; | ||
122 | if (obj_desc && (obj_desc->common.type == ACPI_TYPE_LOCAL_DATA)) { | ||
123 | |||
124 | /* Invoke the attached data deletion handler if present */ | ||
125 | |||
126 | if (obj_desc->data.handler) { | ||
127 | obj_desc->data.handler(node, obj_desc->data.pointer); | ||
128 | } | ||
129 | |||
130 | acpi_ut_remove_reference(obj_desc); | ||
131 | } | ||
132 | |||
133 | /* Now we can delete the node */ | ||
134 | |||
135 | (void)acpi_os_release_object(acpi_gbl_namespace_cache, node); | ||
136 | |||
137 | ACPI_MEM_TRACKING(acpi_gbl_ns_node_list->total_freed++); | ||
138 | ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, "Node %p, Remaining %X\n", | ||
139 | node, acpi_gbl_current_node_count)); | ||
140 | } | ||
141 | |||
142 | /******************************************************************************* | ||
143 | * | ||
144 | * FUNCTION: acpi_ns_remove_node | ||
145 | * | ||
146 | * PARAMETERS: Node - Node to be removed/deleted | ||
147 | * | ||
148 | * RETURN: None | ||
149 | * | ||
150 | * DESCRIPTION: Remove (unlink) and delete a namespace node | ||
151 | * | ||
152 | ******************************************************************************/ | ||
153 | |||
154 | void acpi_ns_remove_node(struct acpi_namespace_node *node) | ||
155 | { | ||
105 | struct acpi_namespace_node *parent_node; | 156 | struct acpi_namespace_node *parent_node; |
106 | struct acpi_namespace_node *prev_node; | 157 | struct acpi_namespace_node *prev_node; |
107 | struct acpi_namespace_node *next_node; | 158 | struct acpi_namespace_node *next_node; |
108 | 159 | ||
109 | ACPI_FUNCTION_TRACE_PTR(ns_delete_node, node); | 160 | ACPI_FUNCTION_TRACE_PTR(ns_remove_node, node); |
110 | 161 | ||
111 | parent_node = acpi_ns_get_parent_node(node); | 162 | parent_node = acpi_ns_get_parent_node(node); |
112 | 163 | ||
@@ -142,12 +193,9 @@ void acpi_ns_delete_node(struct acpi_namespace_node *node) | |||
142 | } | 193 | } |
143 | } | 194 | } |
144 | 195 | ||
145 | ACPI_MEM_TRACKING(acpi_gbl_ns_node_list->total_freed++); | 196 | /* Delete the node and any attached objects */ |
146 | |||
147 | /* Detach an object if there is one, then delete the node */ | ||
148 | 197 | ||
149 | acpi_ns_detach_object(node); | 198 | acpi_ns_delete_node(node); |
150 | (void)acpi_os_release_object(acpi_gbl_namespace_cache, node); | ||
151 | return_VOID; | 199 | return_VOID; |
152 | } | 200 | } |
153 | 201 | ||
@@ -273,25 +321,11 @@ void acpi_ns_delete_children(struct acpi_namespace_node *parent_node) | |||
273 | parent_node, child_node)); | 321 | parent_node, child_node)); |
274 | } | 322 | } |
275 | 323 | ||
276 | /* Now we can free this child object */ | 324 | /* |
277 | 325 | * Delete this child node and move on to the next child in the list. | |
278 | ACPI_MEM_TRACKING(acpi_gbl_ns_node_list->total_freed++); | 326 | * No need to unlink the node since we are deleting the entire branch. |
279 | 327 | */ | |
280 | ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, | 328 | acpi_ns_delete_node(child_node); |
281 | "Object %p, Remaining %X\n", child_node, | ||
282 | acpi_gbl_current_node_count)); | ||
283 | |||
284 | /* Detach an object if there is one, then free the child node */ | ||
285 | |||
286 | acpi_ns_detach_object(child_node); | ||
287 | |||
288 | /* Now we can delete the node */ | ||
289 | |||
290 | (void)acpi_os_release_object(acpi_gbl_namespace_cache, | ||
291 | child_node); | ||
292 | |||
293 | /* And move on to the next child in the list */ | ||
294 | |||
295 | child_node = next_node; | 329 | child_node = next_node; |
296 | 330 | ||
297 | } while (!(flags & ANOBJ_END_OF_PEER_LIST)); | 331 | } while (!(flags & ANOBJ_END_OF_PEER_LIST)); |
@@ -334,9 +368,7 @@ void acpi_ns_delete_namespace_subtree(struct acpi_namespace_node *parent_node) | |||
334 | 368 | ||
335 | /* Get the next node in this scope (NULL if none) */ | 369 | /* Get the next node in this scope (NULL if none) */ |
336 | 370 | ||
337 | child_node = | 371 | child_node = acpi_ns_get_next_node(parent_node, child_node); |
338 | acpi_ns_get_next_node(ACPI_TYPE_ANY, parent_node, | ||
339 | child_node); | ||
340 | if (child_node) { | 372 | if (child_node) { |
341 | 373 | ||
342 | /* Found a child node - detach any attached object */ | 374 | /* Found a child node - detach any attached object */ |
@@ -345,8 +377,7 @@ void acpi_ns_delete_namespace_subtree(struct acpi_namespace_node *parent_node) | |||
345 | 377 | ||
346 | /* Check if this node has any children */ | 378 | /* Check if this node has any children */ |
347 | 379 | ||
348 | if (acpi_ns_get_next_node | 380 | if (child_node->child) { |
349 | (ACPI_TYPE_ANY, child_node, NULL)) { | ||
350 | /* | 381 | /* |
351 | * There is at least one child of this node, | 382 | * There is at least one child of this node, |
352 | * visit the node | 383 | * visit the node |
@@ -432,13 +463,11 @@ void acpi_ns_delete_namespace_by_owner(acpi_owner_id owner_id) | |||
432 | * Get the next child of this parent node. When child_node is NULL, | 463 | * Get the next child of this parent node. When child_node is NULL, |
433 | * the first child of the parent is returned | 464 | * the first child of the parent is returned |
434 | */ | 465 | */ |
435 | child_node = | 466 | child_node = acpi_ns_get_next_node(parent_node, child_node); |
436 | acpi_ns_get_next_node(ACPI_TYPE_ANY, parent_node, | ||
437 | child_node); | ||
438 | 467 | ||
439 | if (deletion_node) { | 468 | if (deletion_node) { |
440 | acpi_ns_delete_children(deletion_node); | 469 | acpi_ns_delete_children(deletion_node); |
441 | acpi_ns_delete_node(deletion_node); | 470 | acpi_ns_remove_node(deletion_node); |
442 | deletion_node = NULL; | 471 | deletion_node = NULL; |
443 | } | 472 | } |
444 | 473 | ||
@@ -452,8 +481,7 @@ void acpi_ns_delete_namespace_by_owner(acpi_owner_id owner_id) | |||
452 | 481 | ||
453 | /* Check if this node has any children */ | 482 | /* Check if this node has any children */ |
454 | 483 | ||
455 | if (acpi_ns_get_next_node | 484 | if (child_node->child) { |
456 | (ACPI_TYPE_ANY, child_node, NULL)) { | ||
457 | /* | 485 | /* |
458 | * There is at least one child of this node, | 486 | * There is at least one child of this node, |
459 | * visit the node | 487 | * visit the node |
diff --git a/drivers/acpi/acpica/nsdumpdv.c b/drivers/acpi/acpica/nsdumpdv.c index 41994fe7fbb8..0fe87f1aef16 100644 --- a/drivers/acpi/acpica/nsdumpdv.c +++ b/drivers/acpi/acpica/nsdumpdv.c | |||
@@ -70,7 +70,6 @@ static acpi_status | |||
70 | acpi_ns_dump_one_device(acpi_handle obj_handle, | 70 | acpi_ns_dump_one_device(acpi_handle obj_handle, |
71 | u32 level, void *context, void **return_value) | 71 | u32 level, void *context, void **return_value) |
72 | { | 72 | { |
73 | struct acpi_buffer buffer; | ||
74 | struct acpi_device_info *info; | 73 | struct acpi_device_info *info; |
75 | acpi_status status; | 74 | acpi_status status; |
76 | u32 i; | 75 | u32 i; |
@@ -80,17 +79,15 @@ acpi_ns_dump_one_device(acpi_handle obj_handle, | |||
80 | status = | 79 | status = |
81 | acpi_ns_dump_one_object(obj_handle, level, context, return_value); | 80 | acpi_ns_dump_one_object(obj_handle, level, context, return_value); |
82 | 81 | ||
83 | buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER; | 82 | status = acpi_get_object_info(obj_handle, &info); |
84 | status = acpi_get_object_info(obj_handle, &buffer); | ||
85 | if (ACPI_SUCCESS(status)) { | 83 | if (ACPI_SUCCESS(status)) { |
86 | info = buffer.pointer; | ||
87 | for (i = 0; i < level; i++) { | 84 | for (i = 0; i < level; i++) { |
88 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_TABLES, " ")); | 85 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_TABLES, " ")); |
89 | } | 86 | } |
90 | 87 | ||
91 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_TABLES, | 88 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_TABLES, |
92 | " HID: %s, ADR: %8.8X%8.8X, Status: %X\n", | 89 | " HID: %s, ADR: %8.8X%8.8X, Status: %X\n", |
93 | info->hardware_id.value, | 90 | info->hardware_id.string, |
94 | ACPI_FORMAT_UINT64(info->address), | 91 | ACPI_FORMAT_UINT64(info->address), |
95 | info->current_status)); | 92 | info->current_status)); |
96 | ACPI_FREE(info); | 93 | ACPI_FREE(info); |
diff --git a/drivers/acpi/acpica/nseval.c b/drivers/acpi/acpica/nseval.c index 8e7dec1176c9..846d1132feb1 100644 --- a/drivers/acpi/acpica/nseval.c +++ b/drivers/acpi/acpica/nseval.c | |||
@@ -50,6 +50,11 @@ | |||
50 | #define _COMPONENT ACPI_NAMESPACE | 50 | #define _COMPONENT ACPI_NAMESPACE |
51 | ACPI_MODULE_NAME("nseval") | 51 | ACPI_MODULE_NAME("nseval") |
52 | 52 | ||
53 | /* Local prototypes */ | ||
54 | static void | ||
55 | acpi_ns_exec_module_code(union acpi_operand_object *method_obj, | ||
56 | struct acpi_evaluate_info *info); | ||
57 | |||
53 | /******************************************************************************* | 58 | /******************************************************************************* |
54 | * | 59 | * |
55 | * FUNCTION: acpi_ns_evaluate | 60 | * FUNCTION: acpi_ns_evaluate |
@@ -76,6 +81,7 @@ ACPI_MODULE_NAME("nseval") | |||
76 | * MUTEX: Locks interpreter | 81 | * MUTEX: Locks interpreter |
77 | * | 82 | * |
78 | ******************************************************************************/ | 83 | ******************************************************************************/ |
84 | |||
79 | acpi_status acpi_ns_evaluate(struct acpi_evaluate_info * info) | 85 | acpi_status acpi_ns_evaluate(struct acpi_evaluate_info * info) |
80 | { | 86 | { |
81 | acpi_status status; | 87 | acpi_status status; |
@@ -276,3 +282,134 @@ acpi_status acpi_ns_evaluate(struct acpi_evaluate_info * info) | |||
276 | */ | 282 | */ |
277 | return_ACPI_STATUS(status); | 283 | return_ACPI_STATUS(status); |
278 | } | 284 | } |
285 | |||
286 | /******************************************************************************* | ||
287 | * | ||
288 | * FUNCTION: acpi_ns_exec_module_code_list | ||
289 | * | ||
290 | * PARAMETERS: None | ||
291 | * | ||
292 | * RETURN: None. Exceptions during method execution are ignored, since | ||
293 | * we cannot abort a table load. | ||
294 | * | ||
295 | * DESCRIPTION: Execute all elements of the global module-level code list. | ||
296 | * Each element is executed as a single control method. | ||
297 | * | ||
298 | ******************************************************************************/ | ||
299 | |||
300 | void acpi_ns_exec_module_code_list(void) | ||
301 | { | ||
302 | union acpi_operand_object *prev; | ||
303 | union acpi_operand_object *next; | ||
304 | struct acpi_evaluate_info *info; | ||
305 | u32 method_count = 0; | ||
306 | |||
307 | ACPI_FUNCTION_TRACE(ns_exec_module_code_list); | ||
308 | |||
309 | /* Exit now if the list is empty */ | ||
310 | |||
311 | next = acpi_gbl_module_code_list; | ||
312 | if (!next) { | ||
313 | return_VOID; | ||
314 | } | ||
315 | |||
316 | /* Allocate the evaluation information block */ | ||
317 | |||
318 | info = ACPI_ALLOCATE(sizeof(struct acpi_evaluate_info)); | ||
319 | if (!info) { | ||
320 | return_VOID; | ||
321 | } | ||
322 | |||
323 | /* Walk the list, executing each "method" */ | ||
324 | |||
325 | while (next) { | ||
326 | prev = next; | ||
327 | next = next->method.mutex; | ||
328 | |||
329 | /* Clear the link field and execute the method */ | ||
330 | |||
331 | prev->method.mutex = NULL; | ||
332 | acpi_ns_exec_module_code(prev, info); | ||
333 | method_count++; | ||
334 | |||
335 | /* Delete the (temporary) method object */ | ||
336 | |||
337 | acpi_ut_remove_reference(prev); | ||
338 | } | ||
339 | |||
340 | ACPI_INFO((AE_INFO, | ||
341 | "Executed %u blocks of module-level executable AML code", | ||
342 | method_count)); | ||
343 | |||
344 | ACPI_FREE(info); | ||
345 | acpi_gbl_module_code_list = NULL; | ||
346 | return_VOID; | ||
347 | } | ||
348 | |||
349 | /******************************************************************************* | ||
350 | * | ||
351 | * FUNCTION: acpi_ns_exec_module_code | ||
352 | * | ||
353 | * PARAMETERS: method_obj - Object container for the module-level code | ||
354 | * Info - Info block for method evaluation | ||
355 | * | ||
356 | * RETURN: None. Exceptions during method execution are ignored, since | ||
357 | * we cannot abort a table load. | ||
358 | * | ||
359 | * DESCRIPTION: Execute a control method containing a block of module-level | ||
360 | * executable AML code. The control method is temporarily | ||
361 | * installed to the root node, then evaluated. | ||
362 | * | ||
363 | ******************************************************************************/ | ||
364 | |||
365 | static void | ||
366 | acpi_ns_exec_module_code(union acpi_operand_object *method_obj, | ||
367 | struct acpi_evaluate_info *info) | ||
368 | { | ||
369 | union acpi_operand_object *root_obj; | ||
370 | acpi_status status; | ||
371 | |||
372 | ACPI_FUNCTION_TRACE(ns_exec_module_code); | ||
373 | |||
374 | /* Initialize the evaluation information block */ | ||
375 | |||
376 | ACPI_MEMSET(info, 0, sizeof(struct acpi_evaluate_info)); | ||
377 | info->prefix_node = acpi_gbl_root_node; | ||
378 | |||
379 | /* | ||
380 | * Get the currently attached root object. Add a reference, because the | ||
381 | * ref count will be decreased when the method object is installed to | ||
382 | * the root node. | ||
383 | */ | ||
384 | root_obj = acpi_ns_get_attached_object(acpi_gbl_root_node); | ||
385 | acpi_ut_add_reference(root_obj); | ||
386 | |||
387 | /* Install the method (module-level code) in the root node */ | ||
388 | |||
389 | status = acpi_ns_attach_object(acpi_gbl_root_node, method_obj, | ||
390 | ACPI_TYPE_METHOD); | ||
391 | if (ACPI_FAILURE(status)) { | ||
392 | goto exit; | ||
393 | } | ||
394 | |||
395 | /* Execute the root node as a control method */ | ||
396 | |||
397 | status = acpi_ns_evaluate(info); | ||
398 | |||
399 | ACPI_DEBUG_PRINT((ACPI_DB_INIT, "Executed module-level code at %p\n", | ||
400 | method_obj->method.aml_start)); | ||
401 | |||
402 | /* Detach the temporary method object */ | ||
403 | |||
404 | acpi_ns_detach_object(acpi_gbl_root_node); | ||
405 | |||
406 | /* Restore the original root object */ | ||
407 | |||
408 | status = | ||
409 | acpi_ns_attach_object(acpi_gbl_root_node, root_obj, | ||
410 | ACPI_TYPE_DEVICE); | ||
411 | |||
412 | exit: | ||
413 | acpi_ut_remove_reference(root_obj); | ||
414 | return_VOID; | ||
415 | } | ||
diff --git a/drivers/acpi/acpica/nsinit.c b/drivers/acpi/acpica/nsinit.c index 2adfcf329e15..1d5b360eb25b 100644 --- a/drivers/acpi/acpica/nsinit.c +++ b/drivers/acpi/acpica/nsinit.c | |||
@@ -170,6 +170,21 @@ acpi_status acpi_ns_initialize_devices(void) | |||
170 | goto error_exit; | 170 | goto error_exit; |
171 | } | 171 | } |
172 | 172 | ||
173 | /* | ||
174 | * Execute the "global" _INI method that may appear at the root. This | ||
175 | * support is provided for Windows compatibility (Vista+) and is not | ||
176 | * part of the ACPI specification. | ||
177 | */ | ||
178 | info.evaluate_info->prefix_node = acpi_gbl_root_node; | ||
179 | info.evaluate_info->pathname = METHOD_NAME__INI; | ||
180 | info.evaluate_info->parameters = NULL; | ||
181 | info.evaluate_info->flags = ACPI_IGNORE_RETURN_VALUE; | ||
182 | |||
183 | status = acpi_ns_evaluate(info.evaluate_info); | ||
184 | if (ACPI_SUCCESS(status)) { | ||
185 | info.num_INI++; | ||
186 | } | ||
187 | |||
173 | /* Walk namespace to execute all _INIs on present devices */ | 188 | /* Walk namespace to execute all _INIs on present devices */ |
174 | 189 | ||
175 | status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, | 190 | status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, |
diff --git a/drivers/acpi/acpica/nsload.c b/drivers/acpi/acpica/nsload.c index dcd7a6adbbbc..a7234e60e985 100644 --- a/drivers/acpi/acpica/nsload.c +++ b/drivers/acpi/acpica/nsload.c | |||
@@ -270,8 +270,7 @@ static acpi_status acpi_ns_delete_subtree(acpi_handle start_handle) | |||
270 | 270 | ||
271 | /* Now delete the starting object, and we are done */ | 271 | /* Now delete the starting object, and we are done */ |
272 | 272 | ||
273 | acpi_ns_delete_node(child_handle); | 273 | acpi_ns_remove_node(child_handle); |
274 | |||
275 | return_ACPI_STATUS(AE_OK); | 274 | return_ACPI_STATUS(AE_OK); |
276 | } | 275 | } |
277 | 276 | ||
diff --git a/drivers/acpi/acpica/nsnames.c b/drivers/acpi/acpica/nsnames.c index ae3dc10a7e81..af8e6bcee07e 100644 --- a/drivers/acpi/acpica/nsnames.c +++ b/drivers/acpi/acpica/nsnames.c | |||
@@ -149,7 +149,7 @@ char *acpi_ns_get_external_pathname(struct acpi_namespace_node *node) | |||
149 | 149 | ||
150 | name_buffer = ACPI_ALLOCATE_ZEROED(size); | 150 | name_buffer = ACPI_ALLOCATE_ZEROED(size); |
151 | if (!name_buffer) { | 151 | if (!name_buffer) { |
152 | ACPI_ERROR((AE_INFO, "Allocation failure")); | 152 | ACPI_ERROR((AE_INFO, "Could not allocate %u bytes", (u32)size)); |
153 | return_PTR(NULL); | 153 | return_PTR(NULL); |
154 | } | 154 | } |
155 | 155 | ||
diff --git a/drivers/acpi/acpica/nsobject.c b/drivers/acpi/acpica/nsobject.c index 3eb20bfda9d8..60f3af08d28c 100644 --- a/drivers/acpi/acpica/nsobject.c +++ b/drivers/acpi/acpica/nsobject.c | |||
@@ -213,6 +213,15 @@ void acpi_ns_detach_object(struct acpi_namespace_node *node) | |||
213 | return_VOID; | 213 | return_VOID; |
214 | } | 214 | } |
215 | 215 | ||
216 | if (node->flags & ANOBJ_ALLOCATED_BUFFER) { | ||
217 | |||
218 | /* Free the dynamic aml buffer */ | ||
219 | |||
220 | if (obj_desc->common.type == ACPI_TYPE_METHOD) { | ||
221 | ACPI_FREE(obj_desc->method.aml_start); | ||
222 | } | ||
223 | } | ||
224 | |||
216 | /* Clear the entry in all cases */ | 225 | /* Clear the entry in all cases */ |
217 | 226 | ||
218 | node->object = NULL; | 227 | node->object = NULL; |
diff --git a/drivers/acpi/acpica/nspredef.c b/drivers/acpi/acpica/nspredef.c index d9e8cbc6e679..f8427afeebdf 100644 --- a/drivers/acpi/acpica/nspredef.c +++ b/drivers/acpi/acpica/nspredef.c | |||
@@ -42,6 +42,8 @@ | |||
42 | * POSSIBILITY OF SUCH DAMAGES. | 42 | * POSSIBILITY OF SUCH DAMAGES. |
43 | */ | 43 | */ |
44 | 44 | ||
45 | #define ACPI_CREATE_PREDEFINED_TABLE | ||
46 | |||
45 | #include <acpi/acpi.h> | 47 | #include <acpi/acpi.h> |
46 | #include "accommon.h" | 48 | #include "accommon.h" |
47 | #include "acnamesp.h" | 49 | #include "acnamesp.h" |
@@ -72,30 +74,31 @@ ACPI_MODULE_NAME("nspredef") | |||
72 | ******************************************************************************/ | 74 | ******************************************************************************/ |
73 | /* Local prototypes */ | 75 | /* Local prototypes */ |
74 | static acpi_status | 76 | static acpi_status |
75 | acpi_ns_check_package(char *pathname, | 77 | acpi_ns_check_package(struct acpi_predefined_data *data, |
76 | union acpi_operand_object **return_object_ptr, | 78 | union acpi_operand_object **return_object_ptr); |
77 | const union acpi_predefined_info *predefined); | 79 | |
80 | static acpi_status | ||
81 | acpi_ns_check_package_list(struct acpi_predefined_data *data, | ||
82 | const union acpi_predefined_info *package, | ||
83 | union acpi_operand_object **elements, u32 count); | ||
78 | 84 | ||
79 | static acpi_status | 85 | static acpi_status |
80 | acpi_ns_check_package_elements(char *pathname, | 86 | acpi_ns_check_package_elements(struct acpi_predefined_data *data, |
81 | union acpi_operand_object **elements, | 87 | union acpi_operand_object **elements, |
82 | u8 type1, | 88 | u8 type1, |
83 | u32 count1, | 89 | u32 count1, |
84 | u8 type2, u32 count2, u32 start_index); | 90 | u8 type2, u32 count2, u32 start_index); |
85 | 91 | ||
86 | static acpi_status | 92 | static acpi_status |
87 | acpi_ns_check_object_type(char *pathname, | 93 | acpi_ns_check_object_type(struct acpi_predefined_data *data, |
88 | union acpi_operand_object **return_object_ptr, | 94 | union acpi_operand_object **return_object_ptr, |
89 | u32 expected_btypes, u32 package_index); | 95 | u32 expected_btypes, u32 package_index); |
90 | 96 | ||
91 | static acpi_status | 97 | static acpi_status |
92 | acpi_ns_check_reference(char *pathname, | 98 | acpi_ns_check_reference(struct acpi_predefined_data *data, |
93 | union acpi_operand_object *return_object); | 99 | union acpi_operand_object *return_object); |
94 | 100 | ||
95 | static acpi_status | 101 | static void acpi_ns_get_expected_types(char *buffer, u32 expected_btypes); |
96 | acpi_ns_repair_object(u32 expected_btypes, | ||
97 | u32 package_index, | ||
98 | union acpi_operand_object **return_object_ptr); | ||
99 | 102 | ||
100 | /* | 103 | /* |
101 | * Names for the types that can be returned by the predefined objects. | 104 | * Names for the types that can be returned by the predefined objects. |
@@ -109,13 +112,13 @@ static const char *acpi_rtype_names[] = { | |||
109 | "/Reference", | 112 | "/Reference", |
110 | }; | 113 | }; |
111 | 114 | ||
112 | #define ACPI_NOT_PACKAGE ACPI_UINT32_MAX | ||
113 | |||
114 | /******************************************************************************* | 115 | /******************************************************************************* |
115 | * | 116 | * |
116 | * FUNCTION: acpi_ns_check_predefined_names | 117 | * FUNCTION: acpi_ns_check_predefined_names |
117 | * | 118 | * |
118 | * PARAMETERS: Node - Namespace node for the method/object | 119 | * PARAMETERS: Node - Namespace node for the method/object |
120 | * user_param_count - Number of parameters actually passed | ||
121 | * return_status - Status from the object evaluation | ||
119 | * return_object_ptr - Pointer to the object returned from the | 122 | * return_object_ptr - Pointer to the object returned from the |
120 | * evaluation of a method or object | 123 | * evaluation of a method or object |
121 | * | 124 | * |
@@ -135,16 +138,17 @@ acpi_ns_check_predefined_names(struct acpi_namespace_node *node, | |||
135 | acpi_status status = AE_OK; | 138 | acpi_status status = AE_OK; |
136 | const union acpi_predefined_info *predefined; | 139 | const union acpi_predefined_info *predefined; |
137 | char *pathname; | 140 | char *pathname; |
141 | struct acpi_predefined_data *data; | ||
138 | 142 | ||
139 | /* Match the name for this method/object against the predefined list */ | 143 | /* Match the name for this method/object against the predefined list */ |
140 | 144 | ||
141 | predefined = acpi_ns_check_for_predefined_name(node); | 145 | predefined = acpi_ns_check_for_predefined_name(node); |
142 | 146 | ||
143 | /* Get the full pathname to the object, for use in error messages */ | 147 | /* Get the full pathname to the object, for use in warning messages */ |
144 | 148 | ||
145 | pathname = acpi_ns_get_external_pathname(node); | 149 | pathname = acpi_ns_get_external_pathname(node); |
146 | if (!pathname) { | 150 | if (!pathname) { |
147 | pathname = ACPI_CAST_PTR(char, predefined->info.name); | 151 | return AE_OK; /* Could not get pathname, ignore */ |
148 | } | 152 | } |
149 | 153 | ||
150 | /* | 154 | /* |
@@ -158,28 +162,17 @@ acpi_ns_check_predefined_names(struct acpi_namespace_node *node, | |||
158 | /* If not a predefined name, we cannot validate the return object */ | 162 | /* If not a predefined name, we cannot validate the return object */ |
159 | 163 | ||
160 | if (!predefined) { | 164 | if (!predefined) { |
161 | goto exit; | 165 | goto cleanup; |
162 | } | ||
163 | |||
164 | /* If the method failed, we cannot validate the return object */ | ||
165 | |||
166 | if ((return_status != AE_OK) && (return_status != AE_CTRL_RETURN_VALUE)) { | ||
167 | goto exit; | ||
168 | } | 166 | } |
169 | 167 | ||
170 | /* | 168 | /* |
171 | * Only validate the return value on the first successful evaluation of | 169 | * If the method failed or did not actually return an object, we cannot |
172 | * the method. This ensures that any warnings will only be emitted during | 170 | * validate the return object |
173 | * the very first evaluation of the method/object. | ||
174 | */ | 171 | */ |
175 | if (node->flags & ANOBJ_EVALUATED) { | 172 | if ((return_status != AE_OK) && (return_status != AE_CTRL_RETURN_VALUE)) { |
176 | goto exit; | 173 | goto cleanup; |
177 | } | 174 | } |
178 | 175 | ||
179 | /* Mark the node as having been successfully evaluated */ | ||
180 | |||
181 | node->flags |= ANOBJ_EVALUATED; | ||
182 | |||
183 | /* | 176 | /* |
184 | * If there is no return value, check if we require a return value for | 177 | * If there is no return value, check if we require a return value for |
185 | * this predefined name. Either one return value is expected, or none, | 178 | * this predefined name. Either one return value is expected, or none, |
@@ -190,50 +183,68 @@ acpi_ns_check_predefined_names(struct acpi_namespace_node *node, | |||
190 | if (!return_object) { | 183 | if (!return_object) { |
191 | if ((predefined->info.expected_btypes) && | 184 | if ((predefined->info.expected_btypes) && |
192 | (!(predefined->info.expected_btypes & ACPI_RTYPE_NONE))) { | 185 | (!(predefined->info.expected_btypes & ACPI_RTYPE_NONE))) { |
193 | ACPI_ERROR((AE_INFO, | 186 | ACPI_WARN_PREDEFINED((AE_INFO, pathname, |
194 | "%s: Missing expected return value", | 187 | ACPI_WARN_ALWAYS, |
195 | pathname)); | 188 | "Missing expected return value")); |
196 | 189 | ||
197 | status = AE_AML_NO_RETURN_VALUE; | 190 | status = AE_AML_NO_RETURN_VALUE; |
198 | } | 191 | } |
199 | goto exit; | 192 | goto cleanup; |
200 | } | 193 | } |
201 | 194 | ||
202 | /* | 195 | /* |
203 | * We have a return value, but if one wasn't expected, just exit, this is | 196 | * 1) We have a return value, but if one wasn't expected, just exit, this is |
204 | * not a problem | 197 | * not a problem. For example, if the "Implicit Return" feature is |
198 | * enabled, methods will always return a value. | ||
205 | * | 199 | * |
206 | * For example, if the "Implicit Return" feature is enabled, methods will | 200 | * 2) If the return value can be of any type, then we cannot perform any |
207 | * always return a value | 201 | * validation, exit. |
208 | */ | 202 | */ |
209 | if (!predefined->info.expected_btypes) { | 203 | if ((!predefined->info.expected_btypes) || |
210 | goto exit; | 204 | (predefined->info.expected_btypes == ACPI_RTYPE_ALL)) { |
205 | goto cleanup; | ||
211 | } | 206 | } |
212 | 207 | ||
208 | /* Create the parameter data block for object validation */ | ||
209 | |||
210 | data = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_predefined_data)); | ||
211 | if (!data) { | ||
212 | goto cleanup; | ||
213 | } | ||
214 | data->predefined = predefined; | ||
215 | data->node_flags = node->flags; | ||
216 | data->pathname = pathname; | ||
217 | |||
213 | /* | 218 | /* |
214 | * Check that the type of the return object is what is expected for | 219 | * Check that the type of the return object is what is expected for |
215 | * this predefined name | 220 | * this predefined name |
216 | */ | 221 | */ |
217 | status = acpi_ns_check_object_type(pathname, return_object_ptr, | 222 | status = acpi_ns_check_object_type(data, return_object_ptr, |
218 | predefined->info.expected_btypes, | 223 | predefined->info.expected_btypes, |
219 | ACPI_NOT_PACKAGE); | 224 | ACPI_NOT_PACKAGE_ELEMENT); |
220 | if (ACPI_FAILURE(status)) { | 225 | if (ACPI_FAILURE(status)) { |
221 | goto exit; | 226 | goto check_validation_status; |
222 | } | 227 | } |
223 | 228 | ||
224 | /* For returned Package objects, check the type of all sub-objects */ | 229 | /* For returned Package objects, check the type of all sub-objects */ |
225 | 230 | ||
226 | if (return_object->common.type == ACPI_TYPE_PACKAGE) { | 231 | if (return_object->common.type == ACPI_TYPE_PACKAGE) { |
227 | status = | 232 | status = acpi_ns_check_package(data, return_object_ptr); |
228 | acpi_ns_check_package(pathname, return_object_ptr, | ||
229 | predefined); | ||
230 | } | 233 | } |
231 | 234 | ||
232 | exit: | 235 | check_validation_status: |
233 | if (pathname != predefined->info.name) { | 236 | /* |
234 | ACPI_FREE(pathname); | 237 | * If the object validation failed or if we successfully repaired one |
238 | * or more objects, mark the parent node to suppress further warning | ||
239 | * messages during the next evaluation of the same method/object. | ||
240 | */ | ||
241 | if (ACPI_FAILURE(status) || (data->flags & ACPI_OBJECT_REPAIRED)) { | ||
242 | node->flags |= ANOBJ_EVALUATED; | ||
235 | } | 243 | } |
244 | ACPI_FREE(data); | ||
236 | 245 | ||
246 | cleanup: | ||
247 | ACPI_FREE(pathname); | ||
237 | return (status); | 248 | return (status); |
238 | } | 249 | } |
239 | 250 | ||
@@ -271,64 +282,58 @@ acpi_ns_check_parameter_count(char *pathname, | |||
271 | param_count = node->object->method.param_count; | 282 | param_count = node->object->method.param_count; |
272 | } | 283 | } |
273 | 284 | ||
274 | /* Argument count check for non-predefined methods/objects */ | ||
275 | |||
276 | if (!predefined) { | 285 | if (!predefined) { |
277 | /* | 286 | /* |
287 | * Check the parameter count for non-predefined methods/objects. | ||
288 | * | ||
278 | * Warning if too few or too many arguments have been passed by the | 289 | * Warning if too few or too many arguments have been passed by the |
279 | * caller. An incorrect number of arguments may not cause the method | 290 | * caller. An incorrect number of arguments may not cause the method |
280 | * to fail. However, the method will fail if there are too few | 291 | * to fail. However, the method will fail if there are too few |
281 | * arguments and the method attempts to use one of the missing ones. | 292 | * arguments and the method attempts to use one of the missing ones. |
282 | */ | 293 | */ |
283 | if (user_param_count < param_count) { | 294 | if (user_param_count < param_count) { |
284 | ACPI_WARNING((AE_INFO, | 295 | ACPI_WARN_PREDEFINED((AE_INFO, pathname, |
285 | "%s: Insufficient arguments - needs %d, found %d", | 296 | ACPI_WARN_ALWAYS, |
286 | pathname, param_count, user_param_count)); | 297 | "Insufficient arguments - needs %u, found %u", |
298 | param_count, user_param_count)); | ||
287 | } else if (user_param_count > param_count) { | 299 | } else if (user_param_count > param_count) { |
288 | ACPI_WARNING((AE_INFO, | 300 | ACPI_WARN_PREDEFINED((AE_INFO, pathname, |
289 | "%s: Excess arguments - needs %d, found %d", | 301 | ACPI_WARN_ALWAYS, |
290 | pathname, param_count, user_param_count)); | 302 | "Excess arguments - needs %u, found %u", |
303 | param_count, user_param_count)); | ||
291 | } | 304 | } |
292 | return; | 305 | return; |
293 | } | 306 | } |
294 | 307 | ||
295 | /* Allow two different legal argument counts (_SCP, etc.) */ | 308 | /* |
296 | 309 | * Validate the user-supplied parameter count. | |
310 | * Allow two different legal argument counts (_SCP, etc.) | ||
311 | */ | ||
297 | required_params_current = predefined->info.param_count & 0x0F; | 312 | required_params_current = predefined->info.param_count & 0x0F; |
298 | required_params_old = predefined->info.param_count >> 4; | 313 | required_params_old = predefined->info.param_count >> 4; |
299 | 314 | ||
300 | if (user_param_count != ACPI_UINT32_MAX) { | 315 | if (user_param_count != ACPI_UINT32_MAX) { |
301 | |||
302 | /* Validate the user-supplied parameter count */ | ||
303 | |||
304 | if ((user_param_count != required_params_current) && | 316 | if ((user_param_count != required_params_current) && |
305 | (user_param_count != required_params_old)) { | 317 | (user_param_count != required_params_old)) { |
306 | ACPI_WARNING((AE_INFO, | 318 | ACPI_WARN_PREDEFINED((AE_INFO, pathname, |
307 | "%s: Parameter count mismatch - " | 319 | ACPI_WARN_ALWAYS, |
308 | "caller passed %d, ACPI requires %d", | 320 | "Parameter count mismatch - " |
309 | pathname, user_param_count, | 321 | "caller passed %u, ACPI requires %u", |
310 | required_params_current)); | 322 | user_param_count, |
323 | required_params_current)); | ||
311 | } | 324 | } |
312 | } | 325 | } |
313 | 326 | ||
314 | /* | 327 | /* |
315 | * Only validate the argument count on the first successful evaluation of | ||
316 | * the method. This ensures that any warnings will only be emitted during | ||
317 | * the very first evaluation of the method/object. | ||
318 | */ | ||
319 | if (node->flags & ANOBJ_EVALUATED) { | ||
320 | return; | ||
321 | } | ||
322 | |||
323 | /* | ||
324 | * Check that the ASL-defined parameter count is what is expected for | 328 | * Check that the ASL-defined parameter count is what is expected for |
325 | * this predefined name. | 329 | * this predefined name (parameter count as defined by the ACPI |
330 | * specification) | ||
326 | */ | 331 | */ |
327 | if ((param_count != required_params_current) && | 332 | if ((param_count != required_params_current) && |
328 | (param_count != required_params_old)) { | 333 | (param_count != required_params_old)) { |
329 | ACPI_WARNING((AE_INFO, | 334 | ACPI_WARN_PREDEFINED((AE_INFO, pathname, node->flags, |
330 | "%s: Parameter count mismatch - ASL declared %d, ACPI requires %d", | 335 | "Parameter count mismatch - ASL declared %u, ACPI requires %u", |
331 | pathname, param_count, required_params_current)); | 336 | param_count, required_params_current)); |
332 | } | 337 | } |
333 | } | 338 | } |
334 | 339 | ||
@@ -361,9 +366,6 @@ const union acpi_predefined_info *acpi_ns_check_for_predefined_name(struct | |||
361 | this_name = predefined_names; | 366 | this_name = predefined_names; |
362 | while (this_name->info.name[0]) { | 367 | while (this_name->info.name[0]) { |
363 | if (ACPI_COMPARE_NAME(node->name.ascii, this_name->info.name)) { | 368 | if (ACPI_COMPARE_NAME(node->name.ascii, this_name->info.name)) { |
364 | |||
365 | /* Return pointer to this table entry */ | ||
366 | |||
367 | return (this_name); | 369 | return (this_name); |
368 | } | 370 | } |
369 | 371 | ||
@@ -378,17 +380,16 @@ const union acpi_predefined_info *acpi_ns_check_for_predefined_name(struct | |||
378 | this_name++; | 380 | this_name++; |
379 | } | 381 | } |
380 | 382 | ||
381 | return (NULL); | 383 | return (NULL); /* Not found */ |
382 | } | 384 | } |
383 | 385 | ||
384 | /******************************************************************************* | 386 | /******************************************************************************* |
385 | * | 387 | * |
386 | * FUNCTION: acpi_ns_check_package | 388 | * FUNCTION: acpi_ns_check_package |
387 | * | 389 | * |
388 | * PARAMETERS: Pathname - Full pathname to the node (for error msgs) | 390 | * PARAMETERS: Data - Pointer to validation data structure |
389 | * return_object_ptr - Pointer to the object returned from the | 391 | * return_object_ptr - Pointer to the object returned from the |
390 | * evaluation of a method or object | 392 | * evaluation of a method or object |
391 | * Predefined - Pointer to entry in predefined name table | ||
392 | * | 393 | * |
393 | * RETURN: Status | 394 | * RETURN: Status |
394 | * | 395 | * |
@@ -398,30 +399,26 @@ const union acpi_predefined_info *acpi_ns_check_for_predefined_name(struct | |||
398 | ******************************************************************************/ | 399 | ******************************************************************************/ |
399 | 400 | ||
400 | static acpi_status | 401 | static acpi_status |
401 | acpi_ns_check_package(char *pathname, | 402 | acpi_ns_check_package(struct acpi_predefined_data *data, |
402 | union acpi_operand_object **return_object_ptr, | 403 | union acpi_operand_object **return_object_ptr) |
403 | const union acpi_predefined_info *predefined) | ||
404 | { | 404 | { |
405 | union acpi_operand_object *return_object = *return_object_ptr; | 405 | union acpi_operand_object *return_object = *return_object_ptr; |
406 | const union acpi_predefined_info *package; | 406 | const union acpi_predefined_info *package; |
407 | union acpi_operand_object *sub_package; | ||
408 | union acpi_operand_object **elements; | 407 | union acpi_operand_object **elements; |
409 | union acpi_operand_object **sub_elements; | 408 | acpi_status status = AE_OK; |
410 | acpi_status status; | ||
411 | u32 expected_count; | 409 | u32 expected_count; |
412 | u32 count; | 410 | u32 count; |
413 | u32 i; | 411 | u32 i; |
414 | u32 j; | ||
415 | 412 | ||
416 | ACPI_FUNCTION_NAME(ns_check_package); | 413 | ACPI_FUNCTION_NAME(ns_check_package); |
417 | 414 | ||
418 | /* The package info for this name is in the next table entry */ | 415 | /* The package info for this name is in the next table entry */ |
419 | 416 | ||
420 | package = predefined + 1; | 417 | package = data->predefined + 1; |
421 | 418 | ||
422 | ACPI_DEBUG_PRINT((ACPI_DB_NAMES, | 419 | ACPI_DEBUG_PRINT((ACPI_DB_NAMES, |
423 | "%s Validating return Package of Type %X, Count %X\n", | 420 | "%s Validating return Package of Type %X, Count %X\n", |
424 | pathname, package->ret_info.type, | 421 | data->pathname, package->ret_info.type, |
425 | return_object->package.count)); | 422 | return_object->package.count)); |
426 | 423 | ||
427 | /* Extract package count and elements array */ | 424 | /* Extract package count and elements array */ |
@@ -432,9 +429,8 @@ acpi_ns_check_package(char *pathname, | |||
432 | /* The package must have at least one element, else invalid */ | 429 | /* The package must have at least one element, else invalid */ |
433 | 430 | ||
434 | if (!count) { | 431 | if (!count) { |
435 | ACPI_WARNING((AE_INFO, | 432 | ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags, |
436 | "%s: Return Package has no elements (empty)", | 433 | "Return Package has no elements (empty)")); |
437 | pathname)); | ||
438 | 434 | ||
439 | return (AE_AML_OPERAND_VALUE); | 435 | return (AE_AML_OPERAND_VALUE); |
440 | } | 436 | } |
@@ -459,15 +455,16 @@ acpi_ns_check_package(char *pathname, | |||
459 | if (count < expected_count) { | 455 | if (count < expected_count) { |
460 | goto package_too_small; | 456 | goto package_too_small; |
461 | } else if (count > expected_count) { | 457 | } else if (count > expected_count) { |
462 | ACPI_WARNING((AE_INFO, | 458 | ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, |
463 | "%s: Return Package is larger than needed - " | 459 | data->node_flags, |
464 | "found %u, expected %u", pathname, count, | 460 | "Return Package is larger than needed - " |
465 | expected_count)); | 461 | "found %u, expected %u", count, |
462 | expected_count)); | ||
466 | } | 463 | } |
467 | 464 | ||
468 | /* Validate all elements of the returned package */ | 465 | /* Validate all elements of the returned package */ |
469 | 466 | ||
470 | status = acpi_ns_check_package_elements(pathname, elements, | 467 | status = acpi_ns_check_package_elements(data, elements, |
471 | package->ret_info. | 468 | package->ret_info. |
472 | object_type1, | 469 | object_type1, |
473 | package->ret_info. | 470 | package->ret_info. |
@@ -476,9 +473,6 @@ acpi_ns_check_package(char *pathname, | |||
476 | object_type2, | 473 | object_type2, |
477 | package->ret_info. | 474 | package->ret_info. |
478 | count2, 0); | 475 | count2, 0); |
479 | if (ACPI_FAILURE(status)) { | ||
480 | return (status); | ||
481 | } | ||
482 | break; | 476 | break; |
483 | 477 | ||
484 | case ACPI_PTYPE1_VAR: | 478 | case ACPI_PTYPE1_VAR: |
@@ -488,7 +482,7 @@ acpi_ns_check_package(char *pathname, | |||
488 | * elements must be of the same type | 482 | * elements must be of the same type |
489 | */ | 483 | */ |
490 | for (i = 0; i < count; i++) { | 484 | for (i = 0; i < count; i++) { |
491 | status = acpi_ns_check_object_type(pathname, elements, | 485 | status = acpi_ns_check_object_type(data, elements, |
492 | package->ret_info. | 486 | package->ret_info. |
493 | object_type1, i); | 487 | object_type1, i); |
494 | if (ACPI_FAILURE(status)) { | 488 | if (ACPI_FAILURE(status)) { |
@@ -520,8 +514,7 @@ acpi_ns_check_package(char *pathname, | |||
520 | /* These are the required package elements (0, 1, or 2) */ | 514 | /* These are the required package elements (0, 1, or 2) */ |
521 | 515 | ||
522 | status = | 516 | status = |
523 | acpi_ns_check_object_type(pathname, | 517 | acpi_ns_check_object_type(data, elements, |
524 | elements, | ||
525 | package-> | 518 | package-> |
526 | ret_info3. | 519 | ret_info3. |
527 | object_type[i], | 520 | object_type[i], |
@@ -533,8 +526,7 @@ acpi_ns_check_package(char *pathname, | |||
533 | /* These are the optional package elements */ | 526 | /* These are the optional package elements */ |
534 | 527 | ||
535 | status = | 528 | status = |
536 | acpi_ns_check_object_type(pathname, | 529 | acpi_ns_check_object_type(data, elements, |
537 | elements, | ||
538 | package-> | 530 | package-> |
539 | ret_info3. | 531 | ret_info3. |
540 | tail_object_type, | 532 | tail_object_type, |
@@ -547,11 +539,30 @@ acpi_ns_check_package(char *pathname, | |||
547 | } | 539 | } |
548 | break; | 540 | break; |
549 | 541 | ||
542 | case ACPI_PTYPE2_REV_FIXED: | ||
543 | |||
544 | /* First element is the (Integer) revision */ | ||
545 | |||
546 | status = acpi_ns_check_object_type(data, elements, | ||
547 | ACPI_RTYPE_INTEGER, 0); | ||
548 | if (ACPI_FAILURE(status)) { | ||
549 | return (status); | ||
550 | } | ||
551 | |||
552 | elements++; | ||
553 | count--; | ||
554 | |||
555 | /* Examine the sub-packages */ | ||
556 | |||
557 | status = | ||
558 | acpi_ns_check_package_list(data, package, elements, count); | ||
559 | break; | ||
560 | |||
550 | case ACPI_PTYPE2_PKG_COUNT: | 561 | case ACPI_PTYPE2_PKG_COUNT: |
551 | 562 | ||
552 | /* First element is the (Integer) count of sub-packages to follow */ | 563 | /* First element is the (Integer) count of sub-packages to follow */ |
553 | 564 | ||
554 | status = acpi_ns_check_object_type(pathname, elements, | 565 | status = acpi_ns_check_object_type(data, elements, |
555 | ACPI_RTYPE_INTEGER, 0); | 566 | ACPI_RTYPE_INTEGER, 0); |
556 | if (ACPI_FAILURE(status)) { | 567 | if (ACPI_FAILURE(status)) { |
557 | return (status); | 568 | return (status); |
@@ -569,9 +580,11 @@ acpi_ns_check_package(char *pathname, | |||
569 | count = expected_count; | 580 | count = expected_count; |
570 | elements++; | 581 | elements++; |
571 | 582 | ||
572 | /* Now we can walk the sub-packages */ | 583 | /* Examine the sub-packages */ |
573 | 584 | ||
574 | /*lint -fallthrough */ | 585 | status = |
586 | acpi_ns_check_package_list(data, package, elements, count); | ||
587 | break; | ||
575 | 588 | ||
576 | case ACPI_PTYPE2: | 589 | case ACPI_PTYPE2: |
577 | case ACPI_PTYPE2_FIXED: | 590 | case ACPI_PTYPE2_FIXED: |
@@ -579,176 +592,240 @@ acpi_ns_check_package(char *pathname, | |||
579 | case ACPI_PTYPE2_COUNT: | 592 | case ACPI_PTYPE2_COUNT: |
580 | 593 | ||
581 | /* | 594 | /* |
582 | * These types all return a single package that consists of a variable | 595 | * These types all return a single Package that consists of a |
583 | * number of sub-packages | 596 | * variable number of sub-Packages. |
597 | * | ||
598 | * First, ensure that the first element is a sub-Package. If not, | ||
599 | * the BIOS may have incorrectly returned the object as a single | ||
600 | * package instead of a Package of Packages (a common error if | ||
601 | * there is only one entry). We may be able to repair this by | ||
602 | * wrapping the returned Package with a new outer Package. | ||
584 | */ | 603 | */ |
585 | for (i = 0; i < count; i++) { | 604 | if ((*elements)->common.type != ACPI_TYPE_PACKAGE) { |
586 | sub_package = *elements; | ||
587 | sub_elements = sub_package->package.elements; | ||
588 | 605 | ||
589 | /* Each sub-object must be of type Package */ | 606 | /* Create the new outer package and populate it */ |
590 | 607 | ||
591 | status = | 608 | status = |
592 | acpi_ns_check_object_type(pathname, &sub_package, | 609 | acpi_ns_repair_package_list(data, |
593 | ACPI_RTYPE_PACKAGE, i); | 610 | return_object_ptr); |
594 | if (ACPI_FAILURE(status)) { | 611 | if (ACPI_FAILURE(status)) { |
595 | return (status); | 612 | return (status); |
596 | } | 613 | } |
597 | 614 | ||
598 | /* Examine the different types of sub-packages */ | 615 | /* Update locals to point to the new package (of 1 element) */ |
599 | 616 | ||
600 | switch (package->ret_info.type) { | 617 | return_object = *return_object_ptr; |
601 | case ACPI_PTYPE2: | 618 | elements = return_object->package.elements; |
602 | case ACPI_PTYPE2_PKG_COUNT: | 619 | count = 1; |
620 | } | ||
603 | 621 | ||
604 | /* Each subpackage has a fixed number of elements */ | 622 | /* Examine the sub-packages */ |
605 | 623 | ||
606 | expected_count = | 624 | status = |
607 | package->ret_info.count1 + | 625 | acpi_ns_check_package_list(data, package, elements, count); |
608 | package->ret_info.count2; | 626 | break; |
609 | if (sub_package->package.count != | ||
610 | expected_count) { | ||
611 | count = sub_package->package.count; | ||
612 | goto package_too_small; | ||
613 | } | ||
614 | 627 | ||
615 | status = | 628 | default: |
616 | acpi_ns_check_package_elements(pathname, | ||
617 | sub_elements, | ||
618 | package-> | ||
619 | ret_info. | ||
620 | object_type1, | ||
621 | package-> | ||
622 | ret_info. | ||
623 | count1, | ||
624 | package-> | ||
625 | ret_info. | ||
626 | object_type2, | ||
627 | package-> | ||
628 | ret_info. | ||
629 | count2, 0); | ||
630 | if (ACPI_FAILURE(status)) { | ||
631 | return (status); | ||
632 | } | ||
633 | break; | ||
634 | 629 | ||
635 | case ACPI_PTYPE2_FIXED: | 630 | /* Should not get here if predefined info table is correct */ |
636 | 631 | ||
637 | /* Each sub-package has a fixed length */ | 632 | ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags, |
633 | "Invalid internal return type in table entry: %X", | ||
634 | package->ret_info.type)); | ||
638 | 635 | ||
639 | expected_count = package->ret_info2.count; | 636 | return (AE_AML_INTERNAL); |
640 | if (sub_package->package.count < expected_count) { | 637 | } |
641 | count = sub_package->package.count; | ||
642 | goto package_too_small; | ||
643 | } | ||
644 | 638 | ||
645 | /* Check the type of each sub-package element */ | 639 | return (status); |
646 | 640 | ||
647 | for (j = 0; j < expected_count; j++) { | 641 | package_too_small: |
648 | status = | ||
649 | acpi_ns_check_object_type(pathname, | ||
650 | &sub_elements[j], | ||
651 | package->ret_info2.object_type[j], j); | ||
652 | if (ACPI_FAILURE(status)) { | ||
653 | return (status); | ||
654 | } | ||
655 | } | ||
656 | break; | ||
657 | 642 | ||
658 | case ACPI_PTYPE2_MIN: | 643 | /* Error exit for the case with an incorrect package count */ |
659 | 644 | ||
660 | /* Each sub-package has a variable but minimum length */ | 645 | ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags, |
646 | "Return Package is too small - found %u elements, expected %u", | ||
647 | count, expected_count)); | ||
661 | 648 | ||
662 | expected_count = package->ret_info.count1; | 649 | return (AE_AML_OPERAND_VALUE); |
663 | if (sub_package->package.count < expected_count) { | 650 | } |
664 | count = sub_package->package.count; | ||
665 | goto package_too_small; | ||
666 | } | ||
667 | 651 | ||
668 | /* Check the type of each sub-package element */ | 652 | /******************************************************************************* |
653 | * | ||
654 | * FUNCTION: acpi_ns_check_package_list | ||
655 | * | ||
656 | * PARAMETERS: Data - Pointer to validation data structure | ||
657 | * Package - Pointer to package-specific info for method | ||
658 | * Elements - Element list of parent package. All elements | ||
659 | * of this list should be of type Package. | ||
660 | * Count - Count of subpackages | ||
661 | * | ||
662 | * RETURN: Status | ||
663 | * | ||
664 | * DESCRIPTION: Examine a list of subpackages | ||
665 | * | ||
666 | ******************************************************************************/ | ||
669 | 667 | ||
670 | status = | 668 | static acpi_status |
671 | acpi_ns_check_package_elements(pathname, | 669 | acpi_ns_check_package_list(struct acpi_predefined_data *data, |
672 | sub_elements, | 670 | const union acpi_predefined_info *package, |
673 | package-> | 671 | union acpi_operand_object **elements, u32 count) |
674 | ret_info. | 672 | { |
675 | object_type1, | 673 | union acpi_operand_object *sub_package; |
676 | sub_package-> | 674 | union acpi_operand_object **sub_elements; |
677 | package. | 675 | acpi_status status; |
678 | count, 0, 0, | 676 | u32 expected_count; |
679 | 0); | 677 | u32 i; |
680 | if (ACPI_FAILURE(status)) { | 678 | u32 j; |
681 | return (status); | ||
682 | } | ||
683 | break; | ||
684 | 679 | ||
685 | case ACPI_PTYPE2_COUNT: | 680 | /* Validate each sub-Package in the parent Package */ |
686 | 681 | ||
687 | /* First element is the (Integer) count of elements to follow */ | 682 | for (i = 0; i < count; i++) { |
683 | sub_package = *elements; | ||
684 | sub_elements = sub_package->package.elements; | ||
688 | 685 | ||
689 | status = | 686 | /* Each sub-object must be of type Package */ |
690 | acpi_ns_check_object_type(pathname, | ||
691 | sub_elements, | ||
692 | ACPI_RTYPE_INTEGER, | ||
693 | 0); | ||
694 | if (ACPI_FAILURE(status)) { | ||
695 | return (status); | ||
696 | } | ||
697 | 687 | ||
698 | /* Make sure package is large enough for the Count */ | 688 | status = acpi_ns_check_object_type(data, &sub_package, |
689 | ACPI_RTYPE_PACKAGE, i); | ||
690 | if (ACPI_FAILURE(status)) { | ||
691 | return (status); | ||
692 | } | ||
699 | 693 | ||
700 | expected_count = | 694 | /* Examine the different types of expected sub-packages */ |
701 | (u32) (*sub_elements)->integer.value; | ||
702 | if (sub_package->package.count < expected_count) { | ||
703 | count = sub_package->package.count; | ||
704 | goto package_too_small; | ||
705 | } | ||
706 | 695 | ||
707 | /* Check the type of each sub-package element */ | 696 | switch (package->ret_info.type) { |
697 | case ACPI_PTYPE2: | ||
698 | case ACPI_PTYPE2_PKG_COUNT: | ||
699 | case ACPI_PTYPE2_REV_FIXED: | ||
708 | 700 | ||
701 | /* Each subpackage has a fixed number of elements */ | ||
702 | |||
703 | expected_count = | ||
704 | package->ret_info.count1 + package->ret_info.count2; | ||
705 | if (sub_package->package.count < expected_count) { | ||
706 | goto package_too_small; | ||
707 | } | ||
708 | |||
709 | status = | ||
710 | acpi_ns_check_package_elements(data, sub_elements, | ||
711 | package->ret_info. | ||
712 | object_type1, | ||
713 | package->ret_info. | ||
714 | count1, | ||
715 | package->ret_info. | ||
716 | object_type2, | ||
717 | package->ret_info. | ||
718 | count2, 0); | ||
719 | if (ACPI_FAILURE(status)) { | ||
720 | return (status); | ||
721 | } | ||
722 | break; | ||
723 | |||
724 | case ACPI_PTYPE2_FIXED: | ||
725 | |||
726 | /* Each sub-package has a fixed length */ | ||
727 | |||
728 | expected_count = package->ret_info2.count; | ||
729 | if (sub_package->package.count < expected_count) { | ||
730 | goto package_too_small; | ||
731 | } | ||
732 | |||
733 | /* Check the type of each sub-package element */ | ||
734 | |||
735 | for (j = 0; j < expected_count; j++) { | ||
709 | status = | 736 | status = |
710 | acpi_ns_check_package_elements(pathname, | 737 | acpi_ns_check_object_type(data, |
711 | (sub_elements | 738 | &sub_elements[j], |
712 | + 1), | 739 | package-> |
713 | package-> | 740 | ret_info2. |
714 | ret_info. | 741 | object_type[j], |
715 | object_type1, | 742 | j); |
716 | (expected_count | ||
717 | - 1), 0, 0, | ||
718 | 1); | ||
719 | if (ACPI_FAILURE(status)) { | 743 | if (ACPI_FAILURE(status)) { |
720 | return (status); | 744 | return (status); |
721 | } | 745 | } |
722 | break; | 746 | } |
747 | break; | ||
748 | |||
749 | case ACPI_PTYPE2_MIN: | ||
750 | |||
751 | /* Each sub-package has a variable but minimum length */ | ||
723 | 752 | ||
724 | default: | 753 | expected_count = package->ret_info.count1; |
725 | break; | 754 | if (sub_package->package.count < expected_count) { |
755 | goto package_too_small; | ||
726 | } | 756 | } |
727 | 757 | ||
728 | elements++; | 758 | /* Check the type of each sub-package element */ |
729 | } | ||
730 | break; | ||
731 | 759 | ||
732 | default: | 760 | status = |
761 | acpi_ns_check_package_elements(data, sub_elements, | ||
762 | package->ret_info. | ||
763 | object_type1, | ||
764 | sub_package->package. | ||
765 | count, 0, 0, 0); | ||
766 | if (ACPI_FAILURE(status)) { | ||
767 | return (status); | ||
768 | } | ||
769 | break; | ||
733 | 770 | ||
734 | /* Should not get here if predefined info table is correct */ | 771 | case ACPI_PTYPE2_COUNT: |
735 | 772 | ||
736 | ACPI_WARNING((AE_INFO, | 773 | /* |
737 | "%s: Invalid internal return type in table entry: %X", | 774 | * First element is the (Integer) count of elements, including |
738 | pathname, package->ret_info.type)); | 775 | * the count field. |
776 | */ | ||
777 | status = acpi_ns_check_object_type(data, sub_elements, | ||
778 | ACPI_RTYPE_INTEGER, | ||
779 | 0); | ||
780 | if (ACPI_FAILURE(status)) { | ||
781 | return (status); | ||
782 | } | ||
739 | 783 | ||
740 | return (AE_AML_INTERNAL); | 784 | /* |
785 | * Make sure package is large enough for the Count and is | ||
786 | * is as large as the minimum size | ||
787 | */ | ||
788 | expected_count = (u32)(*sub_elements)->integer.value; | ||
789 | if (sub_package->package.count < expected_count) { | ||
790 | goto package_too_small; | ||
791 | } | ||
792 | if (sub_package->package.count < | ||
793 | package->ret_info.count1) { | ||
794 | expected_count = package->ret_info.count1; | ||
795 | goto package_too_small; | ||
796 | } | ||
797 | |||
798 | /* Check the type of each sub-package element */ | ||
799 | |||
800 | status = | ||
801 | acpi_ns_check_package_elements(data, | ||
802 | (sub_elements + 1), | ||
803 | package->ret_info. | ||
804 | object_type1, | ||
805 | (expected_count - 1), | ||
806 | 0, 0, 1); | ||
807 | if (ACPI_FAILURE(status)) { | ||
808 | return (status); | ||
809 | } | ||
810 | break; | ||
811 | |||
812 | default: /* Should not get here, type was validated by caller */ | ||
813 | |||
814 | return (AE_AML_INTERNAL); | ||
815 | } | ||
816 | |||
817 | elements++; | ||
741 | } | 818 | } |
742 | 819 | ||
743 | return (AE_OK); | 820 | return (AE_OK); |
744 | 821 | ||
745 | package_too_small: | 822 | package_too_small: |
746 | 823 | ||
747 | /* Error exit for the case with an incorrect package count */ | 824 | /* The sub-package count was smaller than required */ |
748 | 825 | ||
749 | ACPI_WARNING((AE_INFO, "%s: Return Package is too small - " | 826 | ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags, |
750 | "found %u, expected %u", pathname, count, | 827 | "Return Sub-Package[%u] is too small - found %u elements, expected %u", |
751 | expected_count)); | 828 | i, sub_package->package.count, expected_count)); |
752 | 829 | ||
753 | return (AE_AML_OPERAND_VALUE); | 830 | return (AE_AML_OPERAND_VALUE); |
754 | } | 831 | } |
@@ -757,7 +834,7 @@ acpi_ns_check_package(char *pathname, | |||
757 | * | 834 | * |
758 | * FUNCTION: acpi_ns_check_package_elements | 835 | * FUNCTION: acpi_ns_check_package_elements |
759 | * | 836 | * |
760 | * PARAMETERS: Pathname - Full pathname to the node (for error msgs) | 837 | * PARAMETERS: Data - Pointer to validation data structure |
761 | * Elements - Pointer to the package elements array | 838 | * Elements - Pointer to the package elements array |
762 | * Type1 - Object type for first group | 839 | * Type1 - Object type for first group |
763 | * Count1 - Count for first group | 840 | * Count1 - Count for first group |
@@ -773,7 +850,7 @@ acpi_ns_check_package(char *pathname, | |||
773 | ******************************************************************************/ | 850 | ******************************************************************************/ |
774 | 851 | ||
775 | static acpi_status | 852 | static acpi_status |
776 | acpi_ns_check_package_elements(char *pathname, | 853 | acpi_ns_check_package_elements(struct acpi_predefined_data *data, |
777 | union acpi_operand_object **elements, | 854 | union acpi_operand_object **elements, |
778 | u8 type1, | 855 | u8 type1, |
779 | u32 count1, | 856 | u32 count1, |
@@ -789,7 +866,7 @@ acpi_ns_check_package_elements(char *pathname, | |||
789 | * The second group can have a count of zero. | 866 | * The second group can have a count of zero. |
790 | */ | 867 | */ |
791 | for (i = 0; i < count1; i++) { | 868 | for (i = 0; i < count1; i++) { |
792 | status = acpi_ns_check_object_type(pathname, this_element, | 869 | status = acpi_ns_check_object_type(data, this_element, |
793 | type1, i + start_index); | 870 | type1, i + start_index); |
794 | if (ACPI_FAILURE(status)) { | 871 | if (ACPI_FAILURE(status)) { |
795 | return (status); | 872 | return (status); |
@@ -798,7 +875,7 @@ acpi_ns_check_package_elements(char *pathname, | |||
798 | } | 875 | } |
799 | 876 | ||
800 | for (i = 0; i < count2; i++) { | 877 | for (i = 0; i < count2; i++) { |
801 | status = acpi_ns_check_object_type(pathname, this_element, | 878 | status = acpi_ns_check_object_type(data, this_element, |
802 | type2, | 879 | type2, |
803 | (i + count1 + start_index)); | 880 | (i + count1 + start_index)); |
804 | if (ACPI_FAILURE(status)) { | 881 | if (ACPI_FAILURE(status)) { |
@@ -814,12 +891,13 @@ acpi_ns_check_package_elements(char *pathname, | |||
814 | * | 891 | * |
815 | * FUNCTION: acpi_ns_check_object_type | 892 | * FUNCTION: acpi_ns_check_object_type |
816 | * | 893 | * |
817 | * PARAMETERS: Pathname - Full pathname to the node (for error msgs) | 894 | * PARAMETERS: Data - Pointer to validation data structure |
818 | * return_object_ptr - Pointer to the object returned from the | 895 | * return_object_ptr - Pointer to the object returned from the |
819 | * evaluation of a method or object | 896 | * evaluation of a method or object |
820 | * expected_btypes - Bitmap of expected return type(s) | 897 | * expected_btypes - Bitmap of expected return type(s) |
821 | * package_index - Index of object within parent package (if | 898 | * package_index - Index of object within parent package (if |
822 | * applicable - ACPI_NOT_PACKAGE otherwise) | 899 | * applicable - ACPI_NOT_PACKAGE_ELEMENT |
900 | * otherwise) | ||
823 | * | 901 | * |
824 | * RETURN: Status | 902 | * RETURN: Status |
825 | * | 903 | * |
@@ -829,7 +907,7 @@ acpi_ns_check_package_elements(char *pathname, | |||
829 | ******************************************************************************/ | 907 | ******************************************************************************/ |
830 | 908 | ||
831 | static acpi_status | 909 | static acpi_status |
832 | acpi_ns_check_object_type(char *pathname, | 910 | acpi_ns_check_object_type(struct acpi_predefined_data *data, |
833 | union acpi_operand_object **return_object_ptr, | 911 | union acpi_operand_object **return_object_ptr, |
834 | u32 expected_btypes, u32 package_index) | 912 | u32 expected_btypes, u32 package_index) |
835 | { | 913 | { |
@@ -837,9 +915,6 @@ acpi_ns_check_object_type(char *pathname, | |||
837 | acpi_status status = AE_OK; | 915 | acpi_status status = AE_OK; |
838 | u32 return_btype; | 916 | u32 return_btype; |
839 | char type_buffer[48]; /* Room for 5 types */ | 917 | char type_buffer[48]; /* Room for 5 types */ |
840 | u32 this_rtype; | ||
841 | u32 i; | ||
842 | u32 j; | ||
843 | 918 | ||
844 | /* | 919 | /* |
845 | * If we get a NULL return_object here, it is a NULL package element, | 920 | * If we get a NULL return_object here, it is a NULL package element, |
@@ -852,10 +927,11 @@ acpi_ns_check_object_type(char *pathname, | |||
852 | /* A Namespace node should not get here, but make sure */ | 927 | /* A Namespace node should not get here, but make sure */ |
853 | 928 | ||
854 | if (ACPI_GET_DESCRIPTOR_TYPE(return_object) == ACPI_DESC_TYPE_NAMED) { | 929 | if (ACPI_GET_DESCRIPTOR_TYPE(return_object) == ACPI_DESC_TYPE_NAMED) { |
855 | ACPI_WARNING((AE_INFO, | 930 | ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags, |
856 | "%s: Invalid return type - Found a Namespace node [%4.4s] type %s", | 931 | "Invalid return type - Found a Namespace node [%4.4s] type %s", |
857 | pathname, return_object->node.name.ascii, | 932 | return_object->node.name.ascii, |
858 | acpi_ut_get_type_name(return_object->node.type))); | 933 | acpi_ut_get_type_name(return_object->node. |
934 | type))); | ||
859 | return (AE_AML_OPERAND_TYPE); | 935 | return (AE_AML_OPERAND_TYPE); |
860 | } | 936 | } |
861 | 937 | ||
@@ -900,10 +976,11 @@ acpi_ns_check_object_type(char *pathname, | |||
900 | 976 | ||
901 | /* Type mismatch -- attempt repair of the returned object */ | 977 | /* Type mismatch -- attempt repair of the returned object */ |
902 | 978 | ||
903 | status = acpi_ns_repair_object(expected_btypes, package_index, | 979 | status = acpi_ns_repair_object(data, expected_btypes, |
980 | package_index, | ||
904 | return_object_ptr); | 981 | return_object_ptr); |
905 | if (ACPI_SUCCESS(status)) { | 982 | if (ACPI_SUCCESS(status)) { |
906 | return (status); | 983 | return (AE_OK); /* Repair was successful */ |
907 | } | 984 | } |
908 | goto type_error_exit; | 985 | goto type_error_exit; |
909 | } | 986 | } |
@@ -911,7 +988,7 @@ acpi_ns_check_object_type(char *pathname, | |||
911 | /* For reference objects, check that the reference type is correct */ | 988 | /* For reference objects, check that the reference type is correct */ |
912 | 989 | ||
913 | if (return_object->common.type == ACPI_TYPE_LOCAL_REFERENCE) { | 990 | if (return_object->common.type == ACPI_TYPE_LOCAL_REFERENCE) { |
914 | status = acpi_ns_check_reference(pathname, return_object); | 991 | status = acpi_ns_check_reference(data, return_object); |
915 | } | 992 | } |
916 | 993 | ||
917 | return (status); | 994 | return (status); |
@@ -920,33 +997,19 @@ acpi_ns_check_object_type(char *pathname, | |||
920 | 997 | ||
921 | /* Create a string with all expected types for this predefined object */ | 998 | /* Create a string with all expected types for this predefined object */ |
922 | 999 | ||
923 | j = 1; | 1000 | acpi_ns_get_expected_types(type_buffer, expected_btypes); |
924 | type_buffer[0] = 0; | ||
925 | this_rtype = ACPI_RTYPE_INTEGER; | ||
926 | |||
927 | for (i = 0; i < ACPI_NUM_RTYPES; i++) { | ||
928 | |||
929 | /* If one of the expected types, concatenate the name of this type */ | ||
930 | |||
931 | if (expected_btypes & this_rtype) { | ||
932 | ACPI_STRCAT(type_buffer, &acpi_rtype_names[i][j]); | ||
933 | j = 0; /* Use name separator from now on */ | ||
934 | } | ||
935 | this_rtype <<= 1; /* Next Rtype */ | ||
936 | } | ||
937 | 1001 | ||
938 | if (package_index == ACPI_NOT_PACKAGE) { | 1002 | if (package_index == ACPI_NOT_PACKAGE_ELEMENT) { |
939 | ACPI_WARNING((AE_INFO, | 1003 | ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags, |
940 | "%s: Return type mismatch - found %s, expected %s", | 1004 | "Return type mismatch - found %s, expected %s", |
941 | pathname, | 1005 | acpi_ut_get_object_type_name |
942 | acpi_ut_get_object_type_name(return_object), | 1006 | (return_object), type_buffer)); |
943 | type_buffer)); | ||
944 | } else { | 1007 | } else { |
945 | ACPI_WARNING((AE_INFO, | 1008 | ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags, |
946 | "%s: Return Package type mismatch at index %u - " | 1009 | "Return Package type mismatch at index %u - " |
947 | "found %s, expected %s", pathname, package_index, | 1010 | "found %s, expected %s", package_index, |
948 | acpi_ut_get_object_type_name(return_object), | 1011 | acpi_ut_get_object_type_name |
949 | type_buffer)); | 1012 | (return_object), type_buffer)); |
950 | } | 1013 | } |
951 | 1014 | ||
952 | return (AE_AML_OPERAND_TYPE); | 1015 | return (AE_AML_OPERAND_TYPE); |
@@ -956,7 +1019,7 @@ acpi_ns_check_object_type(char *pathname, | |||
956 | * | 1019 | * |
957 | * FUNCTION: acpi_ns_check_reference | 1020 | * FUNCTION: acpi_ns_check_reference |
958 | * | 1021 | * |
959 | * PARAMETERS: Pathname - Full pathname to the node (for error msgs) | 1022 | * PARAMETERS: Data - Pointer to validation data structure |
960 | * return_object - Object returned from the evaluation of a | 1023 | * return_object - Object returned from the evaluation of a |
961 | * method or object | 1024 | * method or object |
962 | * | 1025 | * |
@@ -969,7 +1032,7 @@ acpi_ns_check_object_type(char *pathname, | |||
969 | ******************************************************************************/ | 1032 | ******************************************************************************/ |
970 | 1033 | ||
971 | static acpi_status | 1034 | static acpi_status |
972 | acpi_ns_check_reference(char *pathname, | 1035 | acpi_ns_check_reference(struct acpi_predefined_data *data, |
973 | union acpi_operand_object *return_object) | 1036 | union acpi_operand_object *return_object) |
974 | { | 1037 | { |
975 | 1038 | ||
@@ -982,94 +1045,46 @@ acpi_ns_check_reference(char *pathname, | |||
982 | return (AE_OK); | 1045 | return (AE_OK); |
983 | } | 1046 | } |
984 | 1047 | ||
985 | ACPI_WARNING((AE_INFO, | 1048 | ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags, |
986 | "%s: Return type mismatch - " | 1049 | "Return type mismatch - unexpected reference object type [%s] %2.2X", |
987 | "unexpected reference object type [%s] %2.2X", | 1050 | acpi_ut_get_reference_name(return_object), |
988 | pathname, acpi_ut_get_reference_name(return_object), | 1051 | return_object->reference.class)); |
989 | return_object->reference.class)); | ||
990 | 1052 | ||
991 | return (AE_AML_OPERAND_TYPE); | 1053 | return (AE_AML_OPERAND_TYPE); |
992 | } | 1054 | } |
993 | 1055 | ||
994 | /******************************************************************************* | 1056 | /******************************************************************************* |
995 | * | 1057 | * |
996 | * FUNCTION: acpi_ns_repair_object | 1058 | * FUNCTION: acpi_ns_get_expected_types |
997 | * | 1059 | * |
998 | * PARAMETERS: Pathname - Full pathname to the node (for error msgs) | 1060 | * PARAMETERS: Buffer - Pointer to where the string is returned |
999 | * package_index - Used to determine if target is in a package | 1061 | * expected_btypes - Bitmap of expected return type(s) |
1000 | * return_object_ptr - Pointer to the object returned from the | ||
1001 | * evaluation of a method or object | ||
1002 | * | 1062 | * |
1003 | * RETURN: Status. AE_OK if repair was successful. | 1063 | * RETURN: Buffer is populated with type names. |
1004 | * | 1064 | * |
1005 | * DESCRIPTION: Attempt to repair/convert a return object of a type that was | 1065 | * DESCRIPTION: Translate the expected types bitmap into a string of ascii |
1006 | * not expected. | 1066 | * names of expected types, for use in warning messages. |
1007 | * | 1067 | * |
1008 | ******************************************************************************/ | 1068 | ******************************************************************************/ |
1009 | 1069 | ||
1010 | static acpi_status | 1070 | static void acpi_ns_get_expected_types(char *buffer, u32 expected_btypes) |
1011 | acpi_ns_repair_object(u32 expected_btypes, | ||
1012 | u32 package_index, | ||
1013 | union acpi_operand_object **return_object_ptr) | ||
1014 | { | 1071 | { |
1015 | union acpi_operand_object *return_object = *return_object_ptr; | 1072 | u32 this_rtype; |
1016 | union acpi_operand_object *new_object; | 1073 | u32 i; |
1017 | acpi_size length; | 1074 | u32 j; |
1018 | |||
1019 | switch (return_object->common.type) { | ||
1020 | case ACPI_TYPE_BUFFER: | ||
1021 | |||
1022 | if (!(expected_btypes & ACPI_RTYPE_STRING)) { | ||
1023 | return (AE_AML_OPERAND_TYPE); | ||
1024 | } | ||
1025 | |||
1026 | /* | ||
1027 | * Have a Buffer, expected a String, convert. Use a to_string | ||
1028 | * conversion, no transform performed on the buffer data. The best | ||
1029 | * example of this is the _BIF method, where the string data from | ||
1030 | * the battery is often (incorrectly) returned as buffer object(s). | ||
1031 | */ | ||
1032 | length = 0; | ||
1033 | while ((length < return_object->buffer.length) && | ||
1034 | (return_object->buffer.pointer[length])) { | ||
1035 | length++; | ||
1036 | } | ||
1037 | |||
1038 | /* Allocate a new string object */ | ||
1039 | |||
1040 | new_object = acpi_ut_create_string_object(length); | ||
1041 | if (!new_object) { | ||
1042 | return (AE_NO_MEMORY); | ||
1043 | } | ||
1044 | 1075 | ||
1045 | /* | 1076 | j = 1; |
1046 | * Copy the raw buffer data with no transform. String is already NULL | 1077 | buffer[0] = 0; |
1047 | * terminated at Length+1. | 1078 | this_rtype = ACPI_RTYPE_INTEGER; |
1048 | */ | ||
1049 | ACPI_MEMCPY(new_object->string.pointer, | ||
1050 | return_object->buffer.pointer, length); | ||
1051 | 1079 | ||
1052 | /* Install the new return object */ | 1080 | for (i = 0; i < ACPI_NUM_RTYPES; i++) { |
1053 | 1081 | ||
1054 | acpi_ut_remove_reference(return_object); | 1082 | /* If one of the expected types, concatenate the name of this type */ |
1055 | *return_object_ptr = new_object; | ||
1056 | 1083 | ||
1057 | /* | 1084 | if (expected_btypes & this_rtype) { |
1058 | * If the object is a package element, we need to: | 1085 | ACPI_STRCAT(buffer, &acpi_rtype_names[i][j]); |
1059 | * 1. Decrement the reference count of the orignal object, it was | 1086 | j = 0; /* Use name separator from now on */ |
1060 | * incremented when building the package | ||
1061 | * 2. Increment the reference count of the new object, it will be | ||
1062 | * decremented when releasing the package | ||
1063 | */ | ||
1064 | if (package_index != ACPI_NOT_PACKAGE) { | ||
1065 | acpi_ut_remove_reference(return_object); | ||
1066 | acpi_ut_add_reference(new_object); | ||
1067 | } | 1087 | } |
1068 | return (AE_OK); | 1088 | this_rtype <<= 1; /* Next Rtype */ |
1069 | |||
1070 | default: | ||
1071 | break; | ||
1072 | } | 1089 | } |
1073 | |||
1074 | return (AE_AML_OPERAND_TYPE); | ||
1075 | } | 1090 | } |
diff --git a/drivers/acpi/acpica/nsrepair.c b/drivers/acpi/acpica/nsrepair.c new file mode 100644 index 000000000000..db2b2a99c3a8 --- /dev/null +++ b/drivers/acpi/acpica/nsrepair.c | |||
@@ -0,0 +1,203 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Module Name: nsrepair - Repair for objects returned by predefined methods | ||
4 | * | ||
5 | *****************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2009, Intel Corp. | ||
9 | * All rights reserved. | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * 1. Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions, and the following disclaimer, | ||
16 | * without modification. | ||
17 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
18 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
19 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
20 | * including a substantially similar Disclaimer requirement for further | ||
21 | * binary redistribution. | ||
22 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
23 | * of any contributors may be used to endorse or promote products derived | ||
24 | * from this software without specific prior written permission. | ||
25 | * | ||
26 | * Alternatively, this software may be distributed under the terms of the | ||
27 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
28 | * Software Foundation. | ||
29 | * | ||
30 | * NO WARRANTY | ||
31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
35 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
40 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
41 | * POSSIBILITY OF SUCH DAMAGES. | ||
42 | */ | ||
43 | |||
44 | #include <acpi/acpi.h> | ||
45 | #include "accommon.h" | ||
46 | #include "acnamesp.h" | ||
47 | #include "acpredef.h" | ||
48 | |||
49 | #define _COMPONENT ACPI_NAMESPACE | ||
50 | ACPI_MODULE_NAME("nsrepair") | ||
51 | |||
52 | /******************************************************************************* | ||
53 | * | ||
54 | * FUNCTION: acpi_ns_repair_object | ||
55 | * | ||
56 | * PARAMETERS: Data - Pointer to validation data structure | ||
57 | * expected_btypes - Object types expected | ||
58 | * package_index - Index of object within parent package (if | ||
59 | * applicable - ACPI_NOT_PACKAGE_ELEMENT | ||
60 | * otherwise) | ||
61 | * return_object_ptr - Pointer to the object returned from the | ||
62 | * evaluation of a method or object | ||
63 | * | ||
64 | * RETURN: Status. AE_OK if repair was successful. | ||
65 | * | ||
66 | * DESCRIPTION: Attempt to repair/convert a return object of a type that was | ||
67 | * not expected. | ||
68 | * | ||
69 | ******************************************************************************/ | ||
70 | acpi_status | ||
71 | acpi_ns_repair_object(struct acpi_predefined_data *data, | ||
72 | u32 expected_btypes, | ||
73 | u32 package_index, | ||
74 | union acpi_operand_object **return_object_ptr) | ||
75 | { | ||
76 | union acpi_operand_object *return_object = *return_object_ptr; | ||
77 | union acpi_operand_object *new_object; | ||
78 | acpi_size length; | ||
79 | |||
80 | switch (return_object->common.type) { | ||
81 | case ACPI_TYPE_BUFFER: | ||
82 | |||
83 | /* Does the method/object legally return a string? */ | ||
84 | |||
85 | if (!(expected_btypes & ACPI_RTYPE_STRING)) { | ||
86 | return (AE_AML_OPERAND_TYPE); | ||
87 | } | ||
88 | |||
89 | /* | ||
90 | * Have a Buffer, expected a String, convert. Use a to_string | ||
91 | * conversion, no transform performed on the buffer data. The best | ||
92 | * example of this is the _BIF method, where the string data from | ||
93 | * the battery is often (incorrectly) returned as buffer object(s). | ||
94 | */ | ||
95 | length = 0; | ||
96 | while ((length < return_object->buffer.length) && | ||
97 | (return_object->buffer.pointer[length])) { | ||
98 | length++; | ||
99 | } | ||
100 | |||
101 | /* Allocate a new string object */ | ||
102 | |||
103 | new_object = acpi_ut_create_string_object(length); | ||
104 | if (!new_object) { | ||
105 | return (AE_NO_MEMORY); | ||
106 | } | ||
107 | |||
108 | /* | ||
109 | * Copy the raw buffer data with no transform. String is already NULL | ||
110 | * terminated at Length+1. | ||
111 | */ | ||
112 | ACPI_MEMCPY(new_object->string.pointer, | ||
113 | return_object->buffer.pointer, length); | ||
114 | |||
115 | /* | ||
116 | * If the original object is a package element, we need to: | ||
117 | * 1. Set the reference count of the new object to match the | ||
118 | * reference count of the old object. | ||
119 | * 2. Decrement the reference count of the original object. | ||
120 | */ | ||
121 | if (package_index != ACPI_NOT_PACKAGE_ELEMENT) { | ||
122 | new_object->common.reference_count = | ||
123 | return_object->common.reference_count; | ||
124 | |||
125 | if (return_object->common.reference_count > 1) { | ||
126 | return_object->common.reference_count--; | ||
127 | } | ||
128 | |||
129 | ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, | ||
130 | data->node_flags, | ||
131 | "Converted Buffer to expected String at index %u", | ||
132 | package_index)); | ||
133 | } else { | ||
134 | ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, | ||
135 | data->node_flags, | ||
136 | "Converted Buffer to expected String")); | ||
137 | } | ||
138 | |||
139 | /* Delete old object, install the new return object */ | ||
140 | |||
141 | acpi_ut_remove_reference(return_object); | ||
142 | *return_object_ptr = new_object; | ||
143 | data->flags |= ACPI_OBJECT_REPAIRED; | ||
144 | return (AE_OK); | ||
145 | |||
146 | default: | ||
147 | break; | ||
148 | } | ||
149 | |||
150 | return (AE_AML_OPERAND_TYPE); | ||
151 | } | ||
152 | |||
153 | /******************************************************************************* | ||
154 | * | ||
155 | * FUNCTION: acpi_ns_repair_package_list | ||
156 | * | ||
157 | * PARAMETERS: Data - Pointer to validation data structure | ||
158 | * obj_desc_ptr - Pointer to the object to repair. The new | ||
159 | * package object is returned here, | ||
160 | * overwriting the old object. | ||
161 | * | ||
162 | * RETURN: Status, new object in *obj_desc_ptr | ||
163 | * | ||
164 | * DESCRIPTION: Repair a common problem with objects that are defined to return | ||
165 | * a variable-length Package of Packages. If the variable-length | ||
166 | * is one, some BIOS code mistakenly simply declares a single | ||
167 | * Package instead of a Package with one sub-Package. This | ||
168 | * function attempts to repair this error by wrapping a Package | ||
169 | * object around the original Package, creating the correct | ||
170 | * Package with one sub-Package. | ||
171 | * | ||
172 | * Names that can be repaired in this manner include: | ||
173 | * _ALR, _CSD, _HPX, _MLS, _PRT, _PSS, _TRT, TSS | ||
174 | * | ||
175 | ******************************************************************************/ | ||
176 | |||
177 | acpi_status | ||
178 | acpi_ns_repair_package_list(struct acpi_predefined_data *data, | ||
179 | union acpi_operand_object **obj_desc_ptr) | ||
180 | { | ||
181 | union acpi_operand_object *pkg_obj_desc; | ||
182 | |||
183 | /* | ||
184 | * Create the new outer package and populate it. The new package will | ||
185 | * have a single element, the lone subpackage. | ||
186 | */ | ||
187 | pkg_obj_desc = acpi_ut_create_package_object(1); | ||
188 | if (!pkg_obj_desc) { | ||
189 | return (AE_NO_MEMORY); | ||
190 | } | ||
191 | |||
192 | pkg_obj_desc->package.elements[0] = *obj_desc_ptr; | ||
193 | |||
194 | /* Return the new object in the object pointer */ | ||
195 | |||
196 | *obj_desc_ptr = pkg_obj_desc; | ||
197 | data->flags |= ACPI_OBJECT_REPAIRED; | ||
198 | |||
199 | ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags, | ||
200 | "Incorrectly formed Package, attempting repair")); | ||
201 | |||
202 | return (AE_OK); | ||
203 | } | ||
diff --git a/drivers/acpi/acpica/nssearch.c b/drivers/acpi/acpica/nssearch.c index f9b4f51bf8f2..7e865639a928 100644 --- a/drivers/acpi/acpica/nssearch.c +++ b/drivers/acpi/acpica/nssearch.c | |||
@@ -45,6 +45,10 @@ | |||
45 | #include "accommon.h" | 45 | #include "accommon.h" |
46 | #include "acnamesp.h" | 46 | #include "acnamesp.h" |
47 | 47 | ||
48 | #ifdef ACPI_ASL_COMPILER | ||
49 | #include "amlcode.h" | ||
50 | #endif | ||
51 | |||
48 | #define _COMPONENT ACPI_NAMESPACE | 52 | #define _COMPONENT ACPI_NAMESPACE |
49 | ACPI_MODULE_NAME("nssearch") | 53 | ACPI_MODULE_NAME("nssearch") |
50 | 54 | ||
diff --git a/drivers/acpi/acpica/nsutils.c b/drivers/acpi/acpica/nsutils.c index 78277ed08339..ea55ab4f9849 100644 --- a/drivers/acpi/acpica/nsutils.c +++ b/drivers/acpi/acpica/nsutils.c | |||
@@ -88,7 +88,8 @@ acpi_ns_report_error(const char *module_name, | |||
88 | 88 | ||
89 | /* There is a non-ascii character in the name */ | 89 | /* There is a non-ascii character in the name */ |
90 | 90 | ||
91 | ACPI_MOVE_32_TO_32(&bad_name, internal_name); | 91 | ACPI_MOVE_32_TO_32(&bad_name, |
92 | ACPI_CAST_PTR(u32, internal_name)); | ||
92 | acpi_os_printf("[0x%4.4X] (NON-ASCII)", bad_name); | 93 | acpi_os_printf("[0x%4.4X] (NON-ASCII)", bad_name); |
93 | } else { | 94 | } else { |
94 | /* Convert path to external format */ | 95 | /* Convert path to external format */ |
@@ -836,7 +837,7 @@ acpi_ns_get_node(struct acpi_namespace_node *prefix_node, | |||
836 | acpi_status status; | 837 | acpi_status status; |
837 | char *internal_path; | 838 | char *internal_path; |
838 | 839 | ||
839 | ACPI_FUNCTION_TRACE_PTR(ns_get_node, pathname); | 840 | ACPI_FUNCTION_TRACE_PTR(ns_get_node, ACPI_CAST_PTR(char, pathname)); |
840 | 841 | ||
841 | if (!pathname) { | 842 | if (!pathname) { |
842 | *return_node = prefix_node; | 843 | *return_node = prefix_node; |
diff --git a/drivers/acpi/acpica/nswalk.c b/drivers/acpi/acpica/nswalk.c index 83e3aa6d4b9b..35539df5c75d 100644 --- a/drivers/acpi/acpica/nswalk.c +++ b/drivers/acpi/acpica/nswalk.c | |||
@@ -52,8 +52,7 @@ ACPI_MODULE_NAME("nswalk") | |||
52 | * | 52 | * |
53 | * FUNCTION: acpi_ns_get_next_node | 53 | * FUNCTION: acpi_ns_get_next_node |
54 | * | 54 | * |
55 | * PARAMETERS: Type - Type of node to be searched for | 55 | * PARAMETERS: parent_node - Parent node whose children we are |
56 | * parent_node - Parent node whose children we are | ||
57 | * getting | 56 | * getting |
58 | * child_node - Previous child that was found. | 57 | * child_node - Previous child that was found. |
59 | * The NEXT child will be returned | 58 | * The NEXT child will be returned |
@@ -66,27 +65,68 @@ ACPI_MODULE_NAME("nswalk") | |||
66 | * within Scope is returned. | 65 | * within Scope is returned. |
67 | * | 66 | * |
68 | ******************************************************************************/ | 67 | ******************************************************************************/ |
69 | struct acpi_namespace_node *acpi_ns_get_next_node(acpi_object_type type, struct acpi_namespace_node | 68 | struct acpi_namespace_node *acpi_ns_get_next_node(struct acpi_namespace_node |
70 | *parent_node, struct acpi_namespace_node | 69 | *parent_node, |
70 | struct acpi_namespace_node | ||
71 | *child_node) | 71 | *child_node) |
72 | { | 72 | { |
73 | struct acpi_namespace_node *next_node = NULL; | ||
74 | |||
75 | ACPI_FUNCTION_ENTRY(); | 73 | ACPI_FUNCTION_ENTRY(); |
76 | 74 | ||
77 | if (!child_node) { | 75 | if (!child_node) { |
78 | 76 | ||
79 | /* It's really the parent's _scope_ that we want */ | 77 | /* It's really the parent's _scope_ that we want */ |
80 | 78 | ||
81 | next_node = parent_node->child; | 79 | return parent_node->child; |
82 | } | 80 | } |
83 | 81 | ||
84 | else { | 82 | /* |
85 | /* Start search at the NEXT node */ | 83 | * Get the next node. |
86 | 84 | * | |
87 | next_node = acpi_ns_get_next_valid_node(child_node); | 85 | * If we are at the end of this peer list, return NULL |
86 | */ | ||
87 | if (child_node->flags & ANOBJ_END_OF_PEER_LIST) { | ||
88 | return NULL; | ||
88 | } | 89 | } |
89 | 90 | ||
91 | /* Otherwise just return the next peer */ | ||
92 | |||
93 | return child_node->peer; | ||
94 | } | ||
95 | |||
96 | /******************************************************************************* | ||
97 | * | ||
98 | * FUNCTION: acpi_ns_get_next_node_typed | ||
99 | * | ||
100 | * PARAMETERS: Type - Type of node to be searched for | ||
101 | * parent_node - Parent node whose children we are | ||
102 | * getting | ||
103 | * child_node - Previous child that was found. | ||
104 | * The NEXT child will be returned | ||
105 | * | ||
106 | * RETURN: struct acpi_namespace_node - Pointer to the NEXT child or NULL if | ||
107 | * none is found. | ||
108 | * | ||
109 | * DESCRIPTION: Return the next peer node within the namespace. If Handle | ||
110 | * is valid, Scope is ignored. Otherwise, the first node | ||
111 | * within Scope is returned. | ||
112 | * | ||
113 | ******************************************************************************/ | ||
114 | |||
115 | struct acpi_namespace_node *acpi_ns_get_next_node_typed(acpi_object_type type, | ||
116 | struct | ||
117 | acpi_namespace_node | ||
118 | *parent_node, | ||
119 | struct | ||
120 | acpi_namespace_node | ||
121 | *child_node) | ||
122 | { | ||
123 | struct acpi_namespace_node *next_node = NULL; | ||
124 | |||
125 | ACPI_FUNCTION_ENTRY(); | ||
126 | |||
127 | next_node = acpi_ns_get_next_node(parent_node, child_node); | ||
128 | |||
129 | |||
90 | /* If any type is OK, we are done */ | 130 | /* If any type is OK, we are done */ |
91 | 131 | ||
92 | if (type == ACPI_TYPE_ANY) { | 132 | if (type == ACPI_TYPE_ANY) { |
@@ -186,9 +226,7 @@ acpi_ns_walk_namespace(acpi_object_type type, | |||
186 | /* Get the next node in this scope. Null if not found */ | 226 | /* Get the next node in this scope. Null if not found */ |
187 | 227 | ||
188 | status = AE_OK; | 228 | status = AE_OK; |
189 | child_node = | 229 | child_node = acpi_ns_get_next_node(parent_node, child_node); |
190 | acpi_ns_get_next_node(ACPI_TYPE_ANY, parent_node, | ||
191 | child_node); | ||
192 | if (child_node) { | 230 | if (child_node) { |
193 | 231 | ||
194 | /* Found next child, get the type if we are not searching for ANY */ | 232 | /* Found next child, get the type if we are not searching for ANY */ |
@@ -269,8 +307,7 @@ acpi_ns_walk_namespace(acpi_object_type type, | |||
269 | * function has specified that the maximum depth has been reached. | 307 | * function has specified that the maximum depth has been reached. |
270 | */ | 308 | */ |
271 | if ((level < max_depth) && (status != AE_CTRL_DEPTH)) { | 309 | if ((level < max_depth) && (status != AE_CTRL_DEPTH)) { |
272 | if (acpi_ns_get_next_node | 310 | if (child_node->child) { |
273 | (ACPI_TYPE_ANY, child_node, NULL)) { | ||
274 | 311 | ||
275 | /* There is at least one child of this node, visit it */ | 312 | /* There is at least one child of this node, visit it */ |
276 | 313 | ||
diff --git a/drivers/acpi/acpica/nsxfeval.c b/drivers/acpi/acpica/nsxfeval.c index daf4ad37896d..4929dbdbc8f0 100644 --- a/drivers/acpi/acpica/nsxfeval.c +++ b/drivers/acpi/acpica/nsxfeval.c | |||
@@ -535,10 +535,11 @@ acpi_ns_get_device_callback(acpi_handle obj_handle, | |||
535 | acpi_status status; | 535 | acpi_status status; |
536 | struct acpi_namespace_node *node; | 536 | struct acpi_namespace_node *node; |
537 | u32 flags; | 537 | u32 flags; |
538 | struct acpica_device_id hid; | 538 | struct acpica_device_id *hid; |
539 | struct acpi_compatible_id_list *cid; | 539 | struct acpica_device_id_list *cid; |
540 | u32 i; | 540 | u32 i; |
541 | int found; | 541 | u8 found; |
542 | int no_match; | ||
542 | 543 | ||
543 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | 544 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); |
544 | if (ACPI_FAILURE(status)) { | 545 | if (ACPI_FAILURE(status)) { |
@@ -582,10 +583,14 @@ acpi_ns_get_device_callback(acpi_handle obj_handle, | |||
582 | return (AE_CTRL_DEPTH); | 583 | return (AE_CTRL_DEPTH); |
583 | } | 584 | } |
584 | 585 | ||
585 | if (ACPI_STRNCMP(hid.value, info->hid, sizeof(hid.value)) != 0) { | 586 | no_match = ACPI_STRCMP(hid->string, info->hid); |
586 | 587 | ACPI_FREE(hid); | |
587 | /* Get the list of Compatible IDs */ | ||
588 | 588 | ||
589 | if (no_match) { | ||
590 | /* | ||
591 | * HID does not match, attempt match within the | ||
592 | * list of Compatible IDs (CIDs) | ||
593 | */ | ||
589 | status = acpi_ut_execute_CID(node, &cid); | 594 | status = acpi_ut_execute_CID(node, &cid); |
590 | if (status == AE_NOT_FOUND) { | 595 | if (status == AE_NOT_FOUND) { |
591 | return (AE_OK); | 596 | return (AE_OK); |
@@ -597,10 +602,8 @@ acpi_ns_get_device_callback(acpi_handle obj_handle, | |||
597 | 602 | ||
598 | found = 0; | 603 | found = 0; |
599 | for (i = 0; i < cid->count; i++) { | 604 | for (i = 0; i < cid->count; i++) { |
600 | if (ACPI_STRNCMP(cid->id[i].value, info->hid, | 605 | if (ACPI_STRCMP(cid->ids[i].string, info->hid) |
601 | sizeof(struct | 606 | == 0) { |
602 | acpi_compatible_id)) == | ||
603 | 0) { | ||
604 | found = 1; | 607 | found = 1; |
605 | break; | 608 | break; |
606 | } | 609 | } |
diff --git a/drivers/acpi/acpica/nsxfname.c b/drivers/acpi/acpica/nsxfname.c index 9589fea24997..ddc84af6336e 100644 --- a/drivers/acpi/acpica/nsxfname.c +++ b/drivers/acpi/acpica/nsxfname.c | |||
@@ -45,10 +45,17 @@ | |||
45 | #include <acpi/acpi.h> | 45 | #include <acpi/acpi.h> |
46 | #include "accommon.h" | 46 | #include "accommon.h" |
47 | #include "acnamesp.h" | 47 | #include "acnamesp.h" |
48 | #include "acparser.h" | ||
49 | #include "amlcode.h" | ||
48 | 50 | ||
49 | #define _COMPONENT ACPI_NAMESPACE | 51 | #define _COMPONENT ACPI_NAMESPACE |
50 | ACPI_MODULE_NAME("nsxfname") | 52 | ACPI_MODULE_NAME("nsxfname") |
51 | 53 | ||
54 | /* Local prototypes */ | ||
55 | static char *acpi_ns_copy_device_id(struct acpica_device_id *dest, | ||
56 | struct acpica_device_id *source, | ||
57 | char *string_area); | ||
58 | |||
52 | /****************************************************************************** | 59 | /****************************************************************************** |
53 | * | 60 | * |
54 | * FUNCTION: acpi_get_handle | 61 | * FUNCTION: acpi_get_handle |
@@ -66,6 +73,7 @@ ACPI_MODULE_NAME("nsxfname") | |||
66 | * namespace handle. | 73 | * namespace handle. |
67 | * | 74 | * |
68 | ******************************************************************************/ | 75 | ******************************************************************************/ |
76 | |||
69 | acpi_status | 77 | acpi_status |
70 | acpi_get_handle(acpi_handle parent, | 78 | acpi_get_handle(acpi_handle parent, |
71 | acpi_string pathname, acpi_handle * ret_handle) | 79 | acpi_string pathname, acpi_handle * ret_handle) |
@@ -208,10 +216,38 @@ ACPI_EXPORT_SYMBOL(acpi_get_name) | |||
208 | 216 | ||
209 | /****************************************************************************** | 217 | /****************************************************************************** |
210 | * | 218 | * |
219 | * FUNCTION: acpi_ns_copy_device_id | ||
220 | * | ||
221 | * PARAMETERS: Dest - Pointer to the destination DEVICE_ID | ||
222 | * Source - Pointer to the source DEVICE_ID | ||
223 | * string_area - Pointer to where to copy the dest string | ||
224 | * | ||
225 | * RETURN: Pointer to the next string area | ||
226 | * | ||
227 | * DESCRIPTION: Copy a single DEVICE_ID, including the string data. | ||
228 | * | ||
229 | ******************************************************************************/ | ||
230 | static char *acpi_ns_copy_device_id(struct acpica_device_id *dest, | ||
231 | struct acpica_device_id *source, | ||
232 | char *string_area) | ||
233 | { | ||
234 | /* Create the destination DEVICE_ID */ | ||
235 | |||
236 | dest->string = string_area; | ||
237 | dest->length = source->length; | ||
238 | |||
239 | /* Copy actual string and return a pointer to the next string area */ | ||
240 | |||
241 | ACPI_MEMCPY(string_area, source->string, source->length); | ||
242 | return (string_area + source->length); | ||
243 | } | ||
244 | |||
245 | /****************************************************************************** | ||
246 | * | ||
211 | * FUNCTION: acpi_get_object_info | 247 | * FUNCTION: acpi_get_object_info |
212 | * | 248 | * |
213 | * PARAMETERS: Handle - Object Handle | 249 | * PARAMETERS: Handle - Object Handle |
214 | * Buffer - Where the info is returned | 250 | * return_buffer - Where the info is returned |
215 | * | 251 | * |
216 | * RETURN: Status | 252 | * RETURN: Status |
217 | * | 253 | * |
@@ -219,33 +255,37 @@ ACPI_EXPORT_SYMBOL(acpi_get_name) | |||
219 | * namespace node and possibly by running several standard | 255 | * namespace node and possibly by running several standard |
220 | * control methods (Such as in the case of a device.) | 256 | * control methods (Such as in the case of a device.) |
221 | * | 257 | * |
258 | * For Device and Processor objects, run the Device _HID, _UID, _CID, _STA, | ||
259 | * _ADR, _sx_w, and _sx_d methods. | ||
260 | * | ||
261 | * Note: Allocates the return buffer, must be freed by the caller. | ||
262 | * | ||
222 | ******************************************************************************/ | 263 | ******************************************************************************/ |
264 | |||
223 | acpi_status | 265 | acpi_status |
224 | acpi_get_object_info(acpi_handle handle, struct acpi_buffer * buffer) | 266 | acpi_get_object_info(acpi_handle handle, |
267 | struct acpi_device_info **return_buffer) | ||
225 | { | 268 | { |
226 | acpi_status status; | ||
227 | struct acpi_namespace_node *node; | 269 | struct acpi_namespace_node *node; |
228 | struct acpi_device_info *info; | 270 | struct acpi_device_info *info; |
229 | struct acpi_device_info *return_info; | 271 | struct acpica_device_id_list *cid_list = NULL; |
230 | struct acpi_compatible_id_list *cid_list = NULL; | 272 | struct acpica_device_id *hid = NULL; |
231 | acpi_size size; | 273 | struct acpica_device_id *uid = NULL; |
274 | char *next_id_string; | ||
275 | acpi_object_type type; | ||
276 | acpi_name name; | ||
277 | u8 param_count = 0; | ||
278 | u8 valid = 0; | ||
279 | u32 info_size; | ||
280 | u32 i; | ||
281 | acpi_status status; | ||
232 | 282 | ||
233 | /* Parameter validation */ | 283 | /* Parameter validation */ |
234 | 284 | ||
235 | if (!handle || !buffer) { | 285 | if (!handle || !return_buffer) { |
236 | return (AE_BAD_PARAMETER); | 286 | return (AE_BAD_PARAMETER); |
237 | } | 287 | } |
238 | 288 | ||
239 | status = acpi_ut_validate_buffer(buffer); | ||
240 | if (ACPI_FAILURE(status)) { | ||
241 | return (status); | ||
242 | } | ||
243 | |||
244 | info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_device_info)); | ||
245 | if (!info) { | ||
246 | return (AE_NO_MEMORY); | ||
247 | } | ||
248 | |||
249 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | 289 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); |
250 | if (ACPI_FAILURE(status)) { | 290 | if (ACPI_FAILURE(status)) { |
251 | goto cleanup; | 291 | goto cleanup; |
@@ -254,66 +294,91 @@ acpi_get_object_info(acpi_handle handle, struct acpi_buffer * buffer) | |||
254 | node = acpi_ns_map_handle_to_node(handle); | 294 | node = acpi_ns_map_handle_to_node(handle); |
255 | if (!node) { | 295 | if (!node) { |
256 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | 296 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); |
257 | status = AE_BAD_PARAMETER; | 297 | return (AE_BAD_PARAMETER); |
258 | goto cleanup; | ||
259 | } | 298 | } |
260 | 299 | ||
261 | /* Init return structure */ | 300 | /* Get the namespace node data while the namespace is locked */ |
262 | |||
263 | size = sizeof(struct acpi_device_info); | ||
264 | 301 | ||
265 | info->type = node->type; | 302 | info_size = sizeof(struct acpi_device_info); |
266 | info->name = node->name.integer; | 303 | type = node->type; |
267 | info->valid = 0; | 304 | name = node->name.integer; |
268 | 305 | ||
269 | if (node->type == ACPI_TYPE_METHOD) { | 306 | if (node->type == ACPI_TYPE_METHOD) { |
270 | info->param_count = node->object->method.param_count; | 307 | param_count = node->object->method.param_count; |
271 | } | 308 | } |
272 | 309 | ||
273 | status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | 310 | status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); |
274 | if (ACPI_FAILURE(status)) { | 311 | if (ACPI_FAILURE(status)) { |
275 | goto cleanup; | 312 | return (status); |
276 | } | 313 | } |
277 | 314 | ||
278 | /* If not a device, we are all done */ | 315 | if ((type == ACPI_TYPE_DEVICE) || (type == ACPI_TYPE_PROCESSOR)) { |
279 | |||
280 | if (info->type == ACPI_TYPE_DEVICE) { | ||
281 | /* | 316 | /* |
282 | * Get extra info for ACPI Devices objects only: | 317 | * Get extra info for ACPI Device/Processor objects only: |
283 | * Run the Device _HID, _UID, _CID, _STA, _ADR and _sx_d methods. | 318 | * Run the Device _HID, _UID, and _CID methods. |
284 | * | 319 | * |
285 | * Note: none of these methods are required, so they may or may | 320 | * Note: none of these methods are required, so they may or may |
286 | * not be present for this device. The Info->Valid bitfield is used | 321 | * not be present for this device. The Info->Valid bitfield is used |
287 | * to indicate which methods were found and ran successfully. | 322 | * to indicate which methods were found and run successfully. |
288 | */ | 323 | */ |
289 | 324 | ||
290 | /* Execute the Device._HID method */ | 325 | /* Execute the Device._HID method */ |
291 | 326 | ||
292 | status = acpi_ut_execute_HID(node, &info->hardware_id); | 327 | status = acpi_ut_execute_HID(node, &hid); |
293 | if (ACPI_SUCCESS(status)) { | 328 | if (ACPI_SUCCESS(status)) { |
294 | info->valid |= ACPI_VALID_HID; | 329 | info_size += hid->length; |
330 | valid |= ACPI_VALID_HID; | ||
295 | } | 331 | } |
296 | 332 | ||
297 | /* Execute the Device._UID method */ | 333 | /* Execute the Device._UID method */ |
298 | 334 | ||
299 | status = acpi_ut_execute_UID(node, &info->unique_id); | 335 | status = acpi_ut_execute_UID(node, &uid); |
300 | if (ACPI_SUCCESS(status)) { | 336 | if (ACPI_SUCCESS(status)) { |
301 | info->valid |= ACPI_VALID_UID; | 337 | info_size += uid->length; |
338 | valid |= ACPI_VALID_UID; | ||
302 | } | 339 | } |
303 | 340 | ||
304 | /* Execute the Device._CID method */ | 341 | /* Execute the Device._CID method */ |
305 | 342 | ||
306 | status = acpi_ut_execute_CID(node, &cid_list); | 343 | status = acpi_ut_execute_CID(node, &cid_list); |
307 | if (ACPI_SUCCESS(status)) { | 344 | if (ACPI_SUCCESS(status)) { |
308 | size += cid_list->size; | 345 | |
309 | info->valid |= ACPI_VALID_CID; | 346 | /* Add size of CID strings and CID pointer array */ |
347 | |||
348 | info_size += | ||
349 | (cid_list->list_size - | ||
350 | sizeof(struct acpica_device_id_list)); | ||
351 | valid |= ACPI_VALID_CID; | ||
310 | } | 352 | } |
353 | } | ||
354 | |||
355 | /* | ||
356 | * Now that we have the variable-length data, we can allocate the | ||
357 | * return buffer | ||
358 | */ | ||
359 | info = ACPI_ALLOCATE_ZEROED(info_size); | ||
360 | if (!info) { | ||
361 | status = AE_NO_MEMORY; | ||
362 | goto cleanup; | ||
363 | } | ||
364 | |||
365 | /* Get the fixed-length data */ | ||
366 | |||
367 | if ((type == ACPI_TYPE_DEVICE) || (type == ACPI_TYPE_PROCESSOR)) { | ||
368 | /* | ||
369 | * Get extra info for ACPI Device/Processor objects only: | ||
370 | * Run the _STA, _ADR and, sx_w, and _sx_d methods. | ||
371 | * | ||
372 | * Note: none of these methods are required, so they may or may | ||
373 | * not be present for this device. The Info->Valid bitfield is used | ||
374 | * to indicate which methods were found and run successfully. | ||
375 | */ | ||
311 | 376 | ||
312 | /* Execute the Device._STA method */ | 377 | /* Execute the Device._STA method */ |
313 | 378 | ||
314 | status = acpi_ut_execute_STA(node, &info->current_status); | 379 | status = acpi_ut_execute_STA(node, &info->current_status); |
315 | if (ACPI_SUCCESS(status)) { | 380 | if (ACPI_SUCCESS(status)) { |
316 | info->valid |= ACPI_VALID_STA; | 381 | valid |= ACPI_VALID_STA; |
317 | } | 382 | } |
318 | 383 | ||
319 | /* Execute the Device._ADR method */ | 384 | /* Execute the Device._ADR method */ |
@@ -321,36 +386,100 @@ acpi_get_object_info(acpi_handle handle, struct acpi_buffer * buffer) | |||
321 | status = acpi_ut_evaluate_numeric_object(METHOD_NAME__ADR, node, | 386 | status = acpi_ut_evaluate_numeric_object(METHOD_NAME__ADR, node, |
322 | &info->address); | 387 | &info->address); |
323 | if (ACPI_SUCCESS(status)) { | 388 | if (ACPI_SUCCESS(status)) { |
324 | info->valid |= ACPI_VALID_ADR; | 389 | valid |= ACPI_VALID_ADR; |
390 | } | ||
391 | |||
392 | /* Execute the Device._sx_w methods */ | ||
393 | |||
394 | status = acpi_ut_execute_power_methods(node, | ||
395 | acpi_gbl_lowest_dstate_names, | ||
396 | ACPI_NUM_sx_w_METHODS, | ||
397 | info->lowest_dstates); | ||
398 | if (ACPI_SUCCESS(status)) { | ||
399 | valid |= ACPI_VALID_SXWS; | ||
325 | } | 400 | } |
326 | 401 | ||
327 | /* Execute the Device._sx_d methods */ | 402 | /* Execute the Device._sx_d methods */ |
328 | 403 | ||
329 | status = acpi_ut_execute_sxds(node, info->highest_dstates); | 404 | status = acpi_ut_execute_power_methods(node, |
405 | acpi_gbl_highest_dstate_names, | ||
406 | ACPI_NUM_sx_d_METHODS, | ||
407 | info->highest_dstates); | ||
330 | if (ACPI_SUCCESS(status)) { | 408 | if (ACPI_SUCCESS(status)) { |
331 | info->valid |= ACPI_VALID_SXDS; | 409 | valid |= ACPI_VALID_SXDS; |
332 | } | 410 | } |
333 | } | 411 | } |
334 | 412 | ||
335 | /* Validate/Allocate/Clear caller buffer */ | 413 | /* |
414 | * Create a pointer to the string area of the return buffer. | ||
415 | * Point to the end of the base struct acpi_device_info structure. | ||
416 | */ | ||
417 | next_id_string = ACPI_CAST_PTR(char, info->compatible_id_list.ids); | ||
418 | if (cid_list) { | ||
336 | 419 | ||
337 | status = acpi_ut_initialize_buffer(buffer, size); | 420 | /* Point past the CID DEVICE_ID array */ |
338 | if (ACPI_FAILURE(status)) { | 421 | |
339 | goto cleanup; | 422 | next_id_string += |
423 | ((acpi_size) cid_list->count * | ||
424 | sizeof(struct acpica_device_id)); | ||
340 | } | 425 | } |
341 | 426 | ||
342 | /* Populate the return buffer */ | 427 | /* |
428 | * Copy the HID, UID, and CIDs to the return buffer. The variable-length | ||
429 | * strings are copied to the reserved area at the end of the buffer. | ||
430 | * | ||
431 | * For HID and CID, check if the ID is a PCI Root Bridge. | ||
432 | */ | ||
433 | if (hid) { | ||
434 | next_id_string = acpi_ns_copy_device_id(&info->hardware_id, | ||
435 | hid, next_id_string); | ||
436 | |||
437 | if (acpi_ut_is_pci_root_bridge(hid->string)) { | ||
438 | info->flags |= ACPI_PCI_ROOT_BRIDGE; | ||
439 | } | ||
440 | } | ||
343 | 441 | ||
344 | return_info = buffer->pointer; | 442 | if (uid) { |
345 | ACPI_MEMCPY(return_info, info, sizeof(struct acpi_device_info)); | 443 | next_id_string = acpi_ns_copy_device_id(&info->unique_id, |
444 | uid, next_id_string); | ||
445 | } | ||
346 | 446 | ||
347 | if (cid_list) { | 447 | if (cid_list) { |
348 | ACPI_MEMCPY(&return_info->compatibility_id, cid_list, | 448 | info->compatible_id_list.count = cid_list->count; |
349 | cid_list->size); | 449 | info->compatible_id_list.list_size = cid_list->list_size; |
450 | |||
451 | /* Copy each CID */ | ||
452 | |||
453 | for (i = 0; i < cid_list->count; i++) { | ||
454 | next_id_string = | ||
455 | acpi_ns_copy_device_id(&info->compatible_id_list. | ||
456 | ids[i], &cid_list->ids[i], | ||
457 | next_id_string); | ||
458 | |||
459 | if (acpi_ut_is_pci_root_bridge(cid_list->ids[i].string)) { | ||
460 | info->flags |= ACPI_PCI_ROOT_BRIDGE; | ||
461 | } | ||
462 | } | ||
350 | } | 463 | } |
351 | 464 | ||
465 | /* Copy the fixed-length data */ | ||
466 | |||
467 | info->info_size = info_size; | ||
468 | info->type = type; | ||
469 | info->name = name; | ||
470 | info->param_count = param_count; | ||
471 | info->valid = valid; | ||
472 | |||
473 | *return_buffer = info; | ||
474 | status = AE_OK; | ||
475 | |||
352 | cleanup: | 476 | cleanup: |
353 | ACPI_FREE(info); | 477 | if (hid) { |
478 | ACPI_FREE(hid); | ||
479 | } | ||
480 | if (uid) { | ||
481 | ACPI_FREE(uid); | ||
482 | } | ||
354 | if (cid_list) { | 483 | if (cid_list) { |
355 | ACPI_FREE(cid_list); | 484 | ACPI_FREE(cid_list); |
356 | } | 485 | } |
@@ -358,3 +487,151 @@ acpi_get_object_info(acpi_handle handle, struct acpi_buffer * buffer) | |||
358 | } | 487 | } |
359 | 488 | ||
360 | ACPI_EXPORT_SYMBOL(acpi_get_object_info) | 489 | ACPI_EXPORT_SYMBOL(acpi_get_object_info) |
490 | |||
491 | /****************************************************************************** | ||
492 | * | ||
493 | * FUNCTION: acpi_install_method | ||
494 | * | ||
495 | * PARAMETERS: Buffer - An ACPI table containing one control method | ||
496 | * | ||
497 | * RETURN: Status | ||
498 | * | ||
499 | * DESCRIPTION: Install a control method into the namespace. If the method | ||
500 | * name already exists in the namespace, it is overwritten. The | ||
501 | * input buffer must contain a valid DSDT or SSDT containing a | ||
502 | * single control method. | ||
503 | * | ||
504 | ******************************************************************************/ | ||
505 | acpi_status acpi_install_method(u8 *buffer) | ||
506 | { | ||
507 | struct acpi_table_header *table = | ||
508 | ACPI_CAST_PTR(struct acpi_table_header, buffer); | ||
509 | u8 *aml_buffer; | ||
510 | u8 *aml_start; | ||
511 | char *path; | ||
512 | struct acpi_namespace_node *node; | ||
513 | union acpi_operand_object *method_obj; | ||
514 | struct acpi_parse_state parser_state; | ||
515 | u32 aml_length; | ||
516 | u16 opcode; | ||
517 | u8 method_flags; | ||
518 | acpi_status status; | ||
519 | |||
520 | /* Parameter validation */ | ||
521 | |||
522 | if (!buffer) { | ||
523 | return AE_BAD_PARAMETER; | ||
524 | } | ||
525 | |||
526 | /* Table must be a DSDT or SSDT */ | ||
527 | |||
528 | if (!ACPI_COMPARE_NAME(table->signature, ACPI_SIG_DSDT) && | ||
529 | !ACPI_COMPARE_NAME(table->signature, ACPI_SIG_SSDT)) { | ||
530 | return AE_BAD_HEADER; | ||
531 | } | ||
532 | |||
533 | /* First AML opcode in the table must be a control method */ | ||
534 | |||
535 | parser_state.aml = buffer + sizeof(struct acpi_table_header); | ||
536 | opcode = acpi_ps_peek_opcode(&parser_state); | ||
537 | if (opcode != AML_METHOD_OP) { | ||
538 | return AE_BAD_PARAMETER; | ||
539 | } | ||
540 | |||
541 | /* Extract method information from the raw AML */ | ||
542 | |||
543 | parser_state.aml += acpi_ps_get_opcode_size(opcode); | ||
544 | parser_state.pkg_end = acpi_ps_get_next_package_end(&parser_state); | ||
545 | path = acpi_ps_get_next_namestring(&parser_state); | ||
546 | method_flags = *parser_state.aml++; | ||
547 | aml_start = parser_state.aml; | ||
548 | aml_length = ACPI_PTR_DIFF(parser_state.pkg_end, aml_start); | ||
549 | |||
550 | /* | ||
551 | * Allocate resources up-front. We don't want to have to delete a new | ||
552 | * node from the namespace if we cannot allocate memory. | ||
553 | */ | ||
554 | aml_buffer = ACPI_ALLOCATE(aml_length); | ||
555 | if (!aml_buffer) { | ||
556 | return AE_NO_MEMORY; | ||
557 | } | ||
558 | |||
559 | method_obj = acpi_ut_create_internal_object(ACPI_TYPE_METHOD); | ||
560 | if (!method_obj) { | ||
561 | ACPI_FREE(aml_buffer); | ||
562 | return AE_NO_MEMORY; | ||
563 | } | ||
564 | |||
565 | /* Lock namespace for acpi_ns_lookup, we may be creating a new node */ | ||
566 | |||
567 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | ||
568 | if (ACPI_FAILURE(status)) { | ||
569 | goto error_exit; | ||
570 | } | ||
571 | |||
572 | /* The lookup either returns an existing node or creates a new one */ | ||
573 | |||
574 | status = | ||
575 | acpi_ns_lookup(NULL, path, ACPI_TYPE_METHOD, ACPI_IMODE_LOAD_PASS1, | ||
576 | ACPI_NS_DONT_OPEN_SCOPE | ACPI_NS_ERROR_IF_FOUND, | ||
577 | NULL, &node); | ||
578 | |||
579 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | ||
580 | |||
581 | if (ACPI_FAILURE(status)) { /* ns_lookup */ | ||
582 | if (status != AE_ALREADY_EXISTS) { | ||
583 | goto error_exit; | ||
584 | } | ||
585 | |||
586 | /* Node existed previously, make sure it is a method node */ | ||
587 | |||
588 | if (node->type != ACPI_TYPE_METHOD) { | ||
589 | status = AE_TYPE; | ||
590 | goto error_exit; | ||
591 | } | ||
592 | } | ||
593 | |||
594 | /* Copy the method AML to the local buffer */ | ||
595 | |||
596 | ACPI_MEMCPY(aml_buffer, aml_start, aml_length); | ||
597 | |||
598 | /* Initialize the method object with the new method's information */ | ||
599 | |||
600 | method_obj->method.aml_start = aml_buffer; | ||
601 | method_obj->method.aml_length = aml_length; | ||
602 | |||
603 | method_obj->method.param_count = (u8) | ||
604 | (method_flags & AML_METHOD_ARG_COUNT); | ||
605 | |||
606 | method_obj->method.method_flags = (u8) | ||
607 | (method_flags & ~AML_METHOD_ARG_COUNT); | ||
608 | |||
609 | if (method_flags & AML_METHOD_SERIALIZED) { | ||
610 | method_obj->method.sync_level = (u8) | ||
611 | ((method_flags & AML_METHOD_SYNC_LEVEL) >> 4); | ||
612 | } | ||
613 | |||
614 | /* | ||
615 | * Now that it is complete, we can attach the new method object to | ||
616 | * the method Node (detaches/deletes any existing object) | ||
617 | */ | ||
618 | status = acpi_ns_attach_object(node, method_obj, ACPI_TYPE_METHOD); | ||
619 | |||
620 | /* | ||
621 | * Flag indicates AML buffer is dynamic, must be deleted later. | ||
622 | * Must be set only after attach above. | ||
623 | */ | ||
624 | node->flags |= ANOBJ_ALLOCATED_BUFFER; | ||
625 | |||
626 | /* Remove local reference to the method object */ | ||
627 | |||
628 | acpi_ut_remove_reference(method_obj); | ||
629 | return status; | ||
630 | |||
631 | error_exit: | ||
632 | |||
633 | ACPI_FREE(aml_buffer); | ||
634 | ACPI_FREE(method_obj); | ||
635 | return status; | ||
636 | } | ||
637 | ACPI_EXPORT_SYMBOL(acpi_install_method) | ||
diff --git a/drivers/acpi/acpica/nsxfobj.c b/drivers/acpi/acpica/nsxfobj.c index 1c7efc15225f..4071bad4458e 100644 --- a/drivers/acpi/acpica/nsxfobj.c +++ b/drivers/acpi/acpica/nsxfobj.c | |||
@@ -162,6 +162,7 @@ ACPI_EXPORT_SYMBOL(acpi_get_type) | |||
162 | acpi_status acpi_get_parent(acpi_handle handle, acpi_handle * ret_handle) | 162 | acpi_status acpi_get_parent(acpi_handle handle, acpi_handle * ret_handle) |
163 | { | 163 | { |
164 | struct acpi_namespace_node *node; | 164 | struct acpi_namespace_node *node; |
165 | struct acpi_namespace_node *parent_node; | ||
165 | acpi_status status; | 166 | acpi_status status; |
166 | 167 | ||
167 | if (!ret_handle) { | 168 | if (!ret_handle) { |
@@ -189,12 +190,12 @@ acpi_status acpi_get_parent(acpi_handle handle, acpi_handle * ret_handle) | |||
189 | 190 | ||
190 | /* Get the parent entry */ | 191 | /* Get the parent entry */ |
191 | 192 | ||
192 | *ret_handle = | 193 | parent_node = acpi_ns_get_parent_node(node); |
193 | acpi_ns_convert_entry_to_handle(acpi_ns_get_parent_node(node)); | 194 | *ret_handle = acpi_ns_convert_entry_to_handle(parent_node); |
194 | 195 | ||
195 | /* Return exception if parent is null */ | 196 | /* Return exception if parent is null */ |
196 | 197 | ||
197 | if (!acpi_ns_get_parent_node(node)) { | 198 | if (!parent_node) { |
198 | status = AE_NULL_ENTRY; | 199 | status = AE_NULL_ENTRY; |
199 | } | 200 | } |
200 | 201 | ||
@@ -268,7 +269,7 @@ acpi_get_next_object(acpi_object_type type, | |||
268 | 269 | ||
269 | /* Internal function does the real work */ | 270 | /* Internal function does the real work */ |
270 | 271 | ||
271 | node = acpi_ns_get_next_node(type, parent_node, child_node); | 272 | node = acpi_ns_get_next_node_typed(type, parent_node, child_node); |
272 | if (!node) { | 273 | if (!node) { |
273 | status = AE_NOT_FOUND; | 274 | status = AE_NOT_FOUND; |
274 | goto unlock_and_exit; | 275 | goto unlock_and_exit; |
diff --git a/drivers/acpi/acpica/psloop.c b/drivers/acpi/acpica/psloop.c index c5f6ce19a401..cd7995b3aed4 100644 --- a/drivers/acpi/acpica/psloop.c +++ b/drivers/acpi/acpica/psloop.c | |||
@@ -86,6 +86,9 @@ static acpi_status | |||
86 | acpi_ps_complete_final_op(struct acpi_walk_state *walk_state, | 86 | acpi_ps_complete_final_op(struct acpi_walk_state *walk_state, |
87 | union acpi_parse_object *op, acpi_status status); | 87 | union acpi_parse_object *op, acpi_status status); |
88 | 88 | ||
89 | static void | ||
90 | acpi_ps_link_module_code(u8 *aml_start, u32 aml_length, acpi_owner_id owner_id); | ||
91 | |||
89 | /******************************************************************************* | 92 | /******************************************************************************* |
90 | * | 93 | * |
91 | * FUNCTION: acpi_ps_get_aml_opcode | 94 | * FUNCTION: acpi_ps_get_aml_opcode |
@@ -390,6 +393,7 @@ acpi_ps_get_arguments(struct acpi_walk_state *walk_state, | |||
390 | { | 393 | { |
391 | acpi_status status = AE_OK; | 394 | acpi_status status = AE_OK; |
392 | union acpi_parse_object *arg = NULL; | 395 | union acpi_parse_object *arg = NULL; |
396 | const struct acpi_opcode_info *op_info; | ||
393 | 397 | ||
394 | ACPI_FUNCTION_TRACE_PTR(ps_get_arguments, walk_state); | 398 | ACPI_FUNCTION_TRACE_PTR(ps_get_arguments, walk_state); |
395 | 399 | ||
@@ -449,13 +453,11 @@ acpi_ps_get_arguments(struct acpi_walk_state *walk_state, | |||
449 | INCREMENT_ARG_LIST(walk_state->arg_types); | 453 | INCREMENT_ARG_LIST(walk_state->arg_types); |
450 | } | 454 | } |
451 | 455 | ||
452 | /* Special processing for certain opcodes */ | 456 | /* |
453 | 457 | * Handle executable code at "module-level". This refers to | |
454 | /* TBD (remove): Temporary mechanism to disable this code if needed */ | 458 | * executable opcodes that appear outside of any control method. |
455 | 459 | */ | |
456 | #ifdef ACPI_ENABLE_MODULE_LEVEL_CODE | 460 | if ((walk_state->pass_number <= ACPI_IMODE_LOAD_PASS2) && |
457 | |||
458 | if ((walk_state->pass_number <= ACPI_IMODE_LOAD_PASS1) && | ||
459 | ((walk_state->parse_flags & ACPI_PARSE_DISASSEMBLE) == 0)) { | 461 | ((walk_state->parse_flags & ACPI_PARSE_DISASSEMBLE) == 0)) { |
460 | /* | 462 | /* |
461 | * We want to skip If/Else/While constructs during Pass1 because we | 463 | * We want to skip If/Else/While constructs during Pass1 because we |
@@ -469,6 +471,23 @@ acpi_ps_get_arguments(struct acpi_walk_state *walk_state, | |||
469 | case AML_ELSE_OP: | 471 | case AML_ELSE_OP: |
470 | case AML_WHILE_OP: | 472 | case AML_WHILE_OP: |
471 | 473 | ||
474 | /* | ||
475 | * Currently supported module-level opcodes are: | ||
476 | * IF/ELSE/WHILE. These appear to be the most common, | ||
477 | * and easiest to support since they open an AML | ||
478 | * package. | ||
479 | */ | ||
480 | if (walk_state->pass_number == | ||
481 | ACPI_IMODE_LOAD_PASS1) { | ||
482 | acpi_ps_link_module_code(aml_op_start, | ||
483 | walk_state-> | ||
484 | parser_state. | ||
485 | pkg_end - | ||
486 | aml_op_start, | ||
487 | walk_state-> | ||
488 | owner_id); | ||
489 | } | ||
490 | |||
472 | ACPI_DEBUG_PRINT((ACPI_DB_PARSE, | 491 | ACPI_DEBUG_PRINT((ACPI_DB_PARSE, |
473 | "Pass1: Skipping an If/Else/While body\n")); | 492 | "Pass1: Skipping an If/Else/While body\n")); |
474 | 493 | ||
@@ -480,10 +499,34 @@ acpi_ps_get_arguments(struct acpi_walk_state *walk_state, | |||
480 | break; | 499 | break; |
481 | 500 | ||
482 | default: | 501 | default: |
502 | /* | ||
503 | * Check for an unsupported executable opcode at module | ||
504 | * level. We must be in PASS1, the parent must be a SCOPE, | ||
505 | * The opcode class must be EXECUTE, and the opcode must | ||
506 | * not be an argument to another opcode. | ||
507 | */ | ||
508 | if ((walk_state->pass_number == | ||
509 | ACPI_IMODE_LOAD_PASS1) | ||
510 | && (op->common.parent->common.aml_opcode == | ||
511 | AML_SCOPE_OP)) { | ||
512 | op_info = | ||
513 | acpi_ps_get_opcode_info(op->common. | ||
514 | aml_opcode); | ||
515 | if ((op_info->class == | ||
516 | AML_CLASS_EXECUTE) && (!arg)) { | ||
517 | ACPI_WARNING((AE_INFO, | ||
518 | "Detected an unsupported executable opcode " | ||
519 | "at module-level: [0x%.4X] at table offset 0x%.4X", | ||
520 | op->common.aml_opcode, | ||
521 | (u32)((aml_op_start - walk_state->parser_state.aml_start) | ||
522 | + sizeof(struct acpi_table_header)))); | ||
523 | } | ||
524 | } | ||
483 | break; | 525 | break; |
484 | } | 526 | } |
485 | } | 527 | } |
486 | #endif | 528 | |
529 | /* Special processing for certain opcodes */ | ||
487 | 530 | ||
488 | switch (op->common.aml_opcode) { | 531 | switch (op->common.aml_opcode) { |
489 | case AML_METHOD_OP: | 532 | case AML_METHOD_OP: |
@@ -553,6 +596,66 @@ acpi_ps_get_arguments(struct acpi_walk_state *walk_state, | |||
553 | 596 | ||
554 | /******************************************************************************* | 597 | /******************************************************************************* |
555 | * | 598 | * |
599 | * FUNCTION: acpi_ps_link_module_code | ||
600 | * | ||
601 | * PARAMETERS: aml_start - Pointer to the AML | ||
602 | * aml_length - Length of executable AML | ||
603 | * owner_id - owner_id of module level code | ||
604 | * | ||
605 | * RETURN: None. | ||
606 | * | ||
607 | * DESCRIPTION: Wrap the module-level code with a method object and link the | ||
608 | * object to the global list. Note, the mutex field of the method | ||
609 | * object is used to link multiple module-level code objects. | ||
610 | * | ||
611 | ******************************************************************************/ | ||
612 | |||
613 | static void | ||
614 | acpi_ps_link_module_code(u8 *aml_start, u32 aml_length, acpi_owner_id owner_id) | ||
615 | { | ||
616 | union acpi_operand_object *prev; | ||
617 | union acpi_operand_object *next; | ||
618 | union acpi_operand_object *method_obj; | ||
619 | |||
620 | /* Get the tail of the list */ | ||
621 | |||
622 | prev = next = acpi_gbl_module_code_list; | ||
623 | while (next) { | ||
624 | prev = next; | ||
625 | next = next->method.mutex; | ||
626 | } | ||
627 | |||
628 | /* | ||
629 | * Insert the module level code into the list. Merge it if it is | ||
630 | * adjacent to the previous element. | ||
631 | */ | ||
632 | if (!prev || | ||
633 | ((prev->method.aml_start + prev->method.aml_length) != aml_start)) { | ||
634 | |||
635 | /* Create, initialize, and link a new temporary method object */ | ||
636 | |||
637 | method_obj = acpi_ut_create_internal_object(ACPI_TYPE_METHOD); | ||
638 | if (!method_obj) { | ||
639 | return; | ||
640 | } | ||
641 | |||
642 | method_obj->method.aml_start = aml_start; | ||
643 | method_obj->method.aml_length = aml_length; | ||
644 | method_obj->method.owner_id = owner_id; | ||
645 | method_obj->method.flags |= AOPOBJ_MODULE_LEVEL; | ||
646 | |||
647 | if (!prev) { | ||
648 | acpi_gbl_module_code_list = method_obj; | ||
649 | } else { | ||
650 | prev->method.mutex = method_obj; | ||
651 | } | ||
652 | } else { | ||
653 | prev->method.aml_length += aml_length; | ||
654 | } | ||
655 | } | ||
656 | |||
657 | /******************************************************************************* | ||
658 | * | ||
556 | * FUNCTION: acpi_ps_complete_op | 659 | * FUNCTION: acpi_ps_complete_op |
557 | * | 660 | * |
558 | * PARAMETERS: walk_state - Current state | 661 | * PARAMETERS: walk_state - Current state |
diff --git a/drivers/acpi/acpica/psxface.c b/drivers/acpi/acpica/psxface.c index ff06032c0f06..dd9731c29a79 100644 --- a/drivers/acpi/acpica/psxface.c +++ b/drivers/acpi/acpica/psxface.c | |||
@@ -280,6 +280,10 @@ acpi_status acpi_ps_execute_method(struct acpi_evaluate_info *info) | |||
280 | goto cleanup; | 280 | goto cleanup; |
281 | } | 281 | } |
282 | 282 | ||
283 | if (info->obj_desc->method.flags & AOPOBJ_MODULE_LEVEL) { | ||
284 | walk_state->parse_flags |= ACPI_PARSE_MODULE_LEVEL; | ||
285 | } | ||
286 | |||
283 | /* Invoke an internal method if necessary */ | 287 | /* Invoke an internal method if necessary */ |
284 | 288 | ||
285 | if (info->obj_desc->method.method_flags & AML_METHOD_INTERNAL_ONLY) { | 289 | if (info->obj_desc->method.method_flags & AML_METHOD_INTERNAL_ONLY) { |
diff --git a/drivers/acpi/acpica/rscalc.c b/drivers/acpi/acpica/rscalc.c index 88b5a2c4814d..3c4dcc3d1069 100644 --- a/drivers/acpi/acpica/rscalc.c +++ b/drivers/acpi/acpica/rscalc.c | |||
@@ -547,7 +547,7 @@ acpi_rs_get_pci_routing_table_length(union acpi_operand_object *package_object, | |||
547 | 547 | ||
548 | if (!package_element || | 548 | if (!package_element || |
549 | (package_element->common.type != ACPI_TYPE_PACKAGE)) { | 549 | (package_element->common.type != ACPI_TYPE_PACKAGE)) { |
550 | return_ACPI_STATUS (AE_AML_OPERAND_TYPE); | 550 | return_ACPI_STATUS(AE_AML_OPERAND_TYPE); |
551 | } | 551 | } |
552 | 552 | ||
553 | /* | 553 | /* |
@@ -593,9 +593,6 @@ acpi_rs_get_pci_routing_table_length(union acpi_operand_object *package_object, | |||
593 | } else { | 593 | } else { |
594 | temp_size_needed += | 594 | temp_size_needed += |
595 | acpi_ns_get_pathname_length((*sub_object_list)->reference.node); | 595 | acpi_ns_get_pathname_length((*sub_object_list)->reference.node); |
596 | if (!temp_size_needed) { | ||
597 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
598 | } | ||
599 | } | 596 | } |
600 | } else { | 597 | } else { |
601 | /* | 598 | /* |
diff --git a/drivers/acpi/acpica/rsxface.c b/drivers/acpi/acpica/rsxface.c index 69a2aa5b5d83..395212bcd19b 100644 --- a/drivers/acpi/acpica/rsxface.c +++ b/drivers/acpi/acpica/rsxface.c | |||
@@ -338,13 +338,17 @@ acpi_resource_to_address64(struct acpi_resource *resource, | |||
338 | switch (resource->type) { | 338 | switch (resource->type) { |
339 | case ACPI_RESOURCE_TYPE_ADDRESS16: | 339 | case ACPI_RESOURCE_TYPE_ADDRESS16: |
340 | 340 | ||
341 | address16 = (struct acpi_resource_address16 *)&resource->data; | 341 | address16 = |
342 | ACPI_CAST_PTR(struct acpi_resource_address16, | ||
343 | &resource->data); | ||
342 | ACPI_COPY_ADDRESS(out, address16); | 344 | ACPI_COPY_ADDRESS(out, address16); |
343 | break; | 345 | break; |
344 | 346 | ||
345 | case ACPI_RESOURCE_TYPE_ADDRESS32: | 347 | case ACPI_RESOURCE_TYPE_ADDRESS32: |
346 | 348 | ||
347 | address32 = (struct acpi_resource_address32 *)&resource->data; | 349 | address32 = |
350 | ACPI_CAST_PTR(struct acpi_resource_address32, | ||
351 | &resource->data); | ||
348 | ACPI_COPY_ADDRESS(out, address32); | 352 | ACPI_COPY_ADDRESS(out, address32); |
349 | break; | 353 | break; |
350 | 354 | ||
diff --git a/drivers/acpi/acpica/tbfadt.c b/drivers/acpi/acpica/tbfadt.c index 71e655d14cb0..82b02dcb942e 100644 --- a/drivers/acpi/acpica/tbfadt.c +++ b/drivers/acpi/acpica/tbfadt.c | |||
@@ -284,9 +284,9 @@ void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length) | |||
284 | if (length > sizeof(struct acpi_table_fadt)) { | 284 | if (length > sizeof(struct acpi_table_fadt)) { |
285 | ACPI_WARNING((AE_INFO, | 285 | ACPI_WARNING((AE_INFO, |
286 | "FADT (revision %u) is longer than ACPI 2.0 version, " | 286 | "FADT (revision %u) is longer than ACPI 2.0 version, " |
287 | "truncating length 0x%X to 0x%zX", | 287 | "truncating length 0x%X to 0x%X", |
288 | table->revision, (unsigned)length, | 288 | table->revision, length, |
289 | sizeof(struct acpi_table_fadt))); | 289 | (u32)sizeof(struct acpi_table_fadt))); |
290 | } | 290 | } |
291 | 291 | ||
292 | /* Clear the entire local FADT */ | 292 | /* Clear the entire local FADT */ |
@@ -441,7 +441,7 @@ static void acpi_tb_convert_fadt(void) | |||
441 | &acpi_gbl_FADT, | 441 | &acpi_gbl_FADT, |
442 | fadt_info_table | 442 | fadt_info_table |
443 | [i].length), | 443 | [i].length), |
444 | address32); | 444 | (u64) address32); |
445 | } | 445 | } |
446 | } | 446 | } |
447 | } | 447 | } |
@@ -469,7 +469,6 @@ static void acpi_tb_convert_fadt(void) | |||
469 | static void acpi_tb_validate_fadt(void) | 469 | static void acpi_tb_validate_fadt(void) |
470 | { | 470 | { |
471 | char *name; | 471 | char *name; |
472 | u32 *address32; | ||
473 | struct acpi_generic_address *address64; | 472 | struct acpi_generic_address *address64; |
474 | u8 length; | 473 | u8 length; |
475 | u32 i; | 474 | u32 i; |
@@ -505,15 +504,12 @@ static void acpi_tb_validate_fadt(void) | |||
505 | 504 | ||
506 | for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) { | 505 | for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) { |
507 | /* | 506 | /* |
508 | * Generate pointers to the 32-bit and 64-bit addresses, get the | 507 | * Generate pointer to the 64-bit address, get the register |
509 | * register length (width), and the register name | 508 | * length (width) and the register name |
510 | */ | 509 | */ |
511 | address64 = ACPI_ADD_PTR(struct acpi_generic_address, | 510 | address64 = ACPI_ADD_PTR(struct acpi_generic_address, |
512 | &acpi_gbl_FADT, | 511 | &acpi_gbl_FADT, |
513 | fadt_info_table[i].address64); | 512 | fadt_info_table[i].address64); |
514 | address32 = | ||
515 | ACPI_ADD_PTR(u32, &acpi_gbl_FADT, | ||
516 | fadt_info_table[i].address32); | ||
517 | length = | 513 | length = |
518 | *ACPI_ADD_PTR(u8, &acpi_gbl_FADT, | 514 | *ACPI_ADD_PTR(u8, &acpi_gbl_FADT, |
519 | fadt_info_table[i].length); | 515 | fadt_info_table[i].length); |
diff --git a/drivers/acpi/acpica/tbinstal.c b/drivers/acpi/acpica/tbinstal.c index f865d5a096de..63e82329a9e8 100644 --- a/drivers/acpi/acpica/tbinstal.c +++ b/drivers/acpi/acpica/tbinstal.c | |||
@@ -472,7 +472,7 @@ acpi_status acpi_tb_delete_namespace_by_owner(u32 table_index) | |||
472 | * lock may block, and also since the execution of a namespace walk | 472 | * lock may block, and also since the execution of a namespace walk |
473 | * must be allowed to use the interpreter. | 473 | * must be allowed to use the interpreter. |
474 | */ | 474 | */ |
475 | acpi_ut_release_mutex(ACPI_MTX_INTERPRETER); | 475 | (void)acpi_ut_release_mutex(ACPI_MTX_INTERPRETER); |
476 | status = acpi_ut_acquire_write_lock(&acpi_gbl_namespace_rw_lock); | 476 | status = acpi_ut_acquire_write_lock(&acpi_gbl_namespace_rw_lock); |
477 | 477 | ||
478 | acpi_ns_delete_namespace_by_owner(owner_id); | 478 | acpi_ns_delete_namespace_by_owner(owner_id); |
diff --git a/drivers/acpi/acpica/tbutils.c b/drivers/acpi/acpica/tbutils.c index ef7d2c2d8f0b..1f15497f00d1 100644 --- a/drivers/acpi/acpica/tbutils.c +++ b/drivers/acpi/acpica/tbutils.c | |||
@@ -49,6 +49,12 @@ | |||
49 | ACPI_MODULE_NAME("tbutils") | 49 | ACPI_MODULE_NAME("tbutils") |
50 | 50 | ||
51 | /* Local prototypes */ | 51 | /* Local prototypes */ |
52 | static void acpi_tb_fix_string(char *string, acpi_size length); | ||
53 | |||
54 | static void | ||
55 | acpi_tb_cleanup_table_header(struct acpi_table_header *out_header, | ||
56 | struct acpi_table_header *header); | ||
57 | |||
52 | static acpi_physical_address | 58 | static acpi_physical_address |
53 | acpi_tb_get_root_table_entry(u8 *table_entry, u32 table_entry_size); | 59 | acpi_tb_get_root_table_entry(u8 *table_entry, u32 table_entry_size); |
54 | 60 | ||
@@ -161,6 +167,59 @@ u8 acpi_tb_tables_loaded(void) | |||
161 | 167 | ||
162 | /******************************************************************************* | 168 | /******************************************************************************* |
163 | * | 169 | * |
170 | * FUNCTION: acpi_tb_fix_string | ||
171 | * | ||
172 | * PARAMETERS: String - String to be repaired | ||
173 | * Length - Maximum length | ||
174 | * | ||
175 | * RETURN: None | ||
176 | * | ||
177 | * DESCRIPTION: Replace every non-printable or non-ascii byte in the string | ||
178 | * with a question mark '?'. | ||
179 | * | ||
180 | ******************************************************************************/ | ||
181 | |||
182 | static void acpi_tb_fix_string(char *string, acpi_size length) | ||
183 | { | ||
184 | |||
185 | while (length && *string) { | ||
186 | if (!ACPI_IS_PRINT(*string)) { | ||
187 | *string = '?'; | ||
188 | } | ||
189 | string++; | ||
190 | length--; | ||
191 | } | ||
192 | } | ||
193 | |||
194 | /******************************************************************************* | ||
195 | * | ||
196 | * FUNCTION: acpi_tb_cleanup_table_header | ||
197 | * | ||
198 | * PARAMETERS: out_header - Where the cleaned header is returned | ||
199 | * Header - Input ACPI table header | ||
200 | * | ||
201 | * RETURN: Returns the cleaned header in out_header | ||
202 | * | ||
203 | * DESCRIPTION: Copy the table header and ensure that all "string" fields in | ||
204 | * the header consist of printable characters. | ||
205 | * | ||
206 | ******************************************************************************/ | ||
207 | |||
208 | static void | ||
209 | acpi_tb_cleanup_table_header(struct acpi_table_header *out_header, | ||
210 | struct acpi_table_header *header) | ||
211 | { | ||
212 | |||
213 | ACPI_MEMCPY(out_header, header, sizeof(struct acpi_table_header)); | ||
214 | |||
215 | acpi_tb_fix_string(out_header->signature, ACPI_NAME_SIZE); | ||
216 | acpi_tb_fix_string(out_header->oem_id, ACPI_OEM_ID_SIZE); | ||
217 | acpi_tb_fix_string(out_header->oem_table_id, ACPI_OEM_TABLE_ID_SIZE); | ||
218 | acpi_tb_fix_string(out_header->asl_compiler_id, ACPI_NAME_SIZE); | ||
219 | } | ||
220 | |||
221 | /******************************************************************************* | ||
222 | * | ||
164 | * FUNCTION: acpi_tb_print_table_header | 223 | * FUNCTION: acpi_tb_print_table_header |
165 | * | 224 | * |
166 | * PARAMETERS: Address - Table physical address | 225 | * PARAMETERS: Address - Table physical address |
@@ -176,6 +235,7 @@ void | |||
176 | acpi_tb_print_table_header(acpi_physical_address address, | 235 | acpi_tb_print_table_header(acpi_physical_address address, |
177 | struct acpi_table_header *header) | 236 | struct acpi_table_header *header) |
178 | { | 237 | { |
238 | struct acpi_table_header local_header; | ||
179 | 239 | ||
180 | /* | 240 | /* |
181 | * The reason that the Address is cast to a void pointer is so that we | 241 | * The reason that the Address is cast to a void pointer is so that we |
@@ -192,6 +252,11 @@ acpi_tb_print_table_header(acpi_physical_address address, | |||
192 | 252 | ||
193 | /* RSDP has no common fields */ | 253 | /* RSDP has no common fields */ |
194 | 254 | ||
255 | ACPI_MEMCPY(local_header.oem_id, | ||
256 | ACPI_CAST_PTR(struct acpi_table_rsdp, | ||
257 | header)->oem_id, ACPI_OEM_ID_SIZE); | ||
258 | acpi_tb_fix_string(local_header.oem_id, ACPI_OEM_ID_SIZE); | ||
259 | |||
195 | ACPI_INFO((AE_INFO, "RSDP %p %05X (v%.2d %6.6s)", | 260 | ACPI_INFO((AE_INFO, "RSDP %p %05X (v%.2d %6.6s)", |
196 | ACPI_CAST_PTR (void, address), | 261 | ACPI_CAST_PTR (void, address), |
197 | (ACPI_CAST_PTR(struct acpi_table_rsdp, header)-> | 262 | (ACPI_CAST_PTR(struct acpi_table_rsdp, header)-> |
@@ -200,18 +265,21 @@ acpi_tb_print_table_header(acpi_physical_address address, | |||
200 | header)->length : 20, | 265 | header)->length : 20, |
201 | ACPI_CAST_PTR(struct acpi_table_rsdp, | 266 | ACPI_CAST_PTR(struct acpi_table_rsdp, |
202 | header)->revision, | 267 | header)->revision, |
203 | ACPI_CAST_PTR(struct acpi_table_rsdp, | 268 | local_header.oem_id)); |
204 | header)->oem_id)); | ||
205 | } else { | 269 | } else { |
206 | /* Standard ACPI table with full common header */ | 270 | /* Standard ACPI table with full common header */ |
207 | 271 | ||
272 | acpi_tb_cleanup_table_header(&local_header, header); | ||
273 | |||
208 | ACPI_INFO((AE_INFO, | 274 | ACPI_INFO((AE_INFO, |
209 | "%4.4s %p %05X (v%.2d %6.6s %8.8s %08X %4.4s %08X)", | 275 | "%4.4s %p %05X (v%.2d %6.6s %8.8s %08X %4.4s %08X)", |
210 | header->signature, ACPI_CAST_PTR (void, address), | 276 | local_header.signature, ACPI_CAST_PTR(void, address), |
211 | header->length, header->revision, header->oem_id, | 277 | local_header.length, local_header.revision, |
212 | header->oem_table_id, header->oem_revision, | 278 | local_header.oem_id, local_header.oem_table_id, |
213 | header->asl_compiler_id, | 279 | local_header.oem_revision, |
214 | header->asl_compiler_revision)); | 280 | local_header.asl_compiler_id, |
281 | local_header.asl_compiler_revision)); | ||
282 | |||
215 | } | 283 | } |
216 | } | 284 | } |
217 | 285 | ||
diff --git a/drivers/acpi/acpica/utcopy.c b/drivers/acpi/acpica/utcopy.c index 919624f123d5..0f0c64bf8ac9 100644 --- a/drivers/acpi/acpica/utcopy.c +++ b/drivers/acpi/acpica/utcopy.c | |||
@@ -676,6 +676,7 @@ acpi_ut_copy_simple_object(union acpi_operand_object *source_desc, | |||
676 | { | 676 | { |
677 | u16 reference_count; | 677 | u16 reference_count; |
678 | union acpi_operand_object *next_object; | 678 | union acpi_operand_object *next_object; |
679 | acpi_status status; | ||
679 | 680 | ||
680 | /* Save fields from destination that we don't want to overwrite */ | 681 | /* Save fields from destination that we don't want to overwrite */ |
681 | 682 | ||
@@ -768,6 +769,28 @@ acpi_ut_copy_simple_object(union acpi_operand_object *source_desc, | |||
768 | } | 769 | } |
769 | break; | 770 | break; |
770 | 771 | ||
772 | /* | ||
773 | * For Mutex and Event objects, we cannot simply copy the underlying | ||
774 | * OS object. We must create a new one. | ||
775 | */ | ||
776 | case ACPI_TYPE_MUTEX: | ||
777 | |||
778 | status = acpi_os_create_mutex(&dest_desc->mutex.os_mutex); | ||
779 | if (ACPI_FAILURE(status)) { | ||
780 | return status; | ||
781 | } | ||
782 | break; | ||
783 | |||
784 | case ACPI_TYPE_EVENT: | ||
785 | |||
786 | status = acpi_os_create_semaphore(ACPI_NO_UNIT_LIMIT, 0, | ||
787 | &dest_desc->event. | ||
788 | os_semaphore); | ||
789 | if (ACPI_FAILURE(status)) { | ||
790 | return status; | ||
791 | } | ||
792 | break; | ||
793 | |||
771 | default: | 794 | default: |
772 | /* Nothing to do for other simple objects */ | 795 | /* Nothing to do for other simple objects */ |
773 | break; | 796 | break; |
diff --git a/drivers/acpi/acpica/utdebug.c b/drivers/acpi/acpica/utdebug.c index 38821f53042c..527d729f6815 100644 --- a/drivers/acpi/acpica/utdebug.c +++ b/drivers/acpi/acpica/utdebug.c | |||
@@ -179,9 +179,9 @@ acpi_debug_print(u32 requested_debug_level, | |||
179 | if (thread_id != acpi_gbl_prev_thread_id) { | 179 | if (thread_id != acpi_gbl_prev_thread_id) { |
180 | if (ACPI_LV_THREADS & acpi_dbg_level) { | 180 | if (ACPI_LV_THREADS & acpi_dbg_level) { |
181 | acpi_os_printf | 181 | acpi_os_printf |
182 | ("\n**** Context Switch from TID %lX to TID %lX ****\n\n", | 182 | ("\n**** Context Switch from TID %p to TID %p ****\n\n", |
183 | (unsigned long)acpi_gbl_prev_thread_id, | 183 | ACPI_CAST_PTR(void, acpi_gbl_prev_thread_id), |
184 | (unsigned long)thread_id); | 184 | ACPI_CAST_PTR(void, thread_id)); |
185 | } | 185 | } |
186 | 186 | ||
187 | acpi_gbl_prev_thread_id = thread_id; | 187 | acpi_gbl_prev_thread_id = thread_id; |
@@ -194,7 +194,7 @@ acpi_debug_print(u32 requested_debug_level, | |||
194 | acpi_os_printf("%8s-%04ld ", module_name, line_number); | 194 | acpi_os_printf("%8s-%04ld ", module_name, line_number); |
195 | 195 | ||
196 | if (ACPI_LV_THREADS & acpi_dbg_level) { | 196 | if (ACPI_LV_THREADS & acpi_dbg_level) { |
197 | acpi_os_printf("[%04lX] ", (unsigned long)thread_id); | 197 | acpi_os_printf("[%p] ", ACPI_CAST_PTR(void, thread_id)); |
198 | } | 198 | } |
199 | 199 | ||
200 | acpi_os_printf("[%02ld] %-22.22s: ", | 200 | acpi_os_printf("[%02ld] %-22.22s: ", |
diff --git a/drivers/acpi/acpica/utdelete.c b/drivers/acpi/acpica/utdelete.c index a5ee23bc4f55..96e26e70c63d 100644 --- a/drivers/acpi/acpica/utdelete.c +++ b/drivers/acpi/acpica/utdelete.c | |||
@@ -75,6 +75,7 @@ static void acpi_ut_delete_internal_obj(union acpi_operand_object *object) | |||
75 | union acpi_operand_object *handler_desc; | 75 | union acpi_operand_object *handler_desc; |
76 | union acpi_operand_object *second_desc; | 76 | union acpi_operand_object *second_desc; |
77 | union acpi_operand_object *next_desc; | 77 | union acpi_operand_object *next_desc; |
78 | union acpi_operand_object **last_obj_ptr; | ||
78 | 79 | ||
79 | ACPI_FUNCTION_TRACE_PTR(ut_delete_internal_obj, object); | 80 | ACPI_FUNCTION_TRACE_PTR(ut_delete_internal_obj, object); |
80 | 81 | ||
@@ -214,6 +215,12 @@ static void acpi_ut_delete_internal_obj(union acpi_operand_object *object) | |||
214 | ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, | 215 | ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, |
215 | "***** Region %p\n", object)); | 216 | "***** Region %p\n", object)); |
216 | 217 | ||
218 | /* Invalidate the region address/length via the host OS */ | ||
219 | |||
220 | acpi_os_invalidate_address(object->region.space_id, | ||
221 | object->region.address, | ||
222 | (acpi_size) object->region.length); | ||
223 | |||
217 | second_desc = acpi_ns_get_secondary_object(object); | 224 | second_desc = acpi_ns_get_secondary_object(object); |
218 | if (second_desc) { | 225 | if (second_desc) { |
219 | /* | 226 | /* |
@@ -223,6 +230,26 @@ static void acpi_ut_delete_internal_obj(union acpi_operand_object *object) | |||
223 | */ | 230 | */ |
224 | handler_desc = object->region.handler; | 231 | handler_desc = object->region.handler; |
225 | if (handler_desc) { | 232 | if (handler_desc) { |
233 | next_desc = | ||
234 | handler_desc->address_space.region_list; | ||
235 | last_obj_ptr = | ||
236 | &handler_desc->address_space.region_list; | ||
237 | |||
238 | /* Remove the region object from the handler's list */ | ||
239 | |||
240 | while (next_desc) { | ||
241 | if (next_desc == object) { | ||
242 | *last_obj_ptr = | ||
243 | next_desc->region.next; | ||
244 | break; | ||
245 | } | ||
246 | |||
247 | /* Walk the linked list of handler */ | ||
248 | |||
249 | last_obj_ptr = &next_desc->region.next; | ||
250 | next_desc = next_desc->region.next; | ||
251 | } | ||
252 | |||
226 | if (handler_desc->address_space.handler_flags & | 253 | if (handler_desc->address_space.handler_flags & |
227 | ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) { | 254 | ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) { |
228 | 255 | ||
diff --git a/drivers/acpi/acpica/uteval.c b/drivers/acpi/acpica/uteval.c index 006b16c26017..5d54e36ab453 100644 --- a/drivers/acpi/acpica/uteval.c +++ b/drivers/acpi/acpica/uteval.c | |||
@@ -44,19 +44,10 @@ | |||
44 | #include <acpi/acpi.h> | 44 | #include <acpi/acpi.h> |
45 | #include "accommon.h" | 45 | #include "accommon.h" |
46 | #include "acnamesp.h" | 46 | #include "acnamesp.h" |
47 | #include "acinterp.h" | ||
48 | 47 | ||
49 | #define _COMPONENT ACPI_UTILITIES | 48 | #define _COMPONENT ACPI_UTILITIES |
50 | ACPI_MODULE_NAME("uteval") | 49 | ACPI_MODULE_NAME("uteval") |
51 | 50 | ||
52 | /* Local prototypes */ | ||
53 | static void | ||
54 | acpi_ut_copy_id_string(char *destination, char *source, acpi_size max_length); | ||
55 | |||
56 | static acpi_status | ||
57 | acpi_ut_translate_one_cid(union acpi_operand_object *obj_desc, | ||
58 | struct acpi_compatible_id *one_cid); | ||
59 | |||
60 | /* | 51 | /* |
61 | * Strings supported by the _OSI predefined (internal) method. | 52 | * Strings supported by the _OSI predefined (internal) method. |
62 | * | 53 | * |
@@ -78,6 +69,9 @@ static struct acpi_interface_info acpi_interfaces_supported[] = { | |||
78 | {"Windows 2001 SP2", ACPI_OSI_WIN_XP_SP2}, /* Windows XP SP2 */ | 69 | {"Windows 2001 SP2", ACPI_OSI_WIN_XP_SP2}, /* Windows XP SP2 */ |
79 | {"Windows 2001.1 SP1", ACPI_OSI_WINSRV_2003_SP1}, /* Windows Server 2003 SP1 - Added 03/2006 */ | 70 | {"Windows 2001.1 SP1", ACPI_OSI_WINSRV_2003_SP1}, /* Windows Server 2003 SP1 - Added 03/2006 */ |
80 | {"Windows 2006", ACPI_OSI_WIN_VISTA}, /* Windows Vista - Added 03/2006 */ | 71 | {"Windows 2006", ACPI_OSI_WIN_VISTA}, /* Windows Vista - Added 03/2006 */ |
72 | {"Windows 2006.1", ACPI_OSI_WINSRV_2008}, /* Windows Server 2008 - Added 09/2009 */ | ||
73 | {"Windows 2006 SP1", ACPI_OSI_WIN_VISTA_SP1}, /* Windows Vista SP1 - Added 09/2009 */ | ||
74 | {"Windows 2009", ACPI_OSI_WIN_7}, /* Windows 7 and Server 2008 R2 - Added 09/2009 */ | ||
81 | 75 | ||
82 | /* Feature Group Strings */ | 76 | /* Feature Group Strings */ |
83 | 77 | ||
@@ -213,7 +207,7 @@ acpi_status acpi_osi_invalidate(char *interface) | |||
213 | * RETURN: Status | 207 | * RETURN: Status |
214 | * | 208 | * |
215 | * DESCRIPTION: Evaluates a namespace object and verifies the type of the | 209 | * DESCRIPTION: Evaluates a namespace object and verifies the type of the |
216 | * return object. Common code that simplifies accessing objects | 210 | * return object. Common code that simplifies accessing objects |
217 | * that have required return objects of fixed types. | 211 | * that have required return objects of fixed types. |
218 | * | 212 | * |
219 | * NOTE: Internal function, no parameter validation | 213 | * NOTE: Internal function, no parameter validation |
@@ -298,7 +292,7 @@ acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node, | |||
298 | 292 | ||
299 | if ((acpi_gbl_enable_interpreter_slack) && (!expected_return_btypes)) { | 293 | if ((acpi_gbl_enable_interpreter_slack) && (!expected_return_btypes)) { |
300 | /* | 294 | /* |
301 | * We received a return object, but one was not expected. This can | 295 | * We received a return object, but one was not expected. This can |
302 | * happen frequently if the "implicit return" feature is enabled. | 296 | * happen frequently if the "implicit return" feature is enabled. |
303 | * Just delete the return object and return AE_OK. | 297 | * Just delete the return object and return AE_OK. |
304 | */ | 298 | */ |
@@ -340,12 +334,12 @@ acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node, | |||
340 | * | 334 | * |
341 | * PARAMETERS: object_name - Object name to be evaluated | 335 | * PARAMETERS: object_name - Object name to be evaluated |
342 | * device_node - Node for the device | 336 | * device_node - Node for the device |
343 | * Address - Where the value is returned | 337 | * Value - Where the value is returned |
344 | * | 338 | * |
345 | * RETURN: Status | 339 | * RETURN: Status |
346 | * | 340 | * |
347 | * DESCRIPTION: Evaluates a numeric namespace object for a selected device | 341 | * DESCRIPTION: Evaluates a numeric namespace object for a selected device |
348 | * and stores result in *Address. | 342 | * and stores result in *Value. |
349 | * | 343 | * |
350 | * NOTE: Internal function, no parameter validation | 344 | * NOTE: Internal function, no parameter validation |
351 | * | 345 | * |
@@ -354,7 +348,7 @@ acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node, | |||
354 | acpi_status | 348 | acpi_status |
355 | acpi_ut_evaluate_numeric_object(char *object_name, | 349 | acpi_ut_evaluate_numeric_object(char *object_name, |
356 | struct acpi_namespace_node *device_node, | 350 | struct acpi_namespace_node *device_node, |
357 | acpi_integer * address) | 351 | acpi_integer *value) |
358 | { | 352 | { |
359 | union acpi_operand_object *obj_desc; | 353 | union acpi_operand_object *obj_desc; |
360 | acpi_status status; | 354 | acpi_status status; |
@@ -369,295 +363,7 @@ acpi_ut_evaluate_numeric_object(char *object_name, | |||
369 | 363 | ||
370 | /* Get the returned Integer */ | 364 | /* Get the returned Integer */ |
371 | 365 | ||
372 | *address = obj_desc->integer.value; | 366 | *value = obj_desc->integer.value; |
373 | |||
374 | /* On exit, we must delete the return object */ | ||
375 | |||
376 | acpi_ut_remove_reference(obj_desc); | ||
377 | return_ACPI_STATUS(status); | ||
378 | } | ||
379 | |||
380 | /******************************************************************************* | ||
381 | * | ||
382 | * FUNCTION: acpi_ut_copy_id_string | ||
383 | * | ||
384 | * PARAMETERS: Destination - Where to copy the string | ||
385 | * Source - Source string | ||
386 | * max_length - Length of the destination buffer | ||
387 | * | ||
388 | * RETURN: None | ||
389 | * | ||
390 | * DESCRIPTION: Copies an ID string for the _HID, _CID, and _UID methods. | ||
391 | * Performs removal of a leading asterisk if present -- workaround | ||
392 | * for a known issue on a bunch of machines. | ||
393 | * | ||
394 | ******************************************************************************/ | ||
395 | |||
396 | static void | ||
397 | acpi_ut_copy_id_string(char *destination, char *source, acpi_size max_length) | ||
398 | { | ||
399 | |||
400 | /* | ||
401 | * Workaround for ID strings that have a leading asterisk. This construct | ||
402 | * is not allowed by the ACPI specification (ID strings must be | ||
403 | * alphanumeric), but enough existing machines have this embedded in their | ||
404 | * ID strings that the following code is useful. | ||
405 | */ | ||
406 | if (*source == '*') { | ||
407 | source++; | ||
408 | } | ||
409 | |||
410 | /* Do the actual copy */ | ||
411 | |||
412 | ACPI_STRNCPY(destination, source, max_length); | ||
413 | } | ||
414 | |||
415 | /******************************************************************************* | ||
416 | * | ||
417 | * FUNCTION: acpi_ut_execute_HID | ||
418 | * | ||
419 | * PARAMETERS: device_node - Node for the device | ||
420 | * Hid - Where the HID is returned | ||
421 | * | ||
422 | * RETURN: Status | ||
423 | * | ||
424 | * DESCRIPTION: Executes the _HID control method that returns the hardware | ||
425 | * ID of the device. | ||
426 | * | ||
427 | * NOTE: Internal function, no parameter validation | ||
428 | * | ||
429 | ******************************************************************************/ | ||
430 | |||
431 | acpi_status | ||
432 | acpi_ut_execute_HID(struct acpi_namespace_node *device_node, | ||
433 | struct acpica_device_id *hid) | ||
434 | { | ||
435 | union acpi_operand_object *obj_desc; | ||
436 | acpi_status status; | ||
437 | |||
438 | ACPI_FUNCTION_TRACE(ut_execute_HID); | ||
439 | |||
440 | status = acpi_ut_evaluate_object(device_node, METHOD_NAME__HID, | ||
441 | ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING, | ||
442 | &obj_desc); | ||
443 | if (ACPI_FAILURE(status)) { | ||
444 | return_ACPI_STATUS(status); | ||
445 | } | ||
446 | |||
447 | if (obj_desc->common.type == ACPI_TYPE_INTEGER) { | ||
448 | |||
449 | /* Convert the Numeric HID to string */ | ||
450 | |||
451 | acpi_ex_eisa_id_to_string((u32) obj_desc->integer.value, | ||
452 | hid->value); | ||
453 | } else { | ||
454 | /* Copy the String HID from the returned object */ | ||
455 | |||
456 | acpi_ut_copy_id_string(hid->value, obj_desc->string.pointer, | ||
457 | sizeof(hid->value)); | ||
458 | } | ||
459 | |||
460 | /* On exit, we must delete the return object */ | ||
461 | |||
462 | acpi_ut_remove_reference(obj_desc); | ||
463 | return_ACPI_STATUS(status); | ||
464 | } | ||
465 | |||
466 | /******************************************************************************* | ||
467 | * | ||
468 | * FUNCTION: acpi_ut_translate_one_cid | ||
469 | * | ||
470 | * PARAMETERS: obj_desc - _CID object, must be integer or string | ||
471 | * one_cid - Where the CID string is returned | ||
472 | * | ||
473 | * RETURN: Status | ||
474 | * | ||
475 | * DESCRIPTION: Return a numeric or string _CID value as a string. | ||
476 | * (Compatible ID) | ||
477 | * | ||
478 | * NOTE: Assumes a maximum _CID string length of | ||
479 | * ACPI_MAX_CID_LENGTH. | ||
480 | * | ||
481 | ******************************************************************************/ | ||
482 | |||
483 | static acpi_status | ||
484 | acpi_ut_translate_one_cid(union acpi_operand_object *obj_desc, | ||
485 | struct acpi_compatible_id *one_cid) | ||
486 | { | ||
487 | |||
488 | switch (obj_desc->common.type) { | ||
489 | case ACPI_TYPE_INTEGER: | ||
490 | |||
491 | /* Convert the Numeric CID to string */ | ||
492 | |||
493 | acpi_ex_eisa_id_to_string((u32) obj_desc->integer.value, | ||
494 | one_cid->value); | ||
495 | return (AE_OK); | ||
496 | |||
497 | case ACPI_TYPE_STRING: | ||
498 | |||
499 | if (obj_desc->string.length > ACPI_MAX_CID_LENGTH) { | ||
500 | return (AE_AML_STRING_LIMIT); | ||
501 | } | ||
502 | |||
503 | /* Copy the String CID from the returned object */ | ||
504 | |||
505 | acpi_ut_copy_id_string(one_cid->value, obj_desc->string.pointer, | ||
506 | ACPI_MAX_CID_LENGTH); | ||
507 | return (AE_OK); | ||
508 | |||
509 | default: | ||
510 | |||
511 | return (AE_TYPE); | ||
512 | } | ||
513 | } | ||
514 | |||
515 | /******************************************************************************* | ||
516 | * | ||
517 | * FUNCTION: acpi_ut_execute_CID | ||
518 | * | ||
519 | * PARAMETERS: device_node - Node for the device | ||
520 | * return_cid_list - Where the CID list is returned | ||
521 | * | ||
522 | * RETURN: Status | ||
523 | * | ||
524 | * DESCRIPTION: Executes the _CID control method that returns one or more | ||
525 | * compatible hardware IDs for the device. | ||
526 | * | ||
527 | * NOTE: Internal function, no parameter validation | ||
528 | * | ||
529 | ******************************************************************************/ | ||
530 | |||
531 | acpi_status | ||
532 | acpi_ut_execute_CID(struct acpi_namespace_node * device_node, | ||
533 | struct acpi_compatible_id_list ** return_cid_list) | ||
534 | { | ||
535 | union acpi_operand_object *obj_desc; | ||
536 | acpi_status status; | ||
537 | u32 count; | ||
538 | u32 size; | ||
539 | struct acpi_compatible_id_list *cid_list; | ||
540 | u32 i; | ||
541 | |||
542 | ACPI_FUNCTION_TRACE(ut_execute_CID); | ||
543 | |||
544 | /* Evaluate the _CID method for this device */ | ||
545 | |||
546 | status = acpi_ut_evaluate_object(device_node, METHOD_NAME__CID, | ||
547 | ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING | ||
548 | | ACPI_BTYPE_PACKAGE, &obj_desc); | ||
549 | if (ACPI_FAILURE(status)) { | ||
550 | return_ACPI_STATUS(status); | ||
551 | } | ||
552 | |||
553 | /* Get the number of _CIDs returned */ | ||
554 | |||
555 | count = 1; | ||
556 | if (obj_desc->common.type == ACPI_TYPE_PACKAGE) { | ||
557 | count = obj_desc->package.count; | ||
558 | } | ||
559 | |||
560 | /* Allocate a worst-case buffer for the _CIDs */ | ||
561 | |||
562 | size = (((count - 1) * sizeof(struct acpi_compatible_id)) + | ||
563 | sizeof(struct acpi_compatible_id_list)); | ||
564 | |||
565 | cid_list = ACPI_ALLOCATE_ZEROED((acpi_size) size); | ||
566 | if (!cid_list) { | ||
567 | return_ACPI_STATUS(AE_NO_MEMORY); | ||
568 | } | ||
569 | |||
570 | /* Init CID list */ | ||
571 | |||
572 | cid_list->count = count; | ||
573 | cid_list->size = size; | ||
574 | |||
575 | /* | ||
576 | * A _CID can return either a single compatible ID or a package of | ||
577 | * compatible IDs. Each compatible ID can be one of the following: | ||
578 | * 1) Integer (32 bit compressed EISA ID) or | ||
579 | * 2) String (PCI ID format, e.g. "PCI\VEN_vvvv&DEV_dddd&SUBSYS_ssssssss") | ||
580 | */ | ||
581 | |||
582 | /* The _CID object can be either a single CID or a package (list) of CIDs */ | ||
583 | |||
584 | if (obj_desc->common.type == ACPI_TYPE_PACKAGE) { | ||
585 | |||
586 | /* Translate each package element */ | ||
587 | |||
588 | for (i = 0; i < count; i++) { | ||
589 | status = | ||
590 | acpi_ut_translate_one_cid(obj_desc->package. | ||
591 | elements[i], | ||
592 | &cid_list->id[i]); | ||
593 | if (ACPI_FAILURE(status)) { | ||
594 | break; | ||
595 | } | ||
596 | } | ||
597 | } else { | ||
598 | /* Only one CID, translate to a string */ | ||
599 | |||
600 | status = acpi_ut_translate_one_cid(obj_desc, cid_list->id); | ||
601 | } | ||
602 | |||
603 | /* Cleanup on error */ | ||
604 | |||
605 | if (ACPI_FAILURE(status)) { | ||
606 | ACPI_FREE(cid_list); | ||
607 | } else { | ||
608 | *return_cid_list = cid_list; | ||
609 | } | ||
610 | |||
611 | /* On exit, we must delete the _CID return object */ | ||
612 | |||
613 | acpi_ut_remove_reference(obj_desc); | ||
614 | return_ACPI_STATUS(status); | ||
615 | } | ||
616 | |||
617 | /******************************************************************************* | ||
618 | * | ||
619 | * FUNCTION: acpi_ut_execute_UID | ||
620 | * | ||
621 | * PARAMETERS: device_node - Node for the device | ||
622 | * Uid - Where the UID is returned | ||
623 | * | ||
624 | * RETURN: Status | ||
625 | * | ||
626 | * DESCRIPTION: Executes the _UID control method that returns the hardware | ||
627 | * ID of the device. | ||
628 | * | ||
629 | * NOTE: Internal function, no parameter validation | ||
630 | * | ||
631 | ******************************************************************************/ | ||
632 | |||
633 | acpi_status | ||
634 | acpi_ut_execute_UID(struct acpi_namespace_node *device_node, | ||
635 | struct acpica_device_id *uid) | ||
636 | { | ||
637 | union acpi_operand_object *obj_desc; | ||
638 | acpi_status status; | ||
639 | |||
640 | ACPI_FUNCTION_TRACE(ut_execute_UID); | ||
641 | |||
642 | status = acpi_ut_evaluate_object(device_node, METHOD_NAME__UID, | ||
643 | ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING, | ||
644 | &obj_desc); | ||
645 | if (ACPI_FAILURE(status)) { | ||
646 | return_ACPI_STATUS(status); | ||
647 | } | ||
648 | |||
649 | if (obj_desc->common.type == ACPI_TYPE_INTEGER) { | ||
650 | |||
651 | /* Convert the Numeric UID to string */ | ||
652 | |||
653 | acpi_ex_unsigned_integer_to_string(obj_desc->integer.value, | ||
654 | uid->value); | ||
655 | } else { | ||
656 | /* Copy the String UID from the returned object */ | ||
657 | |||
658 | acpi_ut_copy_id_string(uid->value, obj_desc->string.pointer, | ||
659 | sizeof(uid->value)); | ||
660 | } | ||
661 | 367 | ||
662 | /* On exit, we must delete the return object */ | 368 | /* On exit, we must delete the return object */ |
663 | 369 | ||
@@ -716,60 +422,64 @@ acpi_ut_execute_STA(struct acpi_namespace_node *device_node, u32 * flags) | |||
716 | 422 | ||
717 | /******************************************************************************* | 423 | /******************************************************************************* |
718 | * | 424 | * |
719 | * FUNCTION: acpi_ut_execute_Sxds | 425 | * FUNCTION: acpi_ut_execute_power_methods |
720 | * | 426 | * |
721 | * PARAMETERS: device_node - Node for the device | 427 | * PARAMETERS: device_node - Node for the device |
722 | * Flags - Where the status flags are returned | 428 | * method_names - Array of power method names |
429 | * method_count - Number of methods to execute | ||
430 | * out_values - Where the power method values are returned | ||
723 | * | 431 | * |
724 | * RETURN: Status | 432 | * RETURN: Status, out_values |
725 | * | 433 | * |
726 | * DESCRIPTION: Executes _STA for selected device and stores results in | 434 | * DESCRIPTION: Executes the specified power methods for the device and returns |
727 | * *Flags. | 435 | * the result(s). |
728 | * | 436 | * |
729 | * NOTE: Internal function, no parameter validation | 437 | * NOTE: Internal function, no parameter validation |
730 | * | 438 | * |
731 | ******************************************************************************/ | 439 | ******************************************************************************/ |
732 | 440 | ||
733 | acpi_status | 441 | acpi_status |
734 | acpi_ut_execute_sxds(struct acpi_namespace_node *device_node, u8 * highest) | 442 | acpi_ut_execute_power_methods(struct acpi_namespace_node *device_node, |
443 | const char **method_names, | ||
444 | u8 method_count, u8 *out_values) | ||
735 | { | 445 | { |
736 | union acpi_operand_object *obj_desc; | 446 | union acpi_operand_object *obj_desc; |
737 | acpi_status status; | 447 | acpi_status status; |
448 | acpi_status final_status = AE_NOT_FOUND; | ||
738 | u32 i; | 449 | u32 i; |
739 | 450 | ||
740 | ACPI_FUNCTION_TRACE(ut_execute_sxds); | 451 | ACPI_FUNCTION_TRACE(ut_execute_power_methods); |
741 | 452 | ||
742 | for (i = 0; i < 4; i++) { | 453 | for (i = 0; i < method_count; i++) { |
743 | highest[i] = 0xFF; | 454 | /* |
455 | * Execute the power method (_sx_d or _sx_w). The only allowable | ||
456 | * return type is an Integer. | ||
457 | */ | ||
744 | status = acpi_ut_evaluate_object(device_node, | 458 | status = acpi_ut_evaluate_object(device_node, |
745 | ACPI_CAST_PTR(char, | 459 | ACPI_CAST_PTR(char, |
746 | acpi_gbl_highest_dstate_names | 460 | method_names[i]), |
747 | [i]), | ||
748 | ACPI_BTYPE_INTEGER, &obj_desc); | 461 | ACPI_BTYPE_INTEGER, &obj_desc); |
749 | if (ACPI_FAILURE(status)) { | 462 | if (ACPI_SUCCESS(status)) { |
750 | if (status != AE_NOT_FOUND) { | 463 | out_values[i] = (u8)obj_desc->integer.value; |
751 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | ||
752 | "%s on Device %4.4s, %s\n", | ||
753 | ACPI_CAST_PTR(char, | ||
754 | acpi_gbl_highest_dstate_names | ||
755 | [i]), | ||
756 | acpi_ut_get_node_name | ||
757 | (device_node), | ||
758 | acpi_format_exception | ||
759 | (status))); | ||
760 | |||
761 | return_ACPI_STATUS(status); | ||
762 | } | ||
763 | } else { | ||
764 | /* Extract the Dstate value */ | ||
765 | |||
766 | highest[i] = (u8) obj_desc->integer.value; | ||
767 | 464 | ||
768 | /* Delete the return object */ | 465 | /* Delete the return object */ |
769 | 466 | ||
770 | acpi_ut_remove_reference(obj_desc); | 467 | acpi_ut_remove_reference(obj_desc); |
468 | final_status = AE_OK; /* At least one value is valid */ | ||
469 | continue; | ||
771 | } | 470 | } |
471 | |||
472 | out_values[i] = ACPI_UINT8_MAX; | ||
473 | if (status == AE_NOT_FOUND) { | ||
474 | continue; /* Ignore if not found */ | ||
475 | } | ||
476 | |||
477 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | ||
478 | "Failed %s on Device %4.4s, %s\n", | ||
479 | ACPI_CAST_PTR(char, method_names[i]), | ||
480 | acpi_ut_get_node_name(device_node), | ||
481 | acpi_format_exception(status))); | ||
772 | } | 482 | } |
773 | 483 | ||
774 | return_ACPI_STATUS(AE_OK); | 484 | return_ACPI_STATUS(final_status); |
775 | } | 485 | } |
diff --git a/drivers/acpi/acpica/utglobal.c b/drivers/acpi/acpica/utglobal.c index 59e46f257c02..3f2c68f4e959 100644 --- a/drivers/acpi/acpica/utglobal.c +++ b/drivers/acpi/acpica/utglobal.c | |||
@@ -90,7 +90,15 @@ const char *acpi_gbl_sleep_state_names[ACPI_S_STATE_COUNT] = { | |||
90 | "\\_S5_" | 90 | "\\_S5_" |
91 | }; | 91 | }; |
92 | 92 | ||
93 | const char *acpi_gbl_highest_dstate_names[4] = { | 93 | const char *acpi_gbl_lowest_dstate_names[ACPI_NUM_sx_w_METHODS] = { |
94 | "_S0W", | ||
95 | "_S1W", | ||
96 | "_S2W", | ||
97 | "_S3W", | ||
98 | "_S4W" | ||
99 | }; | ||
100 | |||
101 | const char *acpi_gbl_highest_dstate_names[ACPI_NUM_sx_d_METHODS] = { | ||
94 | "_S1D", | 102 | "_S1D", |
95 | "_S2D", | 103 | "_S2D", |
96 | "_S3D", | 104 | "_S3D", |
@@ -351,6 +359,7 @@ const char *acpi_gbl_region_types[ACPI_NUM_PREDEFINED_REGIONS] = { | |||
351 | "SMBus", | 359 | "SMBus", |
352 | "SystemCMOS", | 360 | "SystemCMOS", |
353 | "PCIBARTarget", | 361 | "PCIBARTarget", |
362 | "IPMI", | ||
354 | "DataTable" | 363 | "DataTable" |
355 | }; | 364 | }; |
356 | 365 | ||
@@ -798,6 +807,7 @@ acpi_status acpi_ut_init_globals(void) | |||
798 | 807 | ||
799 | /* Namespace */ | 808 | /* Namespace */ |
800 | 809 | ||
810 | acpi_gbl_module_code_list = NULL; | ||
801 | acpi_gbl_root_node = NULL; | 811 | acpi_gbl_root_node = NULL; |
802 | acpi_gbl_root_node_struct.name.integer = ACPI_ROOT_NAME; | 812 | acpi_gbl_root_node_struct.name.integer = ACPI_ROOT_NAME; |
803 | acpi_gbl_root_node_struct.descriptor_type = ACPI_DESC_TYPE_NAMED; | 813 | acpi_gbl_root_node_struct.descriptor_type = ACPI_DESC_TYPE_NAMED; |
diff --git a/drivers/acpi/acpica/utids.c b/drivers/acpi/acpica/utids.c new file mode 100644 index 000000000000..52eaae404554 --- /dev/null +++ b/drivers/acpi/acpica/utids.c | |||
@@ -0,0 +1,382 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Module Name: utids - support for device IDs - HID, UID, CID | ||
4 | * | ||
5 | *****************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2009, Intel Corp. | ||
9 | * All rights reserved. | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * 1. Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions, and the following disclaimer, | ||
16 | * without modification. | ||
17 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
18 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
19 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
20 | * including a substantially similar Disclaimer requirement for further | ||
21 | * binary redistribution. | ||
22 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
23 | * of any contributors may be used to endorse or promote products derived | ||
24 | * from this software without specific prior written permission. | ||
25 | * | ||
26 | * Alternatively, this software may be distributed under the terms of the | ||
27 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
28 | * Software Foundation. | ||
29 | * | ||
30 | * NO WARRANTY | ||
31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
35 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
40 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
41 | * POSSIBILITY OF SUCH DAMAGES. | ||
42 | */ | ||
43 | |||
44 | #include <acpi/acpi.h> | ||
45 | #include "accommon.h" | ||
46 | #include "acinterp.h" | ||
47 | |||
48 | #define _COMPONENT ACPI_UTILITIES | ||
49 | ACPI_MODULE_NAME("utids") | ||
50 | |||
51 | /* Local prototypes */ | ||
52 | static void acpi_ut_copy_id_string(char *destination, char *source); | ||
53 | |||
54 | /******************************************************************************* | ||
55 | * | ||
56 | * FUNCTION: acpi_ut_copy_id_string | ||
57 | * | ||
58 | * PARAMETERS: Destination - Where to copy the string | ||
59 | * Source - Source string | ||
60 | * | ||
61 | * RETURN: None | ||
62 | * | ||
63 | * DESCRIPTION: Copies an ID string for the _HID, _CID, and _UID methods. | ||
64 | * Performs removal of a leading asterisk if present -- workaround | ||
65 | * for a known issue on a bunch of machines. | ||
66 | * | ||
67 | ******************************************************************************/ | ||
68 | |||
69 | static void acpi_ut_copy_id_string(char *destination, char *source) | ||
70 | { | ||
71 | |||
72 | /* | ||
73 | * Workaround for ID strings that have a leading asterisk. This construct | ||
74 | * is not allowed by the ACPI specification (ID strings must be | ||
75 | * alphanumeric), but enough existing machines have this embedded in their | ||
76 | * ID strings that the following code is useful. | ||
77 | */ | ||
78 | if (*source == '*') { | ||
79 | source++; | ||
80 | } | ||
81 | |||
82 | /* Do the actual copy */ | ||
83 | |||
84 | ACPI_STRCPY(destination, source); | ||
85 | } | ||
86 | |||
87 | /******************************************************************************* | ||
88 | * | ||
89 | * FUNCTION: acpi_ut_execute_HID | ||
90 | * | ||
91 | * PARAMETERS: device_node - Node for the device | ||
92 | * return_id - Where the string HID is returned | ||
93 | * | ||
94 | * RETURN: Status | ||
95 | * | ||
96 | * DESCRIPTION: Executes the _HID control method that returns the hardware | ||
97 | * ID of the device. The HID is either an 32-bit encoded EISAID | ||
98 | * Integer or a String. A string is always returned. An EISAID | ||
99 | * is converted to a string. | ||
100 | * | ||
101 | * NOTE: Internal function, no parameter validation | ||
102 | * | ||
103 | ******************************************************************************/ | ||
104 | |||
105 | acpi_status | ||
106 | acpi_ut_execute_HID(struct acpi_namespace_node *device_node, | ||
107 | struct acpica_device_id **return_id) | ||
108 | { | ||
109 | union acpi_operand_object *obj_desc; | ||
110 | struct acpica_device_id *hid; | ||
111 | u32 length; | ||
112 | acpi_status status; | ||
113 | |||
114 | ACPI_FUNCTION_TRACE(ut_execute_HID); | ||
115 | |||
116 | status = acpi_ut_evaluate_object(device_node, METHOD_NAME__HID, | ||
117 | ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING, | ||
118 | &obj_desc); | ||
119 | if (ACPI_FAILURE(status)) { | ||
120 | return_ACPI_STATUS(status); | ||
121 | } | ||
122 | |||
123 | /* Get the size of the String to be returned, includes null terminator */ | ||
124 | |||
125 | if (obj_desc->common.type == ACPI_TYPE_INTEGER) { | ||
126 | length = ACPI_EISAID_STRING_SIZE; | ||
127 | } else { | ||
128 | length = obj_desc->string.length + 1; | ||
129 | } | ||
130 | |||
131 | /* Allocate a buffer for the HID */ | ||
132 | |||
133 | hid = | ||
134 | ACPI_ALLOCATE_ZEROED(sizeof(struct acpica_device_id) + | ||
135 | (acpi_size) length); | ||
136 | if (!hid) { | ||
137 | status = AE_NO_MEMORY; | ||
138 | goto cleanup; | ||
139 | } | ||
140 | |||
141 | /* Area for the string starts after DEVICE_ID struct */ | ||
142 | |||
143 | hid->string = ACPI_ADD_PTR(char, hid, sizeof(struct acpica_device_id)); | ||
144 | |||
145 | /* Convert EISAID to a string or simply copy existing string */ | ||
146 | |||
147 | if (obj_desc->common.type == ACPI_TYPE_INTEGER) { | ||
148 | acpi_ex_eisa_id_to_string(hid->string, obj_desc->integer.value); | ||
149 | } else { | ||
150 | acpi_ut_copy_id_string(hid->string, obj_desc->string.pointer); | ||
151 | } | ||
152 | |||
153 | hid->length = length; | ||
154 | *return_id = hid; | ||
155 | |||
156 | cleanup: | ||
157 | |||
158 | /* On exit, we must delete the return object */ | ||
159 | |||
160 | acpi_ut_remove_reference(obj_desc); | ||
161 | return_ACPI_STATUS(status); | ||
162 | } | ||
163 | |||
164 | /******************************************************************************* | ||
165 | * | ||
166 | * FUNCTION: acpi_ut_execute_UID | ||
167 | * | ||
168 | * PARAMETERS: device_node - Node for the device | ||
169 | * return_id - Where the string UID is returned | ||
170 | * | ||
171 | * RETURN: Status | ||
172 | * | ||
173 | * DESCRIPTION: Executes the _UID control method that returns the unique | ||
174 | * ID of the device. The UID is either a 64-bit Integer (NOT an | ||
175 | * EISAID) or a string. Always returns a string. A 64-bit integer | ||
176 | * is converted to a decimal string. | ||
177 | * | ||
178 | * NOTE: Internal function, no parameter validation | ||
179 | * | ||
180 | ******************************************************************************/ | ||
181 | |||
182 | acpi_status | ||
183 | acpi_ut_execute_UID(struct acpi_namespace_node *device_node, | ||
184 | struct acpica_device_id **return_id) | ||
185 | { | ||
186 | union acpi_operand_object *obj_desc; | ||
187 | struct acpica_device_id *uid; | ||
188 | u32 length; | ||
189 | acpi_status status; | ||
190 | |||
191 | ACPI_FUNCTION_TRACE(ut_execute_UID); | ||
192 | |||
193 | status = acpi_ut_evaluate_object(device_node, METHOD_NAME__UID, | ||
194 | ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING, | ||
195 | &obj_desc); | ||
196 | if (ACPI_FAILURE(status)) { | ||
197 | return_ACPI_STATUS(status); | ||
198 | } | ||
199 | |||
200 | /* Get the size of the String to be returned, includes null terminator */ | ||
201 | |||
202 | if (obj_desc->common.type == ACPI_TYPE_INTEGER) { | ||
203 | length = ACPI_MAX64_DECIMAL_DIGITS + 1; | ||
204 | } else { | ||
205 | length = obj_desc->string.length + 1; | ||
206 | } | ||
207 | |||
208 | /* Allocate a buffer for the UID */ | ||
209 | |||
210 | uid = | ||
211 | ACPI_ALLOCATE_ZEROED(sizeof(struct acpica_device_id) + | ||
212 | (acpi_size) length); | ||
213 | if (!uid) { | ||
214 | status = AE_NO_MEMORY; | ||
215 | goto cleanup; | ||
216 | } | ||
217 | |||
218 | /* Area for the string starts after DEVICE_ID struct */ | ||
219 | |||
220 | uid->string = ACPI_ADD_PTR(char, uid, sizeof(struct acpica_device_id)); | ||
221 | |||
222 | /* Convert an Integer to string, or just copy an existing string */ | ||
223 | |||
224 | if (obj_desc->common.type == ACPI_TYPE_INTEGER) { | ||
225 | acpi_ex_integer_to_string(uid->string, obj_desc->integer.value); | ||
226 | } else { | ||
227 | acpi_ut_copy_id_string(uid->string, obj_desc->string.pointer); | ||
228 | } | ||
229 | |||
230 | uid->length = length; | ||
231 | *return_id = uid; | ||
232 | |||
233 | cleanup: | ||
234 | |||
235 | /* On exit, we must delete the return object */ | ||
236 | |||
237 | acpi_ut_remove_reference(obj_desc); | ||
238 | return_ACPI_STATUS(status); | ||
239 | } | ||
240 | |||
241 | /******************************************************************************* | ||
242 | * | ||
243 | * FUNCTION: acpi_ut_execute_CID | ||
244 | * | ||
245 | * PARAMETERS: device_node - Node for the device | ||
246 | * return_cid_list - Where the CID list is returned | ||
247 | * | ||
248 | * RETURN: Status, list of CID strings | ||
249 | * | ||
250 | * DESCRIPTION: Executes the _CID control method that returns one or more | ||
251 | * compatible hardware IDs for the device. | ||
252 | * | ||
253 | * NOTE: Internal function, no parameter validation | ||
254 | * | ||
255 | * A _CID method can return either a single compatible ID or a package of | ||
256 | * compatible IDs. Each compatible ID can be one of the following: | ||
257 | * 1) Integer (32 bit compressed EISA ID) or | ||
258 | * 2) String (PCI ID format, e.g. "PCI\VEN_vvvv&DEV_dddd&SUBSYS_ssssssss") | ||
259 | * | ||
260 | * The Integer CIDs are converted to string format by this function. | ||
261 | * | ||
262 | ******************************************************************************/ | ||
263 | |||
264 | acpi_status | ||
265 | acpi_ut_execute_CID(struct acpi_namespace_node *device_node, | ||
266 | struct acpica_device_id_list **return_cid_list) | ||
267 | { | ||
268 | union acpi_operand_object **cid_objects; | ||
269 | union acpi_operand_object *obj_desc; | ||
270 | struct acpica_device_id_list *cid_list; | ||
271 | char *next_id_string; | ||
272 | u32 string_area_size; | ||
273 | u32 length; | ||
274 | u32 cid_list_size; | ||
275 | acpi_status status; | ||
276 | u32 count; | ||
277 | u32 i; | ||
278 | |||
279 | ACPI_FUNCTION_TRACE(ut_execute_CID); | ||
280 | |||
281 | /* Evaluate the _CID method for this device */ | ||
282 | |||
283 | status = acpi_ut_evaluate_object(device_node, METHOD_NAME__CID, | ||
284 | ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING | ||
285 | | ACPI_BTYPE_PACKAGE, &obj_desc); | ||
286 | if (ACPI_FAILURE(status)) { | ||
287 | return_ACPI_STATUS(status); | ||
288 | } | ||
289 | |||
290 | /* | ||
291 | * Get the count and size of the returned _CIDs. _CID can return either | ||
292 | * a Package of Integers/Strings or a single Integer or String. | ||
293 | * Note: This section also validates that all CID elements are of the | ||
294 | * correct type (Integer or String). | ||
295 | */ | ||
296 | if (obj_desc->common.type == ACPI_TYPE_PACKAGE) { | ||
297 | count = obj_desc->package.count; | ||
298 | cid_objects = obj_desc->package.elements; | ||
299 | } else { /* Single Integer or String CID */ | ||
300 | |||
301 | count = 1; | ||
302 | cid_objects = &obj_desc; | ||
303 | } | ||
304 | |||
305 | string_area_size = 0; | ||
306 | for (i = 0; i < count; i++) { | ||
307 | |||
308 | /* String lengths include null terminator */ | ||
309 | |||
310 | switch (cid_objects[i]->common.type) { | ||
311 | case ACPI_TYPE_INTEGER: | ||
312 | string_area_size += ACPI_EISAID_STRING_SIZE; | ||
313 | break; | ||
314 | |||
315 | case ACPI_TYPE_STRING: | ||
316 | string_area_size += cid_objects[i]->string.length + 1; | ||
317 | break; | ||
318 | |||
319 | default: | ||
320 | status = AE_TYPE; | ||
321 | goto cleanup; | ||
322 | } | ||
323 | } | ||
324 | |||
325 | /* | ||
326 | * Now that we know the length of the CIDs, allocate return buffer: | ||
327 | * 1) Size of the base structure + | ||
328 | * 2) Size of the CID DEVICE_ID array + | ||
329 | * 3) Size of the actual CID strings | ||
330 | */ | ||
331 | cid_list_size = sizeof(struct acpica_device_id_list) + | ||
332 | ((count - 1) * sizeof(struct acpica_device_id)) + string_area_size; | ||
333 | |||
334 | cid_list = ACPI_ALLOCATE_ZEROED(cid_list_size); | ||
335 | if (!cid_list) { | ||
336 | status = AE_NO_MEMORY; | ||
337 | goto cleanup; | ||
338 | } | ||
339 | |||
340 | /* Area for CID strings starts after the CID DEVICE_ID array */ | ||
341 | |||
342 | next_id_string = ACPI_CAST_PTR(char, cid_list->ids) + | ||
343 | ((acpi_size) count * sizeof(struct acpica_device_id)); | ||
344 | |||
345 | /* Copy/convert the CIDs to the return buffer */ | ||
346 | |||
347 | for (i = 0; i < count; i++) { | ||
348 | if (cid_objects[i]->common.type == ACPI_TYPE_INTEGER) { | ||
349 | |||
350 | /* Convert the Integer (EISAID) CID to a string */ | ||
351 | |||
352 | acpi_ex_eisa_id_to_string(next_id_string, | ||
353 | cid_objects[i]->integer. | ||
354 | value); | ||
355 | length = ACPI_EISAID_STRING_SIZE; | ||
356 | } else { /* ACPI_TYPE_STRING */ | ||
357 | |||
358 | /* Copy the String CID from the returned object */ | ||
359 | |||
360 | acpi_ut_copy_id_string(next_id_string, | ||
361 | cid_objects[i]->string.pointer); | ||
362 | length = cid_objects[i]->string.length + 1; | ||
363 | } | ||
364 | |||
365 | cid_list->ids[i].string = next_id_string; | ||
366 | cid_list->ids[i].length = length; | ||
367 | next_id_string += length; | ||
368 | } | ||
369 | |||
370 | /* Finish the CID list */ | ||
371 | |||
372 | cid_list->count = count; | ||
373 | cid_list->list_size = cid_list_size; | ||
374 | *return_cid_list = cid_list; | ||
375 | |||
376 | cleanup: | ||
377 | |||
378 | /* On exit, we must delete the _CID return object */ | ||
379 | |||
380 | acpi_ut_remove_reference(obj_desc); | ||
381 | return_ACPI_STATUS(status); | ||
382 | } | ||
diff --git a/drivers/acpi/acpica/utinit.c b/drivers/acpi/acpica/utinit.c index a54ca84eb362..9d0919ebf7b0 100644 --- a/drivers/acpi/acpica/utinit.c +++ b/drivers/acpi/acpica/utinit.c | |||
@@ -99,33 +99,19 @@ static void acpi_ut_terminate(void) | |||
99 | * | 99 | * |
100 | * FUNCTION: acpi_ut_subsystem_shutdown | 100 | * FUNCTION: acpi_ut_subsystem_shutdown |
101 | * | 101 | * |
102 | * PARAMETERS: none | 102 | * PARAMETERS: None |
103 | * | 103 | * |
104 | * RETURN: none | 104 | * RETURN: None |
105 | * | 105 | * |
106 | * DESCRIPTION: Shutdown the various subsystems. Don't delete the mutex | 106 | * DESCRIPTION: Shutdown the various components. Do not delete the mutex |
107 | * objects here -- because the AML debugger may be still running. | 107 | * objects here, because the AML debugger may be still running. |
108 | * | 108 | * |
109 | ******************************************************************************/ | 109 | ******************************************************************************/ |
110 | 110 | ||
111 | void acpi_ut_subsystem_shutdown(void) | 111 | void acpi_ut_subsystem_shutdown(void) |
112 | { | 112 | { |
113 | |||
114 | ACPI_FUNCTION_TRACE(ut_subsystem_shutdown); | 113 | ACPI_FUNCTION_TRACE(ut_subsystem_shutdown); |
115 | 114 | ||
116 | /* Just exit if subsystem is already shutdown */ | ||
117 | |||
118 | if (acpi_gbl_shutdown) { | ||
119 | ACPI_ERROR((AE_INFO, "ACPI Subsystem is already terminated")); | ||
120 | return_VOID; | ||
121 | } | ||
122 | |||
123 | /* Subsystem appears active, go ahead and shut it down */ | ||
124 | |||
125 | acpi_gbl_shutdown = TRUE; | ||
126 | acpi_gbl_startup_flags = 0; | ||
127 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Shutting down ACPI Subsystem\n")); | ||
128 | |||
129 | #ifndef ACPI_ASL_COMPILER | 115 | #ifndef ACPI_ASL_COMPILER |
130 | 116 | ||
131 | /* Close the acpi_event Handling */ | 117 | /* Close the acpi_event Handling */ |
diff --git a/drivers/acpi/acpica/utmisc.c b/drivers/acpi/acpica/utmisc.c index 1c9e250caefb..61f6315fce9f 100644 --- a/drivers/acpi/acpica/utmisc.c +++ b/drivers/acpi/acpica/utmisc.c | |||
@@ -50,6 +50,11 @@ | |||
50 | #define _COMPONENT ACPI_UTILITIES | 50 | #define _COMPONENT ACPI_UTILITIES |
51 | ACPI_MODULE_NAME("utmisc") | 51 | ACPI_MODULE_NAME("utmisc") |
52 | 52 | ||
53 | /* | ||
54 | * Common suffix for messages | ||
55 | */ | ||
56 | #define ACPI_COMMON_MSG_SUFFIX \ | ||
57 | acpi_os_printf(" (%8.8X/%s-%u)\n", ACPI_CA_VERSION, module_name, line_number) | ||
53 | /******************************************************************************* | 58 | /******************************************************************************* |
54 | * | 59 | * |
55 | * FUNCTION: acpi_ut_validate_exception | 60 | * FUNCTION: acpi_ut_validate_exception |
@@ -120,6 +125,34 @@ const char *acpi_ut_validate_exception(acpi_status status) | |||
120 | 125 | ||
121 | /******************************************************************************* | 126 | /******************************************************************************* |
122 | * | 127 | * |
128 | * FUNCTION: acpi_ut_is_pci_root_bridge | ||
129 | * | ||
130 | * PARAMETERS: Id - The HID/CID in string format | ||
131 | * | ||
132 | * RETURN: TRUE if the Id is a match for a PCI/PCI-Express Root Bridge | ||
133 | * | ||
134 | * DESCRIPTION: Determine if the input ID is a PCI Root Bridge ID. | ||
135 | * | ||
136 | ******************************************************************************/ | ||
137 | |||
138 | u8 acpi_ut_is_pci_root_bridge(char *id) | ||
139 | { | ||
140 | |||
141 | /* | ||
142 | * Check if this is a PCI root bridge. | ||
143 | * ACPI 3.0+: check for a PCI Express root also. | ||
144 | */ | ||
145 | if (!(ACPI_STRCMP(id, | ||
146 | PCI_ROOT_HID_STRING)) || | ||
147 | !(ACPI_STRCMP(id, PCI_EXPRESS_ROOT_HID_STRING))) { | ||
148 | return (TRUE); | ||
149 | } | ||
150 | |||
151 | return (FALSE); | ||
152 | } | ||
153 | |||
154 | /******************************************************************************* | ||
155 | * | ||
123 | * FUNCTION: acpi_ut_is_aml_table | 156 | * FUNCTION: acpi_ut_is_aml_table |
124 | * | 157 | * |
125 | * PARAMETERS: Table - An ACPI table | 158 | * PARAMETERS: Table - An ACPI table |
@@ -1033,11 +1066,11 @@ acpi_error(const char *module_name, u32 line_number, const char *format, ...) | |||
1033 | { | 1066 | { |
1034 | va_list args; | 1067 | va_list args; |
1035 | 1068 | ||
1036 | acpi_os_printf("ACPI Error (%s-%04d): ", module_name, line_number); | 1069 | acpi_os_printf("ACPI Error: "); |
1037 | 1070 | ||
1038 | va_start(args, format); | 1071 | va_start(args, format); |
1039 | acpi_os_vprintf(format, args); | 1072 | acpi_os_vprintf(format, args); |
1040 | acpi_os_printf(" [%X]\n", ACPI_CA_VERSION); | 1073 | ACPI_COMMON_MSG_SUFFIX; |
1041 | va_end(args); | 1074 | va_end(args); |
1042 | } | 1075 | } |
1043 | 1076 | ||
@@ -1047,12 +1080,11 @@ acpi_exception(const char *module_name, | |||
1047 | { | 1080 | { |
1048 | va_list args; | 1081 | va_list args; |
1049 | 1082 | ||
1050 | acpi_os_printf("ACPI Exception (%s-%04d): %s, ", module_name, | 1083 | acpi_os_printf("ACPI Exception: %s, ", acpi_format_exception(status)); |
1051 | line_number, acpi_format_exception(status)); | ||
1052 | 1084 | ||
1053 | va_start(args, format); | 1085 | va_start(args, format); |
1054 | acpi_os_vprintf(format, args); | 1086 | acpi_os_vprintf(format, args); |
1055 | acpi_os_printf(" [%X]\n", ACPI_CA_VERSION); | 1087 | ACPI_COMMON_MSG_SUFFIX; |
1056 | va_end(args); | 1088 | va_end(args); |
1057 | } | 1089 | } |
1058 | 1090 | ||
@@ -1061,11 +1093,11 @@ acpi_warning(const char *module_name, u32 line_number, const char *format, ...) | |||
1061 | { | 1093 | { |
1062 | va_list args; | 1094 | va_list args; |
1063 | 1095 | ||
1064 | acpi_os_printf("ACPI Warning (%s-%04d): ", module_name, line_number); | 1096 | acpi_os_printf("ACPI Warning: "); |
1065 | 1097 | ||
1066 | va_start(args, format); | 1098 | va_start(args, format); |
1067 | acpi_os_vprintf(format, args); | 1099 | acpi_os_vprintf(format, args); |
1068 | acpi_os_printf(" [%X]\n", ACPI_CA_VERSION); | 1100 | ACPI_COMMON_MSG_SUFFIX; |
1069 | va_end(args); | 1101 | va_end(args); |
1070 | } | 1102 | } |
1071 | 1103 | ||
@@ -1074,10 +1106,6 @@ acpi_info(const char *module_name, u32 line_number, const char *format, ...) | |||
1074 | { | 1106 | { |
1075 | va_list args; | 1107 | va_list args; |
1076 | 1108 | ||
1077 | /* | ||
1078 | * Removed module_name, line_number, and acpica version, not needed | ||
1079 | * for info output | ||
1080 | */ | ||
1081 | acpi_os_printf("ACPI: "); | 1109 | acpi_os_printf("ACPI: "); |
1082 | 1110 | ||
1083 | va_start(args, format); | 1111 | va_start(args, format); |
@@ -1090,3 +1118,46 @@ ACPI_EXPORT_SYMBOL(acpi_error) | |||
1090 | ACPI_EXPORT_SYMBOL(acpi_exception) | 1118 | ACPI_EXPORT_SYMBOL(acpi_exception) |
1091 | ACPI_EXPORT_SYMBOL(acpi_warning) | 1119 | ACPI_EXPORT_SYMBOL(acpi_warning) |
1092 | ACPI_EXPORT_SYMBOL(acpi_info) | 1120 | ACPI_EXPORT_SYMBOL(acpi_info) |
1121 | |||
1122 | /******************************************************************************* | ||
1123 | * | ||
1124 | * FUNCTION: acpi_ut_predefined_warning | ||
1125 | * | ||
1126 | * PARAMETERS: module_name - Caller's module name (for error output) | ||
1127 | * line_number - Caller's line number (for error output) | ||
1128 | * Pathname - Full pathname to the node | ||
1129 | * node_flags - From Namespace node for the method/object | ||
1130 | * Format - Printf format string + additional args | ||
1131 | * | ||
1132 | * RETURN: None | ||
1133 | * | ||
1134 | * DESCRIPTION: Warnings for the predefined validation module. Messages are | ||
1135 | * only emitted the first time a problem with a particular | ||
1136 | * method/object is detected. This prevents a flood of error | ||
1137 | * messages for methods that are repeatedly evaluated. | ||
1138 | * | ||
1139 | ******************************************************************************/ | ||
1140 | |||
1141 | void ACPI_INTERNAL_VAR_XFACE | ||
1142 | acpi_ut_predefined_warning(const char *module_name, | ||
1143 | u32 line_number, | ||
1144 | char *pathname, | ||
1145 | u8 node_flags, const char *format, ...) | ||
1146 | { | ||
1147 | va_list args; | ||
1148 | |||
1149 | /* | ||
1150 | * Warning messages for this method/object will be disabled after the | ||
1151 | * first time a validation fails or an object is successfully repaired. | ||
1152 | */ | ||
1153 | if (node_flags & ANOBJ_EVALUATED) { | ||
1154 | return; | ||
1155 | } | ||
1156 | |||
1157 | acpi_os_printf("ACPI Warning for %s: ", pathname); | ||
1158 | |||
1159 | va_start(args, format); | ||
1160 | acpi_os_vprintf(format, args); | ||
1161 | ACPI_COMMON_MSG_SUFFIX; | ||
1162 | va_end(args); | ||
1163 | } | ||
diff --git a/drivers/acpi/acpica/utmutex.c b/drivers/acpi/acpica/utmutex.c index 26c93a748e64..80bb65154117 100644 --- a/drivers/acpi/acpica/utmutex.c +++ b/drivers/acpi/acpica/utmutex.c | |||
@@ -230,17 +230,18 @@ acpi_status acpi_ut_acquire_mutex(acpi_mutex_handle mutex_id) | |||
230 | if (acpi_gbl_mutex_info[i].thread_id == this_thread_id) { | 230 | if (acpi_gbl_mutex_info[i].thread_id == this_thread_id) { |
231 | if (i == mutex_id) { | 231 | if (i == mutex_id) { |
232 | ACPI_ERROR((AE_INFO, | 232 | ACPI_ERROR((AE_INFO, |
233 | "Mutex [%s] already acquired by this thread [%X]", | 233 | "Mutex [%s] already acquired by this thread [%p]", |
234 | acpi_ut_get_mutex_name | 234 | acpi_ut_get_mutex_name |
235 | (mutex_id), | 235 | (mutex_id), |
236 | this_thread_id)); | 236 | ACPI_CAST_PTR(void, |
237 | this_thread_id))); | ||
237 | 238 | ||
238 | return (AE_ALREADY_ACQUIRED); | 239 | return (AE_ALREADY_ACQUIRED); |
239 | } | 240 | } |
240 | 241 | ||
241 | ACPI_ERROR((AE_INFO, | 242 | ACPI_ERROR((AE_INFO, |
242 | "Invalid acquire order: Thread %X owns [%s], wants [%s]", | 243 | "Invalid acquire order: Thread %p owns [%s], wants [%s]", |
243 | this_thread_id, | 244 | ACPI_CAST_PTR(void, this_thread_id), |
244 | acpi_ut_get_mutex_name(i), | 245 | acpi_ut_get_mutex_name(i), |
245 | acpi_ut_get_mutex_name(mutex_id))); | 246 | acpi_ut_get_mutex_name(mutex_id))); |
246 | 247 | ||
@@ -251,24 +252,24 @@ acpi_status acpi_ut_acquire_mutex(acpi_mutex_handle mutex_id) | |||
251 | #endif | 252 | #endif |
252 | 253 | ||
253 | ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, | 254 | ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, |
254 | "Thread %lX attempting to acquire Mutex [%s]\n", | 255 | "Thread %p attempting to acquire Mutex [%s]\n", |
255 | (unsigned long)this_thread_id, | 256 | ACPI_CAST_PTR(void, this_thread_id), |
256 | acpi_ut_get_mutex_name(mutex_id))); | 257 | acpi_ut_get_mutex_name(mutex_id))); |
257 | 258 | ||
258 | status = acpi_os_acquire_mutex(acpi_gbl_mutex_info[mutex_id].mutex, | 259 | status = acpi_os_acquire_mutex(acpi_gbl_mutex_info[mutex_id].mutex, |
259 | ACPI_WAIT_FOREVER); | 260 | ACPI_WAIT_FOREVER); |
260 | if (ACPI_SUCCESS(status)) { | 261 | if (ACPI_SUCCESS(status)) { |
261 | ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, | 262 | ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, |
262 | "Thread %lX acquired Mutex [%s]\n", | 263 | "Thread %p acquired Mutex [%s]\n", |
263 | (unsigned long)this_thread_id, | 264 | ACPI_CAST_PTR(void, this_thread_id), |
264 | acpi_ut_get_mutex_name(mutex_id))); | 265 | acpi_ut_get_mutex_name(mutex_id))); |
265 | 266 | ||
266 | acpi_gbl_mutex_info[mutex_id].use_count++; | 267 | acpi_gbl_mutex_info[mutex_id].use_count++; |
267 | acpi_gbl_mutex_info[mutex_id].thread_id = this_thread_id; | 268 | acpi_gbl_mutex_info[mutex_id].thread_id = this_thread_id; |
268 | } else { | 269 | } else { |
269 | ACPI_EXCEPTION((AE_INFO, status, | 270 | ACPI_EXCEPTION((AE_INFO, status, |
270 | "Thread %lX could not acquire Mutex [%X]", | 271 | "Thread %p could not acquire Mutex [%X]", |
271 | (unsigned long)this_thread_id, mutex_id)); | 272 | ACPI_CAST_PTR(void, this_thread_id), mutex_id)); |
272 | } | 273 | } |
273 | 274 | ||
274 | return (status); | 275 | return (status); |
@@ -293,9 +294,8 @@ acpi_status acpi_ut_release_mutex(acpi_mutex_handle mutex_id) | |||
293 | ACPI_FUNCTION_NAME(ut_release_mutex); | 294 | ACPI_FUNCTION_NAME(ut_release_mutex); |
294 | 295 | ||
295 | this_thread_id = acpi_os_get_thread_id(); | 296 | this_thread_id = acpi_os_get_thread_id(); |
296 | ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, | 297 | ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Thread %p releasing Mutex [%s]\n", |
297 | "Thread %lX releasing Mutex [%s]\n", | 298 | ACPI_CAST_PTR(void, this_thread_id), |
298 | (unsigned long)this_thread_id, | ||
299 | acpi_ut_get_mutex_name(mutex_id))); | 299 | acpi_ut_get_mutex_name(mutex_id))); |
300 | 300 | ||
301 | if (mutex_id > ACPI_MAX_MUTEX) { | 301 | if (mutex_id > ACPI_MAX_MUTEX) { |
diff --git a/drivers/acpi/acpica/utxface.c b/drivers/acpi/acpica/utxface.c index 078a22728c6b..b1f5f680bc78 100644 --- a/drivers/acpi/acpica/utxface.c +++ b/drivers/acpi/acpica/utxface.c | |||
@@ -251,6 +251,16 @@ acpi_status acpi_initialize_objects(u32 flags) | |||
251 | } | 251 | } |
252 | 252 | ||
253 | /* | 253 | /* |
254 | * Execute any module-level code that was detected during the table load | ||
255 | * phase. Although illegal since ACPI 2.0, there are many machines that | ||
256 | * contain this type of code. Each block of detected executable AML code | ||
257 | * outside of any control method is wrapped with a temporary control | ||
258 | * method object and placed on a global list. The methods on this list | ||
259 | * are executed below. | ||
260 | */ | ||
261 | acpi_ns_exec_module_code_list(); | ||
262 | |||
263 | /* | ||
254 | * Initialize the objects that remain uninitialized. This runs the | 264 | * Initialize the objects that remain uninitialized. This runs the |
255 | * executable AML that may be part of the declaration of these objects: | 265 | * executable AML that may be part of the declaration of these objects: |
256 | * operation_regions, buffer_fields, Buffers, and Packages. | 266 | * operation_regions, buffer_fields, Buffers, and Packages. |
@@ -318,7 +328,7 @@ ACPI_EXPORT_SYMBOL(acpi_initialize_objects) | |||
318 | * | 328 | * |
319 | * RETURN: Status | 329 | * RETURN: Status |
320 | * | 330 | * |
321 | * DESCRIPTION: Shutdown the ACPI subsystem. Release all resources. | 331 | * DESCRIPTION: Shutdown the ACPICA subsystem and release all resources. |
322 | * | 332 | * |
323 | ******************************************************************************/ | 333 | ******************************************************************************/ |
324 | acpi_status acpi_terminate(void) | 334 | acpi_status acpi_terminate(void) |
@@ -327,6 +337,19 @@ acpi_status acpi_terminate(void) | |||
327 | 337 | ||
328 | ACPI_FUNCTION_TRACE(acpi_terminate); | 338 | ACPI_FUNCTION_TRACE(acpi_terminate); |
329 | 339 | ||
340 | /* Just exit if subsystem is already shutdown */ | ||
341 | |||
342 | if (acpi_gbl_shutdown) { | ||
343 | ACPI_ERROR((AE_INFO, "ACPI Subsystem is already terminated")); | ||
344 | return_ACPI_STATUS(AE_OK); | ||
345 | } | ||
346 | |||
347 | /* Subsystem appears active, go ahead and shut it down */ | ||
348 | |||
349 | acpi_gbl_shutdown = TRUE; | ||
350 | acpi_gbl_startup_flags = 0; | ||
351 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Shutting down ACPI Subsystem\n")); | ||
352 | |||
330 | /* Terminate the AML Debugger if present */ | 353 | /* Terminate the AML Debugger if present */ |
331 | 354 | ||
332 | ACPI_DEBUGGER_EXEC(acpi_gbl_db_terminate_threads = TRUE); | 355 | ACPI_DEBUGGER_EXEC(acpi_gbl_db_terminate_threads = TRUE); |
@@ -353,6 +376,7 @@ acpi_status acpi_terminate(void) | |||
353 | } | 376 | } |
354 | 377 | ||
355 | ACPI_EXPORT_SYMBOL(acpi_terminate) | 378 | ACPI_EXPORT_SYMBOL(acpi_terminate) |
379 | |||
356 | #ifndef ACPI_ASL_COMPILER | 380 | #ifndef ACPI_ASL_COMPILER |
357 | #ifdef ACPI_FUTURE_USAGE | 381 | #ifdef ACPI_FUTURE_USAGE |
358 | /******************************************************************************* | 382 | /******************************************************************************* |
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index b0de6312919a..3f4602b8f287 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/types.h> | 31 | #include <linux/types.h> |
32 | #include <linux/jiffies.h> | 32 | #include <linux/jiffies.h> |
33 | #include <linux/async.h> | 33 | #include <linux/async.h> |
34 | #include <linux/dmi.h> | ||
34 | 35 | ||
35 | #ifdef CONFIG_ACPI_PROCFS_POWER | 36 | #ifdef CONFIG_ACPI_PROCFS_POWER |
36 | #include <linux/proc_fs.h> | 37 | #include <linux/proc_fs.h> |
@@ -45,6 +46,8 @@ | |||
45 | #include <linux/power_supply.h> | 46 | #include <linux/power_supply.h> |
46 | #endif | 47 | #endif |
47 | 48 | ||
49 | #define PREFIX "ACPI: " | ||
50 | |||
48 | #define ACPI_BATTERY_VALUE_UNKNOWN 0xFFFFFFFF | 51 | #define ACPI_BATTERY_VALUE_UNKNOWN 0xFFFFFFFF |
49 | 52 | ||
50 | #define ACPI_BATTERY_CLASS "battery" | 53 | #define ACPI_BATTERY_CLASS "battery" |
@@ -85,6 +88,10 @@ static const struct acpi_device_id battery_device_ids[] = { | |||
85 | 88 | ||
86 | MODULE_DEVICE_TABLE(acpi, battery_device_ids); | 89 | MODULE_DEVICE_TABLE(acpi, battery_device_ids); |
87 | 90 | ||
91 | /* For buggy DSDTs that report negative 16-bit values for either charging | ||
92 | * or discharging current and/or report 0 as 65536 due to bad math. | ||
93 | */ | ||
94 | #define QUIRK_SIGNED16_CURRENT 0x0001 | ||
88 | 95 | ||
89 | struct acpi_battery { | 96 | struct acpi_battery { |
90 | struct mutex lock; | 97 | struct mutex lock; |
@@ -112,6 +119,7 @@ struct acpi_battery { | |||
112 | int state; | 119 | int state; |
113 | int power_unit; | 120 | int power_unit; |
114 | u8 alarm_present; | 121 | u8 alarm_present; |
122 | long quirks; | ||
115 | }; | 123 | }; |
116 | 124 | ||
117 | #define to_acpi_battery(x) container_of(x, struct acpi_battery, bat); | 125 | #define to_acpi_battery(x) container_of(x, struct acpi_battery, bat); |
@@ -390,6 +398,11 @@ static int acpi_battery_get_state(struct acpi_battery *battery) | |||
390 | state_offsets, ARRAY_SIZE(state_offsets)); | 398 | state_offsets, ARRAY_SIZE(state_offsets)); |
391 | battery->update_time = jiffies; | 399 | battery->update_time = jiffies; |
392 | kfree(buffer.pointer); | 400 | kfree(buffer.pointer); |
401 | |||
402 | if ((battery->quirks & QUIRK_SIGNED16_CURRENT) && | ||
403 | battery->rate_now != -1) | ||
404 | battery->rate_now = abs((s16)battery->rate_now); | ||
405 | |||
393 | return result; | 406 | return result; |
394 | } | 407 | } |
395 | 408 | ||
@@ -495,6 +508,14 @@ static void sysfs_remove_battery(struct acpi_battery *battery) | |||
495 | } | 508 | } |
496 | #endif | 509 | #endif |
497 | 510 | ||
511 | static void acpi_battery_quirks(struct acpi_battery *battery) | ||
512 | { | ||
513 | battery->quirks = 0; | ||
514 | if (dmi_name_in_vendors("Acer") && battery->power_unit) { | ||
515 | battery->quirks |= QUIRK_SIGNED16_CURRENT; | ||
516 | } | ||
517 | } | ||
518 | |||
498 | static int acpi_battery_update(struct acpi_battery *battery) | 519 | static int acpi_battery_update(struct acpi_battery *battery) |
499 | { | 520 | { |
500 | int result, old_present = acpi_battery_present(battery); | 521 | int result, old_present = acpi_battery_present(battery); |
@@ -513,6 +534,7 @@ static int acpi_battery_update(struct acpi_battery *battery) | |||
513 | result = acpi_battery_get_info(battery); | 534 | result = acpi_battery_get_info(battery); |
514 | if (result) | 535 | if (result) |
515 | return result; | 536 | return result; |
537 | acpi_battery_quirks(battery); | ||
516 | acpi_battery_init_alarm(battery); | 538 | acpi_battery_init_alarm(battery); |
517 | } | 539 | } |
518 | #ifdef CONFIG_ACPI_SYSFS_POWER | 540 | #ifdef CONFIG_ACPI_SYSFS_POWER |
@@ -796,13 +818,12 @@ static void acpi_battery_remove_fs(struct acpi_device *device) | |||
796 | Driver Interface | 818 | Driver Interface |
797 | -------------------------------------------------------------------------- */ | 819 | -------------------------------------------------------------------------- */ |
798 | 820 | ||
799 | static void acpi_battery_notify(acpi_handle handle, u32 event, void *data) | 821 | static void acpi_battery_notify(struct acpi_device *device, u32 event) |
800 | { | 822 | { |
801 | struct acpi_battery *battery = data; | 823 | struct acpi_battery *battery = acpi_driver_data(device); |
802 | struct acpi_device *device; | 824 | |
803 | if (!battery) | 825 | if (!battery) |
804 | return; | 826 | return; |
805 | device = battery->device; | ||
806 | acpi_battery_update(battery); | 827 | acpi_battery_update(battery); |
807 | acpi_bus_generate_proc_event(device, event, | 828 | acpi_bus_generate_proc_event(device, event, |
808 | acpi_battery_present(battery)); | 829 | acpi_battery_present(battery)); |
@@ -819,7 +840,6 @@ static void acpi_battery_notify(acpi_handle handle, u32 event, void *data) | |||
819 | static int acpi_battery_add(struct acpi_device *device) | 840 | static int acpi_battery_add(struct acpi_device *device) |
820 | { | 841 | { |
821 | int result = 0; | 842 | int result = 0; |
822 | acpi_status status = 0; | ||
823 | struct acpi_battery *battery = NULL; | 843 | struct acpi_battery *battery = NULL; |
824 | if (!device) | 844 | if (!device) |
825 | return -EINVAL; | 845 | return -EINVAL; |
@@ -834,22 +854,12 @@ static int acpi_battery_add(struct acpi_device *device) | |||
834 | acpi_battery_update(battery); | 854 | acpi_battery_update(battery); |
835 | #ifdef CONFIG_ACPI_PROCFS_POWER | 855 | #ifdef CONFIG_ACPI_PROCFS_POWER |
836 | result = acpi_battery_add_fs(device); | 856 | result = acpi_battery_add_fs(device); |
837 | if (result) | ||
838 | goto end; | ||
839 | #endif | 857 | #endif |
840 | status = acpi_install_notify_handler(device->handle, | 858 | if (!result) { |
841 | ACPI_ALL_NOTIFY, | 859 | printk(KERN_INFO PREFIX "%s Slot [%s] (battery %s)\n", |
842 | acpi_battery_notify, battery); | 860 | ACPI_BATTERY_DEVICE_NAME, acpi_device_bid(device), |
843 | if (ACPI_FAILURE(status)) { | 861 | device->status.battery_present ? "present" : "absent"); |
844 | ACPI_EXCEPTION((AE_INFO, status, "Installing notify handler")); | 862 | } else { |
845 | result = -ENODEV; | ||
846 | goto end; | ||
847 | } | ||
848 | printk(KERN_INFO PREFIX "%s Slot [%s] (battery %s)\n", | ||
849 | ACPI_BATTERY_DEVICE_NAME, acpi_device_bid(device), | ||
850 | device->status.battery_present ? "present" : "absent"); | ||
851 | end: | ||
852 | if (result) { | ||
853 | #ifdef CONFIG_ACPI_PROCFS_POWER | 863 | #ifdef CONFIG_ACPI_PROCFS_POWER |
854 | acpi_battery_remove_fs(device); | 864 | acpi_battery_remove_fs(device); |
855 | #endif | 865 | #endif |
@@ -860,15 +870,11 @@ static int acpi_battery_add(struct acpi_device *device) | |||
860 | 870 | ||
861 | static int acpi_battery_remove(struct acpi_device *device, int type) | 871 | static int acpi_battery_remove(struct acpi_device *device, int type) |
862 | { | 872 | { |
863 | acpi_status status = 0; | ||
864 | struct acpi_battery *battery = NULL; | 873 | struct acpi_battery *battery = NULL; |
865 | 874 | ||
866 | if (!device || !acpi_driver_data(device)) | 875 | if (!device || !acpi_driver_data(device)) |
867 | return -EINVAL; | 876 | return -EINVAL; |
868 | battery = acpi_driver_data(device); | 877 | battery = acpi_driver_data(device); |
869 | status = acpi_remove_notify_handler(device->handle, | ||
870 | ACPI_ALL_NOTIFY, | ||
871 | acpi_battery_notify); | ||
872 | #ifdef CONFIG_ACPI_PROCFS_POWER | 878 | #ifdef CONFIG_ACPI_PROCFS_POWER |
873 | acpi_battery_remove_fs(device); | 879 | acpi_battery_remove_fs(device); |
874 | #endif | 880 | #endif |
@@ -896,10 +902,12 @@ static struct acpi_driver acpi_battery_driver = { | |||
896 | .name = "battery", | 902 | .name = "battery", |
897 | .class = ACPI_BATTERY_CLASS, | 903 | .class = ACPI_BATTERY_CLASS, |
898 | .ids = battery_device_ids, | 904 | .ids = battery_device_ids, |
905 | .flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS, | ||
899 | .ops = { | 906 | .ops = { |
900 | .add = acpi_battery_add, | 907 | .add = acpi_battery_add, |
901 | .resume = acpi_battery_resume, | 908 | .resume = acpi_battery_resume, |
902 | .remove = acpi_battery_remove, | 909 | .remove = acpi_battery_remove, |
910 | .notify = acpi_battery_notify, | ||
903 | }, | 911 | }, |
904 | }; | 912 | }; |
905 | 913 | ||
diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c index 09c69806c1fc..e56b2a7b53db 100644 --- a/drivers/acpi/blacklist.c +++ b/drivers/acpi/blacklist.c | |||
@@ -34,6 +34,8 @@ | |||
34 | #include <acpi/acpi_bus.h> | 34 | #include <acpi/acpi_bus.h> |
35 | #include <linux/dmi.h> | 35 | #include <linux/dmi.h> |
36 | 36 | ||
37 | #include "internal.h" | ||
38 | |||
37 | enum acpi_blacklist_predicates { | 39 | enum acpi_blacklist_predicates { |
38 | all_versions, | 40 | all_versions, |
39 | less_than_or_equal, | 41 | less_than_or_equal, |
@@ -78,9 +80,10 @@ static struct acpi_blacklist_item acpi_blacklist[] __initdata = { | |||
78 | 80 | ||
79 | static int __init blacklist_by_year(void) | 81 | static int __init blacklist_by_year(void) |
80 | { | 82 | { |
81 | int year = dmi_get_year(DMI_BIOS_DATE); | 83 | int year; |
84 | |||
82 | /* Doesn't exist? Likely an old system */ | 85 | /* Doesn't exist? Likely an old system */ |
83 | if (year == -1) { | 86 | if (!dmi_get_date(DMI_BIOS_DATE, &year, NULL, NULL)) { |
84 | printk(KERN_ERR PREFIX "no DMI BIOS year, " | 87 | printk(KERN_ERR PREFIX "no DMI BIOS year, " |
85 | "acpi=force is required to enable ACPI\n" ); | 88 | "acpi=force is required to enable ACPI\n" ); |
86 | return 1; | 89 | return 1; |
@@ -192,6 +195,22 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { | |||
192 | DMI_MATCH(DMI_PRODUCT_NAME, "ESPRIMO Mobile V5505"), | 195 | DMI_MATCH(DMI_PRODUCT_NAME, "ESPRIMO Mobile V5505"), |
193 | }, | 196 | }, |
194 | }, | 197 | }, |
198 | { | ||
199 | .callback = dmi_disable_osi_vista, | ||
200 | .ident = "Sony VGN-NS10J_S", | ||
201 | .matches = { | ||
202 | DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), | ||
203 | DMI_MATCH(DMI_PRODUCT_NAME, "VGN-NS10J_S"), | ||
204 | }, | ||
205 | }, | ||
206 | { | ||
207 | .callback = dmi_disable_osi_vista, | ||
208 | .ident = "Sony VGN-SR290J", | ||
209 | .matches = { | ||
210 | DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), | ||
211 | DMI_MATCH(DMI_PRODUCT_NAME, "Sony VGN-SR290J"), | ||
212 | }, | ||
213 | }, | ||
195 | 214 | ||
196 | /* | 215 | /* |
197 | * BIOS invocation of _OSI(Linux) is almost always a BIOS bug. | 216 | * BIOS invocation of _OSI(Linux) is almost always a BIOS bug. |
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index ae862f1798dc..620183f13e5e 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c | |||
@@ -141,7 +141,7 @@ int acpi_bus_get_status(struct acpi_device *device) | |||
141 | EXPORT_SYMBOL(acpi_bus_get_status); | 141 | EXPORT_SYMBOL(acpi_bus_get_status); |
142 | 142 | ||
143 | void acpi_bus_private_data_handler(acpi_handle handle, | 143 | void acpi_bus_private_data_handler(acpi_handle handle, |
144 | u32 function, void *context) | 144 | void *context) |
145 | { | 145 | { |
146 | return; | 146 | return; |
147 | } | 147 | } |
@@ -450,18 +450,16 @@ int acpi_bus_receive_event(struct acpi_bus_event *event) | |||
450 | Notification Handling | 450 | Notification Handling |
451 | -------------------------------------------------------------------------- */ | 451 | -------------------------------------------------------------------------- */ |
452 | 452 | ||
453 | static int | 453 | static void acpi_bus_check_device(acpi_handle handle) |
454 | acpi_bus_check_device(struct acpi_device *device, int *status_changed) | ||
455 | { | 454 | { |
456 | acpi_status status = 0; | 455 | struct acpi_device *device; |
456 | acpi_status status; | ||
457 | struct acpi_device_status old_status; | 457 | struct acpi_device_status old_status; |
458 | 458 | ||
459 | 459 | if (acpi_bus_get_device(handle, &device)) | |
460 | return; | ||
460 | if (!device) | 461 | if (!device) |
461 | return -EINVAL; | 462 | return; |
462 | |||
463 | if (status_changed) | ||
464 | *status_changed = 0; | ||
465 | 463 | ||
466 | old_status = device->status; | 464 | old_status = device->status; |
467 | 465 | ||
@@ -471,22 +469,15 @@ acpi_bus_check_device(struct acpi_device *device, int *status_changed) | |||
471 | */ | 469 | */ |
472 | if (device->parent && !device->parent->status.present) { | 470 | if (device->parent && !device->parent->status.present) { |
473 | device->status = device->parent->status; | 471 | device->status = device->parent->status; |
474 | if (STRUCT_TO_INT(old_status) != STRUCT_TO_INT(device->status)) { | 472 | return; |
475 | if (status_changed) | ||
476 | *status_changed = 1; | ||
477 | } | ||
478 | return 0; | ||
479 | } | 473 | } |
480 | 474 | ||
481 | status = acpi_bus_get_status(device); | 475 | status = acpi_bus_get_status(device); |
482 | if (ACPI_FAILURE(status)) | 476 | if (ACPI_FAILURE(status)) |
483 | return -ENODEV; | 477 | return; |
484 | 478 | ||
485 | if (STRUCT_TO_INT(old_status) == STRUCT_TO_INT(device->status)) | 479 | if (STRUCT_TO_INT(old_status) == STRUCT_TO_INT(device->status)) |
486 | return 0; | 480 | return; |
487 | |||
488 | if (status_changed) | ||
489 | *status_changed = 1; | ||
490 | 481 | ||
491 | /* | 482 | /* |
492 | * Device Insertion/Removal | 483 | * Device Insertion/Removal |
@@ -498,33 +489,17 @@ acpi_bus_check_device(struct acpi_device *device, int *status_changed) | |||
498 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device removal detected\n")); | 489 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device removal detected\n")); |
499 | /* TBD: Handle device removal */ | 490 | /* TBD: Handle device removal */ |
500 | } | 491 | } |
501 | |||
502 | return 0; | ||
503 | } | 492 | } |
504 | 493 | ||
505 | static int acpi_bus_check_scope(struct acpi_device *device) | 494 | static void acpi_bus_check_scope(acpi_handle handle) |
506 | { | 495 | { |
507 | int result = 0; | ||
508 | int status_changed = 0; | ||
509 | |||
510 | |||
511 | if (!device) | ||
512 | return -EINVAL; | ||
513 | |||
514 | /* Status Change? */ | 496 | /* Status Change? */ |
515 | result = acpi_bus_check_device(device, &status_changed); | 497 | acpi_bus_check_device(handle); |
516 | if (result) | ||
517 | return result; | ||
518 | |||
519 | if (!status_changed) | ||
520 | return 0; | ||
521 | 498 | ||
522 | /* | 499 | /* |
523 | * TBD: Enumerate child devices within this device's scope and | 500 | * TBD: Enumerate child devices within this device's scope and |
524 | * run acpi_bus_check_device()'s on them. | 501 | * run acpi_bus_check_device()'s on them. |
525 | */ | 502 | */ |
526 | |||
527 | return 0; | ||
528 | } | 503 | } |
529 | 504 | ||
530 | static BLOCKING_NOTIFIER_HEAD(acpi_bus_notify_list); | 505 | static BLOCKING_NOTIFIER_HEAD(acpi_bus_notify_list); |
@@ -547,22 +522,19 @@ EXPORT_SYMBOL_GPL(unregister_acpi_bus_notifier); | |||
547 | */ | 522 | */ |
548 | static void acpi_bus_notify(acpi_handle handle, u32 type, void *data) | 523 | static void acpi_bus_notify(acpi_handle handle, u32 type, void *data) |
549 | { | 524 | { |
550 | int result = 0; | ||
551 | struct acpi_device *device = NULL; | 525 | struct acpi_device *device = NULL; |
526 | struct acpi_driver *driver; | ||
527 | |||
528 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Notification %#02x to handle %p\n", | ||
529 | type, handle)); | ||
552 | 530 | ||
553 | blocking_notifier_call_chain(&acpi_bus_notify_list, | 531 | blocking_notifier_call_chain(&acpi_bus_notify_list, |
554 | type, (void *)handle); | 532 | type, (void *)handle); |
555 | 533 | ||
556 | if (acpi_bus_get_device(handle, &device)) | ||
557 | return; | ||
558 | |||
559 | switch (type) { | 534 | switch (type) { |
560 | 535 | ||
561 | case ACPI_NOTIFY_BUS_CHECK: | 536 | case ACPI_NOTIFY_BUS_CHECK: |
562 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 537 | acpi_bus_check_scope(handle); |
563 | "Received BUS CHECK notification for device [%s]\n", | ||
564 | device->pnp.bus_id)); | ||
565 | result = acpi_bus_check_scope(device); | ||
566 | /* | 538 | /* |
567 | * TBD: We'll need to outsource certain events to non-ACPI | 539 | * TBD: We'll need to outsource certain events to non-ACPI |
568 | * drivers via the device manager (device.c). | 540 | * drivers via the device manager (device.c). |
@@ -570,10 +542,7 @@ static void acpi_bus_notify(acpi_handle handle, u32 type, void *data) | |||
570 | break; | 542 | break; |
571 | 543 | ||
572 | case ACPI_NOTIFY_DEVICE_CHECK: | 544 | case ACPI_NOTIFY_DEVICE_CHECK: |
573 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 545 | acpi_bus_check_device(handle); |
574 | "Received DEVICE CHECK notification for device [%s]\n", | ||
575 | device->pnp.bus_id)); | ||
576 | result = acpi_bus_check_device(device, NULL); | ||
577 | /* | 546 | /* |
578 | * TBD: We'll need to outsource certain events to non-ACPI | 547 | * TBD: We'll need to outsource certain events to non-ACPI |
579 | * drivers via the device manager (device.c). | 548 | * drivers via the device manager (device.c). |
@@ -581,44 +550,26 @@ static void acpi_bus_notify(acpi_handle handle, u32 type, void *data) | |||
581 | break; | 550 | break; |
582 | 551 | ||
583 | case ACPI_NOTIFY_DEVICE_WAKE: | 552 | case ACPI_NOTIFY_DEVICE_WAKE: |
584 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
585 | "Received DEVICE WAKE notification for device [%s]\n", | ||
586 | device->pnp.bus_id)); | ||
587 | /* TBD */ | 553 | /* TBD */ |
588 | break; | 554 | break; |
589 | 555 | ||
590 | case ACPI_NOTIFY_EJECT_REQUEST: | 556 | case ACPI_NOTIFY_EJECT_REQUEST: |
591 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
592 | "Received EJECT REQUEST notification for device [%s]\n", | ||
593 | device->pnp.bus_id)); | ||
594 | /* TBD */ | 557 | /* TBD */ |
595 | break; | 558 | break; |
596 | 559 | ||
597 | case ACPI_NOTIFY_DEVICE_CHECK_LIGHT: | 560 | case ACPI_NOTIFY_DEVICE_CHECK_LIGHT: |
598 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
599 | "Received DEVICE CHECK LIGHT notification for device [%s]\n", | ||
600 | device->pnp.bus_id)); | ||
601 | /* TBD: Exactly what does 'light' mean? */ | 561 | /* TBD: Exactly what does 'light' mean? */ |
602 | break; | 562 | break; |
603 | 563 | ||
604 | case ACPI_NOTIFY_FREQUENCY_MISMATCH: | 564 | case ACPI_NOTIFY_FREQUENCY_MISMATCH: |
605 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
606 | "Received FREQUENCY MISMATCH notification for device [%s]\n", | ||
607 | device->pnp.bus_id)); | ||
608 | /* TBD */ | 565 | /* TBD */ |
609 | break; | 566 | break; |
610 | 567 | ||
611 | case ACPI_NOTIFY_BUS_MODE_MISMATCH: | 568 | case ACPI_NOTIFY_BUS_MODE_MISMATCH: |
612 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
613 | "Received BUS MODE MISMATCH notification for device [%s]\n", | ||
614 | device->pnp.bus_id)); | ||
615 | /* TBD */ | 569 | /* TBD */ |
616 | break; | 570 | break; |
617 | 571 | ||
618 | case ACPI_NOTIFY_POWER_FAULT: | 572 | case ACPI_NOTIFY_POWER_FAULT: |
619 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
620 | "Received POWER FAULT notification for device [%s]\n", | ||
621 | device->pnp.bus_id)); | ||
622 | /* TBD */ | 573 | /* TBD */ |
623 | break; | 574 | break; |
624 | 575 | ||
@@ -629,7 +580,13 @@ static void acpi_bus_notify(acpi_handle handle, u32 type, void *data) | |||
629 | break; | 580 | break; |
630 | } | 581 | } |
631 | 582 | ||
632 | return; | 583 | acpi_bus_get_device(handle, &device); |
584 | if (device) { | ||
585 | driver = device->driver; | ||
586 | if (driver && driver->ops.notify && | ||
587 | (driver->flags & ACPI_DRIVER_ALL_NOTIFY_EVENTS)) | ||
588 | driver->ops.notify(device, type); | ||
589 | } | ||
633 | } | 590 | } |
634 | 591 | ||
635 | /* -------------------------------------------------------------------------- | 592 | /* -------------------------------------------------------------------------- |
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c index 9195deba9d94..d295bdccc09c 100644 --- a/drivers/acpi/button.c +++ b/drivers/acpi/button.c | |||
@@ -33,6 +33,8 @@ | |||
33 | #include <acpi/acpi_bus.h> | 33 | #include <acpi/acpi_bus.h> |
34 | #include <acpi/acpi_drivers.h> | 34 | #include <acpi/acpi_drivers.h> |
35 | 35 | ||
36 | #define PREFIX "ACPI: " | ||
37 | |||
36 | #define ACPI_BUTTON_CLASS "button" | 38 | #define ACPI_BUTTON_CLASS "button" |
37 | #define ACPI_BUTTON_FILE_INFO "info" | 39 | #define ACPI_BUTTON_FILE_INFO "info" |
38 | #define ACPI_BUTTON_FILE_STATE "state" | 40 | #define ACPI_BUTTON_FILE_STATE "state" |
diff --git a/drivers/acpi/cm_sbs.c b/drivers/acpi/cm_sbs.c index 332fe4b21708..6c9ee68e46fb 100644 --- a/drivers/acpi/cm_sbs.c +++ b/drivers/acpi/cm_sbs.c | |||
@@ -28,6 +28,8 @@ | |||
28 | #include <acpi/acpi_bus.h> | 28 | #include <acpi/acpi_bus.h> |
29 | #include <acpi/acpi_drivers.h> | 29 | #include <acpi/acpi_drivers.h> |
30 | 30 | ||
31 | #define PREFIX "ACPI: " | ||
32 | |||
31 | ACPI_MODULE_NAME("cm_sbs"); | 33 | ACPI_MODULE_NAME("cm_sbs"); |
32 | #define ACPI_AC_CLASS "ac_adapter" | 34 | #define ACPI_AC_CLASS "ac_adapter" |
33 | #define ACPI_BATTERY_CLASS "battery" | 35 | #define ACPI_BATTERY_CLASS "battery" |
diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c index fe0cdf83641a..642bb305cb65 100644 --- a/drivers/acpi/container.c +++ b/drivers/acpi/container.c | |||
@@ -35,6 +35,8 @@ | |||
35 | #include <acpi/acpi_drivers.h> | 35 | #include <acpi/acpi_drivers.h> |
36 | #include <acpi/container.h> | 36 | #include <acpi/container.h> |
37 | 37 | ||
38 | #define PREFIX "ACPI: " | ||
39 | |||
38 | #define ACPI_CONTAINER_DEVICE_NAME "ACPI container device" | 40 | #define ACPI_CONTAINER_DEVICE_NAME "ACPI container device" |
39 | #define ACPI_CONTAINER_CLASS "container" | 41 | #define ACPI_CONTAINER_CLASS "container" |
40 | 42 | ||
@@ -200,20 +202,17 @@ container_walk_namespace_cb(acpi_handle handle, | |||
200 | u32 lvl, void *context, void **rv) | 202 | u32 lvl, void *context, void **rv) |
201 | { | 203 | { |
202 | char *hid = NULL; | 204 | char *hid = NULL; |
203 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
204 | struct acpi_device_info *info; | 205 | struct acpi_device_info *info; |
205 | acpi_status status; | 206 | acpi_status status; |
206 | int *action = context; | 207 | int *action = context; |
207 | 208 | ||
208 | 209 | status = acpi_get_object_info(handle, &info); | |
209 | status = acpi_get_object_info(handle, &buffer); | 210 | if (ACPI_FAILURE(status)) { |
210 | if (ACPI_FAILURE(status) || !buffer.pointer) { | ||
211 | return AE_OK; | 211 | return AE_OK; |
212 | } | 212 | } |
213 | 213 | ||
214 | info = buffer.pointer; | ||
215 | if (info->valid & ACPI_VALID_HID) | 214 | if (info->valid & ACPI_VALID_HID) |
216 | hid = info->hardware_id.value; | 215 | hid = info->hardware_id.string; |
217 | 216 | ||
218 | if (hid == NULL) { | 217 | if (hid == NULL) { |
219 | goto end; | 218 | goto end; |
@@ -240,7 +239,7 @@ container_walk_namespace_cb(acpi_handle handle, | |||
240 | } | 239 | } |
241 | 240 | ||
242 | end: | 241 | end: |
243 | kfree(buffer.pointer); | 242 | kfree(info); |
244 | 243 | ||
245 | return AE_OK; | 244 | return AE_OK; |
246 | } | 245 | } |
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index efb959d6c8a9..3a2cfefc71ab 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c | |||
@@ -33,6 +33,8 @@ | |||
33 | #include <acpi/acpi_bus.h> | 33 | #include <acpi/acpi_bus.h> |
34 | #include <acpi/acpi_drivers.h> | 34 | #include <acpi/acpi_drivers.h> |
35 | 35 | ||
36 | #define PREFIX "ACPI: " | ||
37 | |||
36 | #define ACPI_DOCK_DRIVER_DESCRIPTION "ACPI Dock Station Driver" | 38 | #define ACPI_DOCK_DRIVER_DESCRIPTION "ACPI Dock Station Driver" |
37 | 39 | ||
38 | ACPI_MODULE_NAME("dock"); | 40 | ACPI_MODULE_NAME("dock"); |
@@ -231,18 +233,16 @@ static int is_ata(acpi_handle handle) | |||
231 | static int is_battery(acpi_handle handle) | 233 | static int is_battery(acpi_handle handle) |
232 | { | 234 | { |
233 | struct acpi_device_info *info; | 235 | struct acpi_device_info *info; |
234 | struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; | ||
235 | int ret = 1; | 236 | int ret = 1; |
236 | 237 | ||
237 | if (!ACPI_SUCCESS(acpi_get_object_info(handle, &buffer))) | 238 | if (!ACPI_SUCCESS(acpi_get_object_info(handle, &info))) |
238 | return 0; | 239 | return 0; |
239 | info = buffer.pointer; | ||
240 | if (!(info->valid & ACPI_VALID_HID)) | 240 | if (!(info->valid & ACPI_VALID_HID)) |
241 | ret = 0; | 241 | ret = 0; |
242 | else | 242 | else |
243 | ret = !strcmp("PNP0C0A", info->hardware_id.value); | 243 | ret = !strcmp("PNP0C0A", info->hardware_id.string); |
244 | 244 | ||
245 | kfree(buffer.pointer); | 245 | kfree(info); |
246 | return ret; | 246 | return ret; |
247 | } | 247 | } |
248 | 248 | ||
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 391f331674c7..08b8cf79946b 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
@@ -47,7 +47,6 @@ | |||
47 | #define ACPI_EC_DEVICE_NAME "Embedded Controller" | 47 | #define ACPI_EC_DEVICE_NAME "Embedded Controller" |
48 | #define ACPI_EC_FILE_INFO "info" | 48 | #define ACPI_EC_FILE_INFO "info" |
49 | 49 | ||
50 | #undef PREFIX | ||
51 | #define PREFIX "ACPI: EC: " | 50 | #define PREFIX "ACPI: EC: " |
52 | 51 | ||
53 | /* EC status register */ | 52 | /* EC status register */ |
@@ -68,15 +67,13 @@ enum ec_command { | |||
68 | #define ACPI_EC_DELAY 500 /* Wait 500ms max. during EC ops */ | 67 | #define ACPI_EC_DELAY 500 /* Wait 500ms max. during EC ops */ |
69 | #define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */ | 68 | #define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */ |
70 | #define ACPI_EC_CDELAY 10 /* Wait 10us before polling EC */ | 69 | #define ACPI_EC_CDELAY 10 /* Wait 10us before polling EC */ |
70 | #define ACPI_EC_MSI_UDELAY 550 /* Wait 550us for MSI EC */ | ||
71 | 71 | ||
72 | #define ACPI_EC_STORM_THRESHOLD 8 /* number of false interrupts | 72 | #define ACPI_EC_STORM_THRESHOLD 8 /* number of false interrupts |
73 | per one transaction */ | 73 | per one transaction */ |
74 | 74 | ||
75 | enum { | 75 | enum { |
76 | EC_FLAGS_QUERY_PENDING, /* Query is pending */ | 76 | EC_FLAGS_QUERY_PENDING, /* Query is pending */ |
77 | EC_FLAGS_GPE_MODE, /* Expect GPE to be sent | ||
78 | * for status change */ | ||
79 | EC_FLAGS_NO_GPE, /* Don't use GPE mode */ | ||
80 | EC_FLAGS_GPE_STORM, /* GPE storm detected */ | 77 | EC_FLAGS_GPE_STORM, /* GPE storm detected */ |
81 | EC_FLAGS_HANDLERS_INSTALLED /* Handlers for GPE and | 78 | EC_FLAGS_HANDLERS_INSTALLED /* Handlers for GPE and |
82 | * OpReg are installed */ | 79 | * OpReg are installed */ |
@@ -170,7 +167,7 @@ static void start_transaction(struct acpi_ec *ec) | |||
170 | acpi_ec_write_cmd(ec, ec->curr->command); | 167 | acpi_ec_write_cmd(ec, ec->curr->command); |
171 | } | 168 | } |
172 | 169 | ||
173 | static void gpe_transaction(struct acpi_ec *ec, u8 status) | 170 | static void advance_transaction(struct acpi_ec *ec, u8 status) |
174 | { | 171 | { |
175 | unsigned long flags; | 172 | unsigned long flags; |
176 | spin_lock_irqsave(&ec->curr_lock, flags); | 173 | spin_lock_irqsave(&ec->curr_lock, flags); |
@@ -201,29 +198,6 @@ unlock: | |||
201 | spin_unlock_irqrestore(&ec->curr_lock, flags); | 198 | spin_unlock_irqrestore(&ec->curr_lock, flags); |
202 | } | 199 | } |
203 | 200 | ||
204 | static int acpi_ec_wait(struct acpi_ec *ec) | ||
205 | { | ||
206 | if (wait_event_timeout(ec->wait, ec_transaction_done(ec), | ||
207 | msecs_to_jiffies(ACPI_EC_DELAY))) | ||
208 | return 0; | ||
209 | /* try restart command if we get any false interrupts */ | ||
210 | if (ec->curr->irq_count && | ||
211 | (acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF) == 0) { | ||
212 | pr_debug(PREFIX "controller reset, restart transaction\n"); | ||
213 | start_transaction(ec); | ||
214 | if (wait_event_timeout(ec->wait, ec_transaction_done(ec), | ||
215 | msecs_to_jiffies(ACPI_EC_DELAY))) | ||
216 | return 0; | ||
217 | } | ||
218 | /* missing GPEs, switch back to poll mode */ | ||
219 | if (printk_ratelimit()) | ||
220 | pr_info(PREFIX "missing confirmations, " | ||
221 | "switch off interrupt mode.\n"); | ||
222 | set_bit(EC_FLAGS_NO_GPE, &ec->flags); | ||
223 | clear_bit(EC_FLAGS_GPE_MODE, &ec->flags); | ||
224 | return 1; | ||
225 | } | ||
226 | |||
227 | static void acpi_ec_gpe_query(void *ec_cxt); | 201 | static void acpi_ec_gpe_query(void *ec_cxt); |
228 | 202 | ||
229 | static int ec_check_sci(struct acpi_ec *ec, u8 state) | 203 | static int ec_check_sci(struct acpi_ec *ec, u8 state) |
@@ -236,43 +210,51 @@ static int ec_check_sci(struct acpi_ec *ec, u8 state) | |||
236 | return 0; | 210 | return 0; |
237 | } | 211 | } |
238 | 212 | ||
239 | static void ec_delay(void) | ||
240 | { | ||
241 | /* EC in MSI notebooks don't tolerate delays other than 550 usec */ | ||
242 | if (EC_FLAGS_MSI) | ||
243 | udelay(ACPI_EC_DELAY); | ||
244 | else | ||
245 | /* Use shortest sleep available */ | ||
246 | msleep(1); | ||
247 | } | ||
248 | |||
249 | static int ec_poll(struct acpi_ec *ec) | 213 | static int ec_poll(struct acpi_ec *ec) |
250 | { | 214 | { |
251 | unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY); | 215 | unsigned long flags; |
252 | udelay(ACPI_EC_CDELAY); | 216 | int repeat = 2; /* number of command restarts */ |
253 | while (time_before(jiffies, delay)) { | 217 | while (repeat--) { |
254 | gpe_transaction(ec, acpi_ec_read_status(ec)); | 218 | unsigned long delay = jiffies + |
255 | ec_delay(); | 219 | msecs_to_jiffies(ACPI_EC_DELAY); |
256 | if (ec_transaction_done(ec)) | 220 | do { |
257 | return 0; | 221 | /* don't sleep with disabled interrupts */ |
222 | if (EC_FLAGS_MSI || irqs_disabled()) { | ||
223 | udelay(ACPI_EC_MSI_UDELAY); | ||
224 | if (ec_transaction_done(ec)) | ||
225 | return 0; | ||
226 | } else { | ||
227 | if (wait_event_timeout(ec->wait, | ||
228 | ec_transaction_done(ec), | ||
229 | msecs_to_jiffies(1))) | ||
230 | return 0; | ||
231 | } | ||
232 | advance_transaction(ec, acpi_ec_read_status(ec)); | ||
233 | } while (time_before(jiffies, delay)); | ||
234 | if (!ec->curr->irq_count || | ||
235 | (acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF)) | ||
236 | break; | ||
237 | /* try restart command if we get any false interrupts */ | ||
238 | pr_debug(PREFIX "controller reset, restart transaction\n"); | ||
239 | spin_lock_irqsave(&ec->curr_lock, flags); | ||
240 | start_transaction(ec); | ||
241 | spin_unlock_irqrestore(&ec->curr_lock, flags); | ||
258 | } | 242 | } |
259 | return -ETIME; | 243 | return -ETIME; |
260 | } | 244 | } |
261 | 245 | ||
262 | static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, | 246 | static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, |
263 | struct transaction *t, | 247 | struct transaction *t) |
264 | int force_poll) | ||
265 | { | 248 | { |
266 | unsigned long tmp; | 249 | unsigned long tmp; |
267 | int ret = 0; | 250 | int ret = 0; |
268 | pr_debug(PREFIX "transaction start\n"); | 251 | pr_debug(PREFIX "transaction start\n"); |
269 | /* disable GPE during transaction if storm is detected */ | 252 | /* disable GPE during transaction if storm is detected */ |
270 | if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) { | 253 | if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) { |
271 | clear_bit(EC_FLAGS_GPE_MODE, &ec->flags); | ||
272 | acpi_disable_gpe(NULL, ec->gpe); | 254 | acpi_disable_gpe(NULL, ec->gpe); |
273 | } | 255 | } |
274 | if (EC_FLAGS_MSI) | 256 | if (EC_FLAGS_MSI) |
275 | udelay(ACPI_EC_DELAY); | 257 | udelay(ACPI_EC_MSI_UDELAY); |
276 | /* start transaction */ | 258 | /* start transaction */ |
277 | spin_lock_irqsave(&ec->curr_lock, tmp); | 259 | spin_lock_irqsave(&ec->curr_lock, tmp); |
278 | /* following two actions should be kept atomic */ | 260 | /* following two actions should be kept atomic */ |
@@ -281,11 +263,7 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, | |||
281 | if (ec->curr->command == ACPI_EC_COMMAND_QUERY) | 263 | if (ec->curr->command == ACPI_EC_COMMAND_QUERY) |
282 | clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); | 264 | clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); |
283 | spin_unlock_irqrestore(&ec->curr_lock, tmp); | 265 | spin_unlock_irqrestore(&ec->curr_lock, tmp); |
284 | /* if we selected poll mode or failed in GPE-mode do a poll loop */ | 266 | ret = ec_poll(ec); |
285 | if (force_poll || | ||
286 | !test_bit(EC_FLAGS_GPE_MODE, &ec->flags) || | ||
287 | acpi_ec_wait(ec)) | ||
288 | ret = ec_poll(ec); | ||
289 | pr_debug(PREFIX "transaction end\n"); | 267 | pr_debug(PREFIX "transaction end\n"); |
290 | spin_lock_irqsave(&ec->curr_lock, tmp); | 268 | spin_lock_irqsave(&ec->curr_lock, tmp); |
291 | ec->curr = NULL; | 269 | ec->curr = NULL; |
@@ -295,8 +273,7 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, | |||
295 | ec_check_sci(ec, acpi_ec_read_status(ec)); | 273 | ec_check_sci(ec, acpi_ec_read_status(ec)); |
296 | /* it is safe to enable GPE outside of transaction */ | 274 | /* it is safe to enable GPE outside of transaction */ |
297 | acpi_enable_gpe(NULL, ec->gpe); | 275 | acpi_enable_gpe(NULL, ec->gpe); |
298 | } else if (test_bit(EC_FLAGS_GPE_MODE, &ec->flags) && | 276 | } else if (t->irq_count > ACPI_EC_STORM_THRESHOLD) { |
299 | t->irq_count > ACPI_EC_STORM_THRESHOLD) { | ||
300 | pr_info(PREFIX "GPE storm detected, " | 277 | pr_info(PREFIX "GPE storm detected, " |
301 | "transactions will use polling mode\n"); | 278 | "transactions will use polling mode\n"); |
302 | set_bit(EC_FLAGS_GPE_STORM, &ec->flags); | 279 | set_bit(EC_FLAGS_GPE_STORM, &ec->flags); |
@@ -314,16 +291,14 @@ static int ec_wait_ibf0(struct acpi_ec *ec) | |||
314 | { | 291 | { |
315 | unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY); | 292 | unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY); |
316 | /* interrupt wait manually if GPE mode is not active */ | 293 | /* interrupt wait manually if GPE mode is not active */ |
317 | unsigned long timeout = test_bit(EC_FLAGS_GPE_MODE, &ec->flags) ? | ||
318 | msecs_to_jiffies(ACPI_EC_DELAY) : msecs_to_jiffies(1); | ||
319 | while (time_before(jiffies, delay)) | 294 | while (time_before(jiffies, delay)) |
320 | if (wait_event_timeout(ec->wait, ec_check_ibf0(ec), timeout)) | 295 | if (wait_event_timeout(ec->wait, ec_check_ibf0(ec), |
296 | msecs_to_jiffies(1))) | ||
321 | return 0; | 297 | return 0; |
322 | return -ETIME; | 298 | return -ETIME; |
323 | } | 299 | } |
324 | 300 | ||
325 | static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t, | 301 | static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t) |
326 | int force_poll) | ||
327 | { | 302 | { |
328 | int status; | 303 | int status; |
329 | u32 glk; | 304 | u32 glk; |
@@ -345,7 +320,7 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t, | |||
345 | status = -ETIME; | 320 | status = -ETIME; |
346 | goto end; | 321 | goto end; |
347 | } | 322 | } |
348 | status = acpi_ec_transaction_unlocked(ec, t, force_poll); | 323 | status = acpi_ec_transaction_unlocked(ec, t); |
349 | end: | 324 | end: |
350 | if (ec->global_lock) | 325 | if (ec->global_lock) |
351 | acpi_release_global_lock(glk); | 326 | acpi_release_global_lock(glk); |
@@ -354,10 +329,6 @@ unlock: | |||
354 | return status; | 329 | return status; |
355 | } | 330 | } |
356 | 331 | ||
357 | /* | ||
358 | * Note: samsung nv5000 doesn't work with ec burst mode. | ||
359 | * http://bugzilla.kernel.org/show_bug.cgi?id=4980 | ||
360 | */ | ||
361 | static int acpi_ec_burst_enable(struct acpi_ec *ec) | 332 | static int acpi_ec_burst_enable(struct acpi_ec *ec) |
362 | { | 333 | { |
363 | u8 d; | 334 | u8 d; |
@@ -365,7 +336,7 @@ static int acpi_ec_burst_enable(struct acpi_ec *ec) | |||
365 | .wdata = NULL, .rdata = &d, | 336 | .wdata = NULL, .rdata = &d, |
366 | .wlen = 0, .rlen = 1}; | 337 | .wlen = 0, .rlen = 1}; |
367 | 338 | ||
368 | return acpi_ec_transaction(ec, &t, 0); | 339 | return acpi_ec_transaction(ec, &t); |
369 | } | 340 | } |
370 | 341 | ||
371 | static int acpi_ec_burst_disable(struct acpi_ec *ec) | 342 | static int acpi_ec_burst_disable(struct acpi_ec *ec) |
@@ -375,7 +346,7 @@ static int acpi_ec_burst_disable(struct acpi_ec *ec) | |||
375 | .wlen = 0, .rlen = 0}; | 346 | .wlen = 0, .rlen = 0}; |
376 | 347 | ||
377 | return (acpi_ec_read_status(ec) & ACPI_EC_FLAG_BURST) ? | 348 | return (acpi_ec_read_status(ec) & ACPI_EC_FLAG_BURST) ? |
378 | acpi_ec_transaction(ec, &t, 0) : 0; | 349 | acpi_ec_transaction(ec, &t) : 0; |
379 | } | 350 | } |
380 | 351 | ||
381 | static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 * data) | 352 | static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 * data) |
@@ -386,7 +357,7 @@ static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 * data) | |||
386 | .wdata = &address, .rdata = &d, | 357 | .wdata = &address, .rdata = &d, |
387 | .wlen = 1, .rlen = 1}; | 358 | .wlen = 1, .rlen = 1}; |
388 | 359 | ||
389 | result = acpi_ec_transaction(ec, &t, 0); | 360 | result = acpi_ec_transaction(ec, &t); |
390 | *data = d; | 361 | *data = d; |
391 | return result; | 362 | return result; |
392 | } | 363 | } |
@@ -398,7 +369,7 @@ static int acpi_ec_write(struct acpi_ec *ec, u8 address, u8 data) | |||
398 | .wdata = wdata, .rdata = NULL, | 369 | .wdata = wdata, .rdata = NULL, |
399 | .wlen = 2, .rlen = 0}; | 370 | .wlen = 2, .rlen = 0}; |
400 | 371 | ||
401 | return acpi_ec_transaction(ec, &t, 0); | 372 | return acpi_ec_transaction(ec, &t); |
402 | } | 373 | } |
403 | 374 | ||
404 | /* | 375 | /* |
@@ -466,7 +437,7 @@ int ec_transaction(u8 command, | |||
466 | if (!first_ec) | 437 | if (!first_ec) |
467 | return -ENODEV; | 438 | return -ENODEV; |
468 | 439 | ||
469 | return acpi_ec_transaction(first_ec, &t, force_poll); | 440 | return acpi_ec_transaction(first_ec, &t); |
470 | } | 441 | } |
471 | 442 | ||
472 | EXPORT_SYMBOL(ec_transaction); | 443 | EXPORT_SYMBOL(ec_transaction); |
@@ -487,7 +458,7 @@ static int acpi_ec_query(struct acpi_ec *ec, u8 * data) | |||
487 | * bit to be cleared (and thus clearing the interrupt source). | 458 | * bit to be cleared (and thus clearing the interrupt source). |
488 | */ | 459 | */ |
489 | 460 | ||
490 | result = acpi_ec_transaction(ec, &t, 0); | 461 | result = acpi_ec_transaction(ec, &t); |
491 | if (result) | 462 | if (result) |
492 | return result; | 463 | return result; |
493 | 464 | ||
@@ -570,28 +541,10 @@ static u32 acpi_ec_gpe_handler(void *data) | |||
570 | pr_debug(PREFIX "~~~> interrupt\n"); | 541 | pr_debug(PREFIX "~~~> interrupt\n"); |
571 | status = acpi_ec_read_status(ec); | 542 | status = acpi_ec_read_status(ec); |
572 | 543 | ||
573 | if (test_bit(EC_FLAGS_GPE_MODE, &ec->flags)) { | 544 | advance_transaction(ec, status); |
574 | gpe_transaction(ec, status); | 545 | if (ec_transaction_done(ec) && (status & ACPI_EC_FLAG_IBF) == 0) |
575 | if (ec_transaction_done(ec) && | 546 | wake_up(&ec->wait); |
576 | (status & ACPI_EC_FLAG_IBF) == 0) | ||
577 | wake_up(&ec->wait); | ||
578 | } | ||
579 | |||
580 | ec_check_sci(ec, status); | 547 | ec_check_sci(ec, status); |
581 | if (!test_bit(EC_FLAGS_GPE_MODE, &ec->flags) && | ||
582 | !test_bit(EC_FLAGS_NO_GPE, &ec->flags)) { | ||
583 | /* this is non-query, must be confirmation */ | ||
584 | if (!test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) { | ||
585 | if (printk_ratelimit()) | ||
586 | pr_info(PREFIX "non-query interrupt received," | ||
587 | " switching to interrupt mode\n"); | ||
588 | } else { | ||
589 | /* hush, STORM switches the mode every transaction */ | ||
590 | pr_debug(PREFIX "non-query interrupt received," | ||
591 | " switching to interrupt mode\n"); | ||
592 | } | ||
593 | set_bit(EC_FLAGS_GPE_MODE, &ec->flags); | ||
594 | } | ||
595 | return ACPI_INTERRUPT_HANDLED; | 548 | return ACPI_INTERRUPT_HANDLED; |
596 | } | 549 | } |
597 | 550 | ||
@@ -617,7 +570,8 @@ acpi_ec_space_handler(u32 function, acpi_physical_address address, | |||
617 | if (bits != 8 && acpi_strict) | 570 | if (bits != 8 && acpi_strict) |
618 | return AE_BAD_PARAMETER; | 571 | return AE_BAD_PARAMETER; |
619 | 572 | ||
620 | acpi_ec_burst_enable(ec); | 573 | if (EC_FLAGS_MSI) |
574 | acpi_ec_burst_enable(ec); | ||
621 | 575 | ||
622 | if (function == ACPI_READ) { | 576 | if (function == ACPI_READ) { |
623 | result = acpi_ec_read(ec, address, &temp); | 577 | result = acpi_ec_read(ec, address, &temp); |
@@ -638,7 +592,8 @@ acpi_ec_space_handler(u32 function, acpi_physical_address address, | |||
638 | } | 592 | } |
639 | } | 593 | } |
640 | 594 | ||
641 | acpi_ec_burst_disable(ec); | 595 | if (EC_FLAGS_MSI) |
596 | acpi_ec_burst_disable(ec); | ||
642 | 597 | ||
643 | switch (result) { | 598 | switch (result) { |
644 | case -EINVAL: | 599 | case -EINVAL: |
@@ -788,6 +743,42 @@ ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval) | |||
788 | return AE_CTRL_TERMINATE; | 743 | return AE_CTRL_TERMINATE; |
789 | } | 744 | } |
790 | 745 | ||
746 | static int ec_install_handlers(struct acpi_ec *ec) | ||
747 | { | ||
748 | acpi_status status; | ||
749 | if (test_bit(EC_FLAGS_HANDLERS_INSTALLED, &ec->flags)) | ||
750 | return 0; | ||
751 | status = acpi_install_gpe_handler(NULL, ec->gpe, | ||
752 | ACPI_GPE_EDGE_TRIGGERED, | ||
753 | &acpi_ec_gpe_handler, ec); | ||
754 | if (ACPI_FAILURE(status)) | ||
755 | return -ENODEV; | ||
756 | acpi_set_gpe_type(NULL, ec->gpe, ACPI_GPE_TYPE_RUNTIME); | ||
757 | acpi_enable_gpe(NULL, ec->gpe); | ||
758 | status = acpi_install_address_space_handler(ec->handle, | ||
759 | ACPI_ADR_SPACE_EC, | ||
760 | &acpi_ec_space_handler, | ||
761 | NULL, ec); | ||
762 | if (ACPI_FAILURE(status)) { | ||
763 | if (status == AE_NOT_FOUND) { | ||
764 | /* | ||
765 | * Maybe OS fails in evaluating the _REG object. | ||
766 | * The AE_NOT_FOUND error will be ignored and OS | ||
767 | * continue to initialize EC. | ||
768 | */ | ||
769 | printk(KERN_ERR "Fail in evaluating the _REG object" | ||
770 | " of EC device. Broken bios is suspected.\n"); | ||
771 | } else { | ||
772 | acpi_remove_gpe_handler(NULL, ec->gpe, | ||
773 | &acpi_ec_gpe_handler); | ||
774 | return -ENODEV; | ||
775 | } | ||
776 | } | ||
777 | |||
778 | set_bit(EC_FLAGS_HANDLERS_INSTALLED, &ec->flags); | ||
779 | return 0; | ||
780 | } | ||
781 | |||
791 | static void ec_remove_handlers(struct acpi_ec *ec) | 782 | static void ec_remove_handlers(struct acpi_ec *ec) |
792 | { | 783 | { |
793 | if (ACPI_FAILURE(acpi_remove_address_space_handler(ec->handle, | 784 | if (ACPI_FAILURE(acpi_remove_address_space_handler(ec->handle, |
@@ -802,9 +793,8 @@ static void ec_remove_handlers(struct acpi_ec *ec) | |||
802 | static int acpi_ec_add(struct acpi_device *device) | 793 | static int acpi_ec_add(struct acpi_device *device) |
803 | { | 794 | { |
804 | struct acpi_ec *ec = NULL; | 795 | struct acpi_ec *ec = NULL; |
796 | int ret; | ||
805 | 797 | ||
806 | if (!device) | ||
807 | return -EINVAL; | ||
808 | strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME); | 798 | strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME); |
809 | strcpy(acpi_device_class(device), ACPI_EC_CLASS); | 799 | strcpy(acpi_device_class(device), ACPI_EC_CLASS); |
810 | 800 | ||
@@ -837,9 +827,12 @@ static int acpi_ec_add(struct acpi_device *device) | |||
837 | acpi_ec_add_fs(device); | 827 | acpi_ec_add_fs(device); |
838 | pr_info(PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n", | 828 | pr_info(PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n", |
839 | ec->gpe, ec->command_addr, ec->data_addr); | 829 | ec->gpe, ec->command_addr, ec->data_addr); |
840 | pr_info(PREFIX "driver started in %s mode\n", | 830 | |
841 | (test_bit(EC_FLAGS_GPE_MODE, &ec->flags))?"interrupt":"poll"); | 831 | ret = ec_install_handlers(ec); |
842 | return 0; | 832 | |
833 | /* EC is fully operational, allow queries */ | ||
834 | clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); | ||
835 | return ret; | ||
843 | } | 836 | } |
844 | 837 | ||
845 | static int acpi_ec_remove(struct acpi_device *device, int type) | 838 | static int acpi_ec_remove(struct acpi_device *device, int type) |
@@ -851,6 +844,7 @@ static int acpi_ec_remove(struct acpi_device *device, int type) | |||
851 | return -EINVAL; | 844 | return -EINVAL; |
852 | 845 | ||
853 | ec = acpi_driver_data(device); | 846 | ec = acpi_driver_data(device); |
847 | ec_remove_handlers(ec); | ||
854 | mutex_lock(&ec->lock); | 848 | mutex_lock(&ec->lock); |
855 | list_for_each_entry_safe(handler, tmp, &ec->list, node) { | 849 | list_for_each_entry_safe(handler, tmp, &ec->list, node) { |
856 | list_del(&handler->node); | 850 | list_del(&handler->node); |
@@ -888,75 +882,6 @@ ec_parse_io_ports(struct acpi_resource *resource, void *context) | |||
888 | return AE_OK; | 882 | return AE_OK; |
889 | } | 883 | } |
890 | 884 | ||
891 | static int ec_install_handlers(struct acpi_ec *ec) | ||
892 | { | ||
893 | acpi_status status; | ||
894 | if (test_bit(EC_FLAGS_HANDLERS_INSTALLED, &ec->flags)) | ||
895 | return 0; | ||
896 | status = acpi_install_gpe_handler(NULL, ec->gpe, | ||
897 | ACPI_GPE_EDGE_TRIGGERED, | ||
898 | &acpi_ec_gpe_handler, ec); | ||
899 | if (ACPI_FAILURE(status)) | ||
900 | return -ENODEV; | ||
901 | acpi_set_gpe_type(NULL, ec->gpe, ACPI_GPE_TYPE_RUNTIME); | ||
902 | acpi_enable_gpe(NULL, ec->gpe); | ||
903 | status = acpi_install_address_space_handler(ec->handle, | ||
904 | ACPI_ADR_SPACE_EC, | ||
905 | &acpi_ec_space_handler, | ||
906 | NULL, ec); | ||
907 | if (ACPI_FAILURE(status)) { | ||
908 | if (status == AE_NOT_FOUND) { | ||
909 | /* | ||
910 | * Maybe OS fails in evaluating the _REG object. | ||
911 | * The AE_NOT_FOUND error will be ignored and OS | ||
912 | * continue to initialize EC. | ||
913 | */ | ||
914 | printk(KERN_ERR "Fail in evaluating the _REG object" | ||
915 | " of EC device. Broken bios is suspected.\n"); | ||
916 | } else { | ||
917 | acpi_remove_gpe_handler(NULL, ec->gpe, | ||
918 | &acpi_ec_gpe_handler); | ||
919 | return -ENODEV; | ||
920 | } | ||
921 | } | ||
922 | |||
923 | set_bit(EC_FLAGS_HANDLERS_INSTALLED, &ec->flags); | ||
924 | return 0; | ||
925 | } | ||
926 | |||
927 | static int acpi_ec_start(struct acpi_device *device) | ||
928 | { | ||
929 | struct acpi_ec *ec; | ||
930 | int ret = 0; | ||
931 | |||
932 | if (!device) | ||
933 | return -EINVAL; | ||
934 | |||
935 | ec = acpi_driver_data(device); | ||
936 | |||
937 | if (!ec) | ||
938 | return -EINVAL; | ||
939 | |||
940 | ret = ec_install_handlers(ec); | ||
941 | |||
942 | /* EC is fully operational, allow queries */ | ||
943 | clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); | ||
944 | return ret; | ||
945 | } | ||
946 | |||
947 | static int acpi_ec_stop(struct acpi_device *device, int type) | ||
948 | { | ||
949 | struct acpi_ec *ec; | ||
950 | if (!device) | ||
951 | return -EINVAL; | ||
952 | ec = acpi_driver_data(device); | ||
953 | if (!ec) | ||
954 | return -EINVAL; | ||
955 | ec_remove_handlers(ec); | ||
956 | |||
957 | return 0; | ||
958 | } | ||
959 | |||
960 | int __init acpi_boot_ec_enable(void) | 885 | int __init acpi_boot_ec_enable(void) |
961 | { | 886 | { |
962 | if (!boot_ec || test_bit(EC_FLAGS_HANDLERS_INSTALLED, &boot_ec->flags)) | 887 | if (!boot_ec || test_bit(EC_FLAGS_HANDLERS_INSTALLED, &boot_ec->flags)) |
@@ -1054,8 +979,6 @@ static int acpi_ec_suspend(struct acpi_device *device, pm_message_t state) | |||
1054 | { | 979 | { |
1055 | struct acpi_ec *ec = acpi_driver_data(device); | 980 | struct acpi_ec *ec = acpi_driver_data(device); |
1056 | /* Stop using GPE */ | 981 | /* Stop using GPE */ |
1057 | set_bit(EC_FLAGS_NO_GPE, &ec->flags); | ||
1058 | clear_bit(EC_FLAGS_GPE_MODE, &ec->flags); | ||
1059 | acpi_disable_gpe(NULL, ec->gpe); | 982 | acpi_disable_gpe(NULL, ec->gpe); |
1060 | return 0; | 983 | return 0; |
1061 | } | 984 | } |
@@ -1064,8 +987,6 @@ static int acpi_ec_resume(struct acpi_device *device) | |||
1064 | { | 987 | { |
1065 | struct acpi_ec *ec = acpi_driver_data(device); | 988 | struct acpi_ec *ec = acpi_driver_data(device); |
1066 | /* Enable use of GPE back */ | 989 | /* Enable use of GPE back */ |
1067 | clear_bit(EC_FLAGS_NO_GPE, &ec->flags); | ||
1068 | set_bit(EC_FLAGS_GPE_MODE, &ec->flags); | ||
1069 | acpi_enable_gpe(NULL, ec->gpe); | 990 | acpi_enable_gpe(NULL, ec->gpe); |
1070 | return 0; | 991 | return 0; |
1071 | } | 992 | } |
@@ -1077,8 +998,6 @@ static struct acpi_driver acpi_ec_driver = { | |||
1077 | .ops = { | 998 | .ops = { |
1078 | .add = acpi_ec_add, | 999 | .add = acpi_ec_add, |
1079 | .remove = acpi_ec_remove, | 1000 | .remove = acpi_ec_remove, |
1080 | .start = acpi_ec_start, | ||
1081 | .stop = acpi_ec_stop, | ||
1082 | .suspend = acpi_ec_suspend, | 1001 | .suspend = acpi_ec_suspend, |
1083 | .resume = acpi_ec_resume, | 1002 | .resume = acpi_ec_resume, |
1084 | }, | 1003 | }, |
diff --git a/drivers/acpi/event.c b/drivers/acpi/event.c index aeb7e5fb4a04..c511071bfd79 100644 --- a/drivers/acpi/event.c +++ b/drivers/acpi/event.c | |||
@@ -14,6 +14,8 @@ | |||
14 | #include <net/netlink.h> | 14 | #include <net/netlink.h> |
15 | #include <net/genetlink.h> | 15 | #include <net/genetlink.h> |
16 | 16 | ||
17 | #include "internal.h" | ||
18 | |||
17 | #define _COMPONENT ACPI_SYSTEM_COMPONENT | 19 | #define _COMPONENT ACPI_SYSTEM_COMPONENT |
18 | ACPI_MODULE_NAME("event"); | 20 | ACPI_MODULE_NAME("event"); |
19 | 21 | ||
diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c index 53698ea08371..f419849a0d3f 100644 --- a/drivers/acpi/fan.c +++ b/drivers/acpi/fan.c | |||
@@ -34,6 +34,8 @@ | |||
34 | #include <acpi/acpi_bus.h> | 34 | #include <acpi/acpi_bus.h> |
35 | #include <acpi/acpi_drivers.h> | 35 | #include <acpi/acpi_drivers.h> |
36 | 36 | ||
37 | #define PREFIX "ACPI: " | ||
38 | |||
37 | #define ACPI_FAN_CLASS "fan" | 39 | #define ACPI_FAN_CLASS "fan" |
38 | #define ACPI_FAN_FILE_STATE "state" | 40 | #define ACPI_FAN_FILE_STATE "state" |
39 | 41 | ||
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index 8bd2c2a6884d..c6645f26224b 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c | |||
@@ -12,6 +12,8 @@ | |||
12 | #include <linux/rwsem.h> | 12 | #include <linux/rwsem.h> |
13 | #include <linux/acpi.h> | 13 | #include <linux/acpi.h> |
14 | 14 | ||
15 | #include "internal.h" | ||
16 | |||
15 | #define ACPI_GLUE_DEBUG 0 | 17 | #define ACPI_GLUE_DEBUG 0 |
16 | #if ACPI_GLUE_DEBUG | 18 | #if ACPI_GLUE_DEBUG |
17 | #define DBG(x...) printk(PREFIX x) | 19 | #define DBG(x...) printk(PREFIX x) |
@@ -93,15 +95,13 @@ do_acpi_find_child(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
93 | { | 95 | { |
94 | acpi_status status; | 96 | acpi_status status; |
95 | struct acpi_device_info *info; | 97 | struct acpi_device_info *info; |
96 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
97 | struct acpi_find_child *find = context; | 98 | struct acpi_find_child *find = context; |
98 | 99 | ||
99 | status = acpi_get_object_info(handle, &buffer); | 100 | status = acpi_get_object_info(handle, &info); |
100 | if (ACPI_SUCCESS(status)) { | 101 | if (ACPI_SUCCESS(status)) { |
101 | info = buffer.pointer; | ||
102 | if (info->address == find->address) | 102 | if (info->address == find->address) |
103 | find->handle = handle; | 103 | find->handle = handle; |
104 | kfree(buffer.pointer); | 104 | kfree(info); |
105 | } | 105 | } |
106 | return AE_OK; | 106 | return AE_OK; |
107 | } | 107 | } |
@@ -121,7 +121,7 @@ EXPORT_SYMBOL(acpi_get_child); | |||
121 | 121 | ||
122 | /* Link ACPI devices with physical devices */ | 122 | /* Link ACPI devices with physical devices */ |
123 | static void acpi_glue_data_handler(acpi_handle handle, | 123 | static void acpi_glue_data_handler(acpi_handle handle, |
124 | u32 function, void *context) | 124 | void *context) |
125 | { | 125 | { |
126 | /* we provide an empty handler */ | 126 | /* we provide an empty handler */ |
127 | } | 127 | } |
@@ -140,46 +140,6 @@ struct device *acpi_get_physical_device(acpi_handle handle) | |||
140 | 140 | ||
141 | EXPORT_SYMBOL(acpi_get_physical_device); | 141 | EXPORT_SYMBOL(acpi_get_physical_device); |
142 | 142 | ||
143 | /* ToDo: When a PCI bridge is found, return the PCI device behind the bridge | ||
144 | * This should work in general, but did not on a Lenovo T61 for the | ||
145 | * graphics card. But this must be fixed when the PCI device is | ||
146 | * bound and the kernel device struct is attached to the acpi device | ||
147 | * Note: A success call will increase reference count by one | ||
148 | * Do call put_device(dev) on the returned device then | ||
149 | */ | ||
150 | struct device *acpi_get_physical_pci_device(acpi_handle handle) | ||
151 | { | ||
152 | struct device *dev; | ||
153 | long long device_id; | ||
154 | acpi_status status; | ||
155 | |||
156 | status = | ||
157 | acpi_evaluate_integer(handle, "_ADR", NULL, &device_id); | ||
158 | |||
159 | if (ACPI_FAILURE(status)) | ||
160 | return NULL; | ||
161 | |||
162 | /* We need to attempt to determine whether the _ADR refers to a | ||
163 | PCI device or not. There's no terribly good way to do this, | ||
164 | so the best we can hope for is to assume that there'll never | ||
165 | be a device in the host bridge */ | ||
166 | if (device_id >= 0x10000) { | ||
167 | /* It looks like a PCI device. Does it exist? */ | ||
168 | dev = acpi_get_physical_device(handle); | ||
169 | } else { | ||
170 | /* It doesn't look like a PCI device. Does its parent | ||
171 | exist? */ | ||
172 | acpi_handle phandle; | ||
173 | if (acpi_get_parent(handle, &phandle)) | ||
174 | return NULL; | ||
175 | dev = acpi_get_physical_device(phandle); | ||
176 | } | ||
177 | if (!dev) | ||
178 | return NULL; | ||
179 | return dev; | ||
180 | } | ||
181 | EXPORT_SYMBOL(acpi_get_physical_pci_device); | ||
182 | |||
183 | static int acpi_bind_one(struct device *dev, acpi_handle handle) | 143 | static int acpi_bind_one(struct device *dev, acpi_handle handle) |
184 | { | 144 | { |
185 | struct acpi_device *acpi_dev; | 145 | struct acpi_device *acpi_dev; |
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index 11a69b53004e..074cf8682d52 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h | |||
@@ -1,4 +1,24 @@ | |||
1 | /* For use by Linux/ACPI infrastructure, not drivers */ | 1 | /* |
2 | * acpi/internal.h | ||
3 | * For use by Linux/ACPI infrastructure, not drivers | ||
4 | * | ||
5 | * Copyright (c) 2009, Intel Corporation. | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms and conditions of the GNU General Public License, | ||
9 | * version 2, as published by the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
14 | * more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along with | ||
17 | * this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | ||
19 | */ | ||
20 | |||
21 | #define PREFIX "ACPI: " | ||
2 | 22 | ||
3 | int init_acpi_device_notify(void); | 23 | int init_acpi_device_notify(void); |
4 | int acpi_scan_init(void); | 24 | int acpi_scan_init(void); |
diff --git a/drivers/acpi/numa.c b/drivers/acpi/numa.c index d440ccd27d91..202dd0c976a3 100644 --- a/drivers/acpi/numa.c +++ b/drivers/acpi/numa.c | |||
@@ -30,6 +30,8 @@ | |||
30 | #include <linux/acpi.h> | 30 | #include <linux/acpi.h> |
31 | #include <acpi/acpi_bus.h> | 31 | #include <acpi/acpi_bus.h> |
32 | 32 | ||
33 | #define PREFIX "ACPI: " | ||
34 | |||
33 | #define ACPI_NUMA 0x80000000 | 35 | #define ACPI_NUMA 0x80000000 |
34 | #define _COMPONENT ACPI_NUMA | 36 | #define _COMPONENT ACPI_NUMA |
35 | ACPI_MODULE_NAME("numa"); | 37 | ACPI_MODULE_NAME("numa"); |
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index d916bea729f1..c5b4f1ed9b71 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c | |||
@@ -79,6 +79,7 @@ static acpi_osd_handler acpi_irq_handler; | |||
79 | static void *acpi_irq_context; | 79 | static void *acpi_irq_context; |
80 | static struct workqueue_struct *kacpid_wq; | 80 | static struct workqueue_struct *kacpid_wq; |
81 | static struct workqueue_struct *kacpi_notify_wq; | 81 | static struct workqueue_struct *kacpi_notify_wq; |
82 | static struct workqueue_struct *kacpi_hotplug_wq; | ||
82 | 83 | ||
83 | struct acpi_res_list { | 84 | struct acpi_res_list { |
84 | resource_size_t start; | 85 | resource_size_t start; |
@@ -87,6 +88,7 @@ struct acpi_res_list { | |||
87 | char name[5]; /* only can have a length of 4 chars, make use of this | 88 | char name[5]; /* only can have a length of 4 chars, make use of this |
88 | one instead of res->name, no need to kalloc then */ | 89 | one instead of res->name, no need to kalloc then */ |
89 | struct list_head resource_list; | 90 | struct list_head resource_list; |
91 | int count; | ||
90 | }; | 92 | }; |
91 | 93 | ||
92 | static LIST_HEAD(resource_list_head); | 94 | static LIST_HEAD(resource_list_head); |
@@ -188,12 +190,39 @@ acpi_status __init acpi_os_initialize(void) | |||
188 | return AE_OK; | 190 | return AE_OK; |
189 | } | 191 | } |
190 | 192 | ||
193 | static void bind_to_cpu0(struct work_struct *work) | ||
194 | { | ||
195 | set_cpus_allowed(current, cpumask_of_cpu(0)); | ||
196 | kfree(work); | ||
197 | } | ||
198 | |||
199 | static void bind_workqueue(struct workqueue_struct *wq) | ||
200 | { | ||
201 | struct work_struct *work; | ||
202 | |||
203 | work = kzalloc(sizeof(struct work_struct), GFP_KERNEL); | ||
204 | INIT_WORK(work, bind_to_cpu0); | ||
205 | queue_work(wq, work); | ||
206 | } | ||
207 | |||
191 | acpi_status acpi_os_initialize1(void) | 208 | acpi_status acpi_os_initialize1(void) |
192 | { | 209 | { |
210 | /* | ||
211 | * On some machines, a software-initiated SMI causes corruption unless | ||
212 | * the SMI runs on CPU 0. An SMI can be initiated by any AML, but | ||
213 | * typically it's done in GPE-related methods that are run via | ||
214 | * workqueues, so we can avoid the known corruption cases by binding | ||
215 | * the workqueues to CPU 0. | ||
216 | */ | ||
193 | kacpid_wq = create_singlethread_workqueue("kacpid"); | 217 | kacpid_wq = create_singlethread_workqueue("kacpid"); |
218 | bind_workqueue(kacpid_wq); | ||
194 | kacpi_notify_wq = create_singlethread_workqueue("kacpi_notify"); | 219 | kacpi_notify_wq = create_singlethread_workqueue("kacpi_notify"); |
220 | bind_workqueue(kacpi_notify_wq); | ||
221 | kacpi_hotplug_wq = create_singlethread_workqueue("kacpi_hotplug"); | ||
222 | bind_workqueue(kacpi_hotplug_wq); | ||
195 | BUG_ON(!kacpid_wq); | 223 | BUG_ON(!kacpid_wq); |
196 | BUG_ON(!kacpi_notify_wq); | 224 | BUG_ON(!kacpi_notify_wq); |
225 | BUG_ON(!kacpi_hotplug_wq); | ||
197 | return AE_OK; | 226 | return AE_OK; |
198 | } | 227 | } |
199 | 228 | ||
@@ -206,6 +235,7 @@ acpi_status acpi_os_terminate(void) | |||
206 | 235 | ||
207 | destroy_workqueue(kacpid_wq); | 236 | destroy_workqueue(kacpid_wq); |
208 | destroy_workqueue(kacpi_notify_wq); | 237 | destroy_workqueue(kacpi_notify_wq); |
238 | destroy_workqueue(kacpi_hotplug_wq); | ||
209 | 239 | ||
210 | return AE_OK; | 240 | return AE_OK; |
211 | } | 241 | } |
@@ -716,6 +746,7 @@ static acpi_status __acpi_os_execute(acpi_execute_type type, | |||
716 | acpi_status status = AE_OK; | 746 | acpi_status status = AE_OK; |
717 | struct acpi_os_dpc *dpc; | 747 | struct acpi_os_dpc *dpc; |
718 | struct workqueue_struct *queue; | 748 | struct workqueue_struct *queue; |
749 | work_func_t func; | ||
719 | int ret; | 750 | int ret; |
720 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | 751 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, |
721 | "Scheduling function [%p(%p)] for deferred execution.\n", | 752 | "Scheduling function [%p(%p)] for deferred execution.\n", |
@@ -740,15 +771,17 @@ static acpi_status __acpi_os_execute(acpi_execute_type type, | |||
740 | dpc->function = function; | 771 | dpc->function = function; |
741 | dpc->context = context; | 772 | dpc->context = context; |
742 | 773 | ||
743 | if (!hp) { | 774 | /* |
744 | INIT_WORK(&dpc->work, acpi_os_execute_deferred); | 775 | * We can't run hotplug code in keventd_wq/kacpid_wq/kacpid_notify_wq |
745 | queue = (type == OSL_NOTIFY_HANDLER) ? | 776 | * because the hotplug code may call driver .remove() functions, |
746 | kacpi_notify_wq : kacpid_wq; | 777 | * which invoke flush_scheduled_work/acpi_os_wait_events_complete |
747 | ret = queue_work(queue, &dpc->work); | 778 | * to flush these workqueues. |
748 | } else { | 779 | */ |
749 | INIT_WORK(&dpc->work, acpi_os_execute_hp_deferred); | 780 | queue = hp ? kacpi_hotplug_wq : |
750 | ret = schedule_work(&dpc->work); | 781 | (type == OSL_NOTIFY_HANDLER ? kacpi_notify_wq : kacpid_wq); |
751 | } | 782 | func = hp ? acpi_os_execute_hp_deferred : acpi_os_execute_deferred; |
783 | INIT_WORK(&dpc->work, func); | ||
784 | ret = queue_work(queue, &dpc->work); | ||
752 | 785 | ||
753 | if (!ret) { | 786 | if (!ret) { |
754 | printk(KERN_ERR PREFIX | 787 | printk(KERN_ERR PREFIX |
@@ -1326,6 +1359,89 @@ acpi_os_validate_interface (char *interface) | |||
1326 | return AE_SUPPORT; | 1359 | return AE_SUPPORT; |
1327 | } | 1360 | } |
1328 | 1361 | ||
1362 | static inline int acpi_res_list_add(struct acpi_res_list *res) | ||
1363 | { | ||
1364 | struct acpi_res_list *res_list_elem; | ||
1365 | |||
1366 | list_for_each_entry(res_list_elem, &resource_list_head, | ||
1367 | resource_list) { | ||
1368 | |||
1369 | if (res->resource_type == res_list_elem->resource_type && | ||
1370 | res->start == res_list_elem->start && | ||
1371 | res->end == res_list_elem->end) { | ||
1372 | |||
1373 | /* | ||
1374 | * The Region(addr,len) already exist in the list, | ||
1375 | * just increase the count | ||
1376 | */ | ||
1377 | |||
1378 | res_list_elem->count++; | ||
1379 | return 0; | ||
1380 | } | ||
1381 | } | ||
1382 | |||
1383 | res->count = 1; | ||
1384 | list_add(&res->resource_list, &resource_list_head); | ||
1385 | return 1; | ||
1386 | } | ||
1387 | |||
1388 | static inline void acpi_res_list_del(struct acpi_res_list *res) | ||
1389 | { | ||
1390 | struct acpi_res_list *res_list_elem; | ||
1391 | |||
1392 | list_for_each_entry(res_list_elem, &resource_list_head, | ||
1393 | resource_list) { | ||
1394 | |||
1395 | if (res->resource_type == res_list_elem->resource_type && | ||
1396 | res->start == res_list_elem->start && | ||
1397 | res->end == res_list_elem->end) { | ||
1398 | |||
1399 | /* | ||
1400 | * If the res count is decreased to 0, | ||
1401 | * remove and free it | ||
1402 | */ | ||
1403 | |||
1404 | if (--res_list_elem->count == 0) { | ||
1405 | list_del(&res_list_elem->resource_list); | ||
1406 | kfree(res_list_elem); | ||
1407 | } | ||
1408 | return; | ||
1409 | } | ||
1410 | } | ||
1411 | } | ||
1412 | |||
1413 | acpi_status | ||
1414 | acpi_os_invalidate_address( | ||
1415 | u8 space_id, | ||
1416 | acpi_physical_address address, | ||
1417 | acpi_size length) | ||
1418 | { | ||
1419 | struct acpi_res_list res; | ||
1420 | |||
1421 | switch (space_id) { | ||
1422 | case ACPI_ADR_SPACE_SYSTEM_IO: | ||
1423 | case ACPI_ADR_SPACE_SYSTEM_MEMORY: | ||
1424 | /* Only interference checks against SystemIO and SytemMemory | ||
1425 | are needed */ | ||
1426 | res.start = address; | ||
1427 | res.end = address + length - 1; | ||
1428 | res.resource_type = space_id; | ||
1429 | spin_lock(&acpi_res_lock); | ||
1430 | acpi_res_list_del(&res); | ||
1431 | spin_unlock(&acpi_res_lock); | ||
1432 | break; | ||
1433 | case ACPI_ADR_SPACE_PCI_CONFIG: | ||
1434 | case ACPI_ADR_SPACE_EC: | ||
1435 | case ACPI_ADR_SPACE_SMBUS: | ||
1436 | case ACPI_ADR_SPACE_CMOS: | ||
1437 | case ACPI_ADR_SPACE_PCI_BAR_TARGET: | ||
1438 | case ACPI_ADR_SPACE_DATA_TABLE: | ||
1439 | case ACPI_ADR_SPACE_FIXED_HARDWARE: | ||
1440 | break; | ||
1441 | } | ||
1442 | return AE_OK; | ||
1443 | } | ||
1444 | |||
1329 | /****************************************************************************** | 1445 | /****************************************************************************** |
1330 | * | 1446 | * |
1331 | * FUNCTION: acpi_os_validate_address | 1447 | * FUNCTION: acpi_os_validate_address |
@@ -1350,6 +1466,7 @@ acpi_os_validate_address ( | |||
1350 | char *name) | 1466 | char *name) |
1351 | { | 1467 | { |
1352 | struct acpi_res_list *res; | 1468 | struct acpi_res_list *res; |
1469 | int added; | ||
1353 | if (acpi_enforce_resources == ENFORCE_RESOURCES_NO) | 1470 | if (acpi_enforce_resources == ENFORCE_RESOURCES_NO) |
1354 | return AE_OK; | 1471 | return AE_OK; |
1355 | 1472 | ||
@@ -1367,14 +1484,17 @@ acpi_os_validate_address ( | |||
1367 | res->end = address + length - 1; | 1484 | res->end = address + length - 1; |
1368 | res->resource_type = space_id; | 1485 | res->resource_type = space_id; |
1369 | spin_lock(&acpi_res_lock); | 1486 | spin_lock(&acpi_res_lock); |
1370 | list_add(&res->resource_list, &resource_list_head); | 1487 | added = acpi_res_list_add(res); |
1371 | spin_unlock(&acpi_res_lock); | 1488 | spin_unlock(&acpi_res_lock); |
1372 | pr_debug("Added %s resource: start: 0x%llx, end: 0x%llx, " | 1489 | pr_debug("%s %s resource: start: 0x%llx, end: 0x%llx, " |
1373 | "name: %s\n", (space_id == ACPI_ADR_SPACE_SYSTEM_IO) | 1490 | "name: %s\n", added ? "Added" : "Already exist", |
1491 | (space_id == ACPI_ADR_SPACE_SYSTEM_IO) | ||
1374 | ? "SystemIO" : "System Memory", | 1492 | ? "SystemIO" : "System Memory", |
1375 | (unsigned long long)res->start, | 1493 | (unsigned long long)res->start, |
1376 | (unsigned long long)res->end, | 1494 | (unsigned long long)res->end, |
1377 | res->name); | 1495 | res->name); |
1496 | if (!added) | ||
1497 | kfree(res); | ||
1378 | break; | 1498 | break; |
1379 | case ACPI_ADR_SPACE_PCI_CONFIG: | 1499 | case ACPI_ADR_SPACE_PCI_CONFIG: |
1380 | case ACPI_ADR_SPACE_EC: | 1500 | case ACPI_ADR_SPACE_EC: |
diff --git a/drivers/acpi/pci_bind.c b/drivers/acpi/pci_bind.c index bc46de3d967f..a5a77b78a723 100644 --- a/drivers/acpi/pci_bind.c +++ b/drivers/acpi/pci_bind.c | |||
@@ -24,12 +24,7 @@ | |||
24 | */ | 24 | */ |
25 | 25 | ||
26 | #include <linux/kernel.h> | 26 | #include <linux/kernel.h> |
27 | #include <linux/module.h> | ||
28 | #include <linux/init.h> | ||
29 | #include <linux/types.h> | 27 | #include <linux/types.h> |
30 | #include <linux/proc_fs.h> | ||
31 | #include <linux/spinlock.h> | ||
32 | #include <linux/pm.h> | ||
33 | #include <linux/pci.h> | 28 | #include <linux/pci.h> |
34 | #include <linux/acpi.h> | 29 | #include <linux/acpi.h> |
35 | #include <acpi/acpi_bus.h> | 30 | #include <acpi/acpi_bus.h> |
@@ -38,310 +33,76 @@ | |||
38 | #define _COMPONENT ACPI_PCI_COMPONENT | 33 | #define _COMPONENT ACPI_PCI_COMPONENT |
39 | ACPI_MODULE_NAME("pci_bind"); | 34 | ACPI_MODULE_NAME("pci_bind"); |
40 | 35 | ||
41 | struct acpi_pci_data { | 36 | static int acpi_pci_unbind(struct acpi_device *device) |
42 | struct acpi_pci_id id; | ||
43 | struct pci_bus *bus; | ||
44 | struct pci_dev *dev; | ||
45 | }; | ||
46 | |||
47 | static int acpi_pci_unbind(struct acpi_device *device); | ||
48 | |||
49 | static void acpi_pci_data_handler(acpi_handle handle, u32 function, | ||
50 | void *context) | ||
51 | { | ||
52 | |||
53 | /* TBD: Anything we need to do here? */ | ||
54 | |||
55 | return; | ||
56 | } | ||
57 | |||
58 | /** | ||
59 | * acpi_get_pci_id | ||
60 | * ------------------ | ||
61 | * This function is used by the ACPI Interpreter (a.k.a. Core Subsystem) | ||
62 | * to resolve PCI information for ACPI-PCI devices defined in the namespace. | ||
63 | * This typically occurs when resolving PCI operation region information. | ||
64 | */ | ||
65 | acpi_status acpi_get_pci_id(acpi_handle handle, struct acpi_pci_id *id) | ||
66 | { | 37 | { |
67 | int result = 0; | 38 | struct pci_dev *dev; |
68 | acpi_status status = AE_OK; | ||
69 | struct acpi_device *device = NULL; | ||
70 | struct acpi_pci_data *data = NULL; | ||
71 | |||
72 | |||
73 | if (!id) | ||
74 | return AE_BAD_PARAMETER; | ||
75 | |||
76 | result = acpi_bus_get_device(handle, &device); | ||
77 | if (result) { | ||
78 | printk(KERN_ERR PREFIX | ||
79 | "Invalid ACPI Bus context for device %s\n", | ||
80 | acpi_device_bid(device)); | ||
81 | return AE_NOT_EXIST; | ||
82 | } | ||
83 | |||
84 | status = acpi_get_data(handle, acpi_pci_data_handler, (void **)&data); | ||
85 | if (ACPI_FAILURE(status) || !data) { | ||
86 | ACPI_EXCEPTION((AE_INFO, status, | ||
87 | "Invalid ACPI-PCI context for device %s", | ||
88 | acpi_device_bid(device))); | ||
89 | return status; | ||
90 | } | ||
91 | 39 | ||
92 | *id = data->id; | 40 | dev = acpi_get_pci_dev(device->handle); |
41 | if (!dev || !dev->subordinate) | ||
42 | goto out; | ||
93 | 43 | ||
94 | /* | 44 | acpi_pci_irq_del_prt(dev->subordinate); |
95 | id->segment = data->id.segment; | ||
96 | id->bus = data->id.bus; | ||
97 | id->device = data->id.device; | ||
98 | id->function = data->id.function; | ||
99 | */ | ||
100 | 45 | ||
101 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 46 | device->ops.bind = NULL; |
102 | "Device %s has PCI address %04x:%02x:%02x.%d\n", | 47 | device->ops.unbind = NULL; |
103 | acpi_device_bid(device), id->segment, id->bus, | ||
104 | id->device, id->function)); | ||
105 | 48 | ||
106 | return AE_OK; | 49 | out: |
50 | pci_dev_put(dev); | ||
51 | return 0; | ||
107 | } | 52 | } |
108 | 53 | ||
109 | EXPORT_SYMBOL(acpi_get_pci_id); | 54 | static int acpi_pci_bind(struct acpi_device *device) |
110 | |||
111 | int acpi_pci_bind(struct acpi_device *device) | ||
112 | { | 55 | { |
113 | int result = 0; | ||
114 | acpi_status status; | 56 | acpi_status status; |
115 | struct acpi_pci_data *data; | ||
116 | struct acpi_pci_data *pdata; | ||
117 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
118 | acpi_handle handle; | 57 | acpi_handle handle; |
58 | struct pci_bus *bus; | ||
59 | struct pci_dev *dev; | ||
119 | 60 | ||
120 | if (!device || !device->parent) | 61 | dev = acpi_get_pci_dev(device->handle); |
121 | return -EINVAL; | 62 | if (!dev) |
122 | 63 | return 0; | |
123 | data = kzalloc(sizeof(struct acpi_pci_data), GFP_KERNEL); | ||
124 | if (!data) | ||
125 | return -ENOMEM; | ||
126 | |||
127 | status = acpi_get_name(device->handle, ACPI_FULL_PATHNAME, &buffer); | ||
128 | if (ACPI_FAILURE(status)) { | ||
129 | kfree(data); | ||
130 | return -ENODEV; | ||
131 | } | ||
132 | |||
133 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Binding PCI device [%s]...\n", | ||
134 | (char *)buffer.pointer)); | ||
135 | |||
136 | /* | ||
137 | * Segment & Bus | ||
138 | * ------------- | ||
139 | * These are obtained via the parent device's ACPI-PCI context. | ||
140 | */ | ||
141 | status = acpi_get_data(device->parent->handle, acpi_pci_data_handler, | ||
142 | (void **)&pdata); | ||
143 | if (ACPI_FAILURE(status) || !pdata || !pdata->bus) { | ||
144 | ACPI_EXCEPTION((AE_INFO, status, | ||
145 | "Invalid ACPI-PCI context for parent device %s", | ||
146 | acpi_device_bid(device->parent))); | ||
147 | result = -ENODEV; | ||
148 | goto end; | ||
149 | } | ||
150 | data->id.segment = pdata->id.segment; | ||
151 | data->id.bus = pdata->bus->number; | ||
152 | |||
153 | /* | ||
154 | * Device & Function | ||
155 | * ----------------- | ||
156 | * These are simply obtained from the device's _ADR method. Note | ||
157 | * that a value of zero is valid. | ||
158 | */ | ||
159 | data->id.device = device->pnp.bus_address >> 16; | ||
160 | data->id.function = device->pnp.bus_address & 0xFFFF; | ||
161 | |||
162 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "...to %04x:%02x:%02x.%d\n", | ||
163 | data->id.segment, data->id.bus, data->id.device, | ||
164 | data->id.function)); | ||
165 | |||
166 | /* | ||
167 | * TBD: Support slot devices (e.g. function=0xFFFF). | ||
168 | */ | ||
169 | |||
170 | /* | ||
171 | * Locate PCI Device | ||
172 | * ----------------- | ||
173 | * Locate matching device in PCI namespace. If it doesn't exist | ||
174 | * this typically means that the device isn't currently inserted | ||
175 | * (e.g. docking station, port replicator, etc.). | ||
176 | */ | ||
177 | data->dev = pci_get_slot(pdata->bus, | ||
178 | PCI_DEVFN(data->id.device, data->id.function)); | ||
179 | if (!data->dev) { | ||
180 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
181 | "Device %04x:%02x:%02x.%d not present in PCI namespace\n", | ||
182 | data->id.segment, data->id.bus, | ||
183 | data->id.device, data->id.function)); | ||
184 | result = -ENODEV; | ||
185 | goto end; | ||
186 | } | ||
187 | if (!data->dev->bus) { | ||
188 | printk(KERN_ERR PREFIX | ||
189 | "Device %04x:%02x:%02x.%d has invalid 'bus' field\n", | ||
190 | data->id.segment, data->id.bus, | ||
191 | data->id.device, data->id.function); | ||
192 | result = -ENODEV; | ||
193 | goto end; | ||
194 | } | ||
195 | 64 | ||
196 | /* | 65 | /* |
197 | * PCI Bridge? | 66 | * Install the 'bind' function to facilitate callbacks for |
198 | * ----------- | 67 | * children of the P2P bridge. |
199 | * If so, set the 'bus' field and install the 'bind' function to | ||
200 | * facilitate callbacks for all of its children. | ||
201 | */ | 68 | */ |
202 | if (data->dev->subordinate) { | 69 | if (dev->subordinate) { |
203 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 70 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
204 | "Device %04x:%02x:%02x.%d is a PCI bridge\n", | 71 | "Device %04x:%02x:%02x.%d is a PCI bridge\n", |
205 | data->id.segment, data->id.bus, | 72 | pci_domain_nr(dev->bus), dev->bus->number, |
206 | data->id.device, data->id.function)); | 73 | PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn))); |
207 | data->bus = data->dev->subordinate; | ||
208 | device->ops.bind = acpi_pci_bind; | 74 | device->ops.bind = acpi_pci_bind; |
209 | device->ops.unbind = acpi_pci_unbind; | 75 | device->ops.unbind = acpi_pci_unbind; |
210 | } | 76 | } |
211 | 77 | ||
212 | /* | 78 | /* |
213 | * Attach ACPI-PCI Context | 79 | * Evaluate and parse _PRT, if exists. This code allows parsing of |
214 | * ----------------------- | 80 | * _PRT objects within the scope of non-bridge devices. Note that |
215 | * Thus binding the ACPI and PCI devices. | 81 | * _PRTs within the scope of a PCI bridge assume the bridge's |
216 | */ | 82 | * subordinate bus number. |
217 | status = acpi_attach_data(device->handle, acpi_pci_data_handler, data); | ||
218 | if (ACPI_FAILURE(status)) { | ||
219 | ACPI_EXCEPTION((AE_INFO, status, | ||
220 | "Unable to attach ACPI-PCI context to device %s", | ||
221 | acpi_device_bid(device))); | ||
222 | result = -ENODEV; | ||
223 | goto end; | ||
224 | } | ||
225 | |||
226 | /* | ||
227 | * PCI Routing Table | ||
228 | * ----------------- | ||
229 | * Evaluate and parse _PRT, if exists. This code is independent of | ||
230 | * PCI bridges (above) to allow parsing of _PRT objects within the | ||
231 | * scope of non-bridge devices. Note that _PRTs within the scope of | ||
232 | * a PCI bridge assume the bridge's subordinate bus number. | ||
233 | * | 83 | * |
234 | * TBD: Can _PRTs exist within the scope of non-bridge PCI devices? | 84 | * TBD: Can _PRTs exist within the scope of non-bridge PCI devices? |
235 | */ | 85 | */ |
236 | status = acpi_get_handle(device->handle, METHOD_NAME__PRT, &handle); | 86 | status = acpi_get_handle(device->handle, METHOD_NAME__PRT, &handle); |
237 | if (ACPI_SUCCESS(status)) { | ||
238 | if (data->bus) /* PCI-PCI bridge */ | ||
239 | acpi_pci_irq_add_prt(device->handle, data->id.segment, | ||
240 | data->bus->number); | ||
241 | else /* non-bridge PCI device */ | ||
242 | acpi_pci_irq_add_prt(device->handle, data->id.segment, | ||
243 | data->id.bus); | ||
244 | } | ||
245 | |||
246 | end: | ||
247 | kfree(buffer.pointer); | ||
248 | if (result) { | ||
249 | pci_dev_put(data->dev); | ||
250 | kfree(data); | ||
251 | } | ||
252 | return result; | ||
253 | } | ||
254 | |||
255 | static int acpi_pci_unbind(struct acpi_device *device) | ||
256 | { | ||
257 | int result = 0; | ||
258 | acpi_status status; | ||
259 | struct acpi_pci_data *data; | ||
260 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
261 | |||
262 | |||
263 | if (!device || !device->parent) | ||
264 | return -EINVAL; | ||
265 | |||
266 | status = acpi_get_name(device->handle, ACPI_FULL_PATHNAME, &buffer); | ||
267 | if (ACPI_FAILURE(status)) | 87 | if (ACPI_FAILURE(status)) |
268 | return -ENODEV; | 88 | goto out; |
269 | 89 | ||
270 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Unbinding PCI device [%s]...\n", | 90 | if (dev->subordinate) |
271 | (char *) buffer.pointer)); | 91 | bus = dev->subordinate; |
272 | kfree(buffer.pointer); | 92 | else |
93 | bus = dev->bus; | ||
273 | 94 | ||
274 | status = | 95 | acpi_pci_irq_add_prt(device->handle, bus); |
275 | acpi_get_data(device->handle, acpi_pci_data_handler, | ||
276 | (void **)&data); | ||
277 | if (ACPI_FAILURE(status)) { | ||
278 | result = -ENODEV; | ||
279 | goto end; | ||
280 | } | ||
281 | 96 | ||
282 | status = acpi_detach_data(device->handle, acpi_pci_data_handler); | 97 | out: |
283 | if (ACPI_FAILURE(status)) { | 98 | pci_dev_put(dev); |
284 | ACPI_EXCEPTION((AE_INFO, status, | 99 | return 0; |
285 | "Unable to detach data from device %s", | ||
286 | acpi_device_bid(device))); | ||
287 | result = -ENODEV; | ||
288 | goto end; | ||
289 | } | ||
290 | if (data->dev->subordinate) { | ||
291 | acpi_pci_irq_del_prt(data->id.segment, data->bus->number); | ||
292 | } | ||
293 | pci_dev_put(data->dev); | ||
294 | kfree(data); | ||
295 | |||
296 | end: | ||
297 | return result; | ||
298 | } | 100 | } |
299 | 101 | ||
300 | int | 102 | int acpi_pci_bind_root(struct acpi_device *device) |
301 | acpi_pci_bind_root(struct acpi_device *device, | ||
302 | struct acpi_pci_id *id, struct pci_bus *bus) | ||
303 | { | 103 | { |
304 | int result = 0; | ||
305 | acpi_status status; | ||
306 | struct acpi_pci_data *data = NULL; | ||
307 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
308 | |||
309 | if (!device || !id || !bus) { | ||
310 | return -EINVAL; | ||
311 | } | ||
312 | |||
313 | data = kzalloc(sizeof(struct acpi_pci_data), GFP_KERNEL); | ||
314 | if (!data) | ||
315 | return -ENOMEM; | ||
316 | |||
317 | data->id = *id; | ||
318 | data->bus = bus; | ||
319 | device->ops.bind = acpi_pci_bind; | 104 | device->ops.bind = acpi_pci_bind; |
320 | device->ops.unbind = acpi_pci_unbind; | 105 | device->ops.unbind = acpi_pci_unbind; |
321 | 106 | ||
322 | status = acpi_get_name(device->handle, ACPI_FULL_PATHNAME, &buffer); | 107 | return 0; |
323 | if (ACPI_FAILURE(status)) { | ||
324 | kfree (data); | ||
325 | return -ENODEV; | ||
326 | } | ||
327 | |||
328 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Binding PCI root bridge [%s] to " | ||
329 | "%04x:%02x\n", (char *)buffer.pointer, | ||
330 | id->segment, id->bus)); | ||
331 | |||
332 | status = acpi_attach_data(device->handle, acpi_pci_data_handler, data); | ||
333 | if (ACPI_FAILURE(status)) { | ||
334 | ACPI_EXCEPTION((AE_INFO, status, | ||
335 | "Unable to attach ACPI-PCI context to device %s", | ||
336 | (char *)buffer.pointer)); | ||
337 | result = -ENODEV; | ||
338 | goto end; | ||
339 | } | ||
340 | |||
341 | end: | ||
342 | kfree(buffer.pointer); | ||
343 | if (result != 0) | ||
344 | kfree(data); | ||
345 | |||
346 | return result; | ||
347 | } | 108 | } |
diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c index 51b9f8280f88..843699ed93f2 100644 --- a/drivers/acpi/pci_irq.c +++ b/drivers/acpi/pci_irq.c | |||
@@ -40,6 +40,8 @@ | |||
40 | #include <acpi/acpi_bus.h> | 40 | #include <acpi/acpi_bus.h> |
41 | #include <acpi/acpi_drivers.h> | 41 | #include <acpi/acpi_drivers.h> |
42 | 42 | ||
43 | #define PREFIX "ACPI: " | ||
44 | |||
43 | #define _COMPONENT ACPI_PCI_COMPONENT | 45 | #define _COMPONENT ACPI_PCI_COMPONENT |
44 | ACPI_MODULE_NAME("pci_irq"); | 46 | ACPI_MODULE_NAME("pci_irq"); |
45 | 47 | ||
@@ -182,7 +184,7 @@ static void do_prt_fixups(struct acpi_prt_entry *entry, | |||
182 | } | 184 | } |
183 | } | 185 | } |
184 | 186 | ||
185 | static int acpi_pci_irq_add_entry(acpi_handle handle, int segment, int bus, | 187 | static int acpi_pci_irq_add_entry(acpi_handle handle, struct pci_bus *bus, |
186 | struct acpi_pci_routing_table *prt) | 188 | struct acpi_pci_routing_table *prt) |
187 | { | 189 | { |
188 | struct acpi_prt_entry *entry; | 190 | struct acpi_prt_entry *entry; |
@@ -196,8 +198,8 @@ static int acpi_pci_irq_add_entry(acpi_handle handle, int segment, int bus, | |||
196 | * 1=INTA, 2=INTB. We use the PCI encoding throughout, so convert | 198 | * 1=INTA, 2=INTB. We use the PCI encoding throughout, so convert |
197 | * it here. | 199 | * it here. |
198 | */ | 200 | */ |
199 | entry->id.segment = segment; | 201 | entry->id.segment = pci_domain_nr(bus); |
200 | entry->id.bus = bus; | 202 | entry->id.bus = bus->number; |
201 | entry->id.device = (prt->address >> 16) & 0xFFFF; | 203 | entry->id.device = (prt->address >> 16) & 0xFFFF; |
202 | entry->pin = prt->pin + 1; | 204 | entry->pin = prt->pin + 1; |
203 | 205 | ||
@@ -242,7 +244,7 @@ static int acpi_pci_irq_add_entry(acpi_handle handle, int segment, int bus, | |||
242 | return 0; | 244 | return 0; |
243 | } | 245 | } |
244 | 246 | ||
245 | int acpi_pci_irq_add_prt(acpi_handle handle, int segment, int bus) | 247 | int acpi_pci_irq_add_prt(acpi_handle handle, struct pci_bus *bus) |
246 | { | 248 | { |
247 | acpi_status status; | 249 | acpi_status status; |
248 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | 250 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; |
@@ -271,7 +273,7 @@ int acpi_pci_irq_add_prt(acpi_handle handle, int segment, int bus) | |||
271 | 273 | ||
272 | entry = buffer.pointer; | 274 | entry = buffer.pointer; |
273 | while (entry && (entry->length > 0)) { | 275 | while (entry && (entry->length > 0)) { |
274 | acpi_pci_irq_add_entry(handle, segment, bus, entry); | 276 | acpi_pci_irq_add_entry(handle, bus, entry); |
275 | entry = (struct acpi_pci_routing_table *) | 277 | entry = (struct acpi_pci_routing_table *) |
276 | ((unsigned long)entry + entry->length); | 278 | ((unsigned long)entry + entry->length); |
277 | } | 279 | } |
@@ -280,16 +282,17 @@ int acpi_pci_irq_add_prt(acpi_handle handle, int segment, int bus) | |||
280 | return 0; | 282 | return 0; |
281 | } | 283 | } |
282 | 284 | ||
283 | void acpi_pci_irq_del_prt(int segment, int bus) | 285 | void acpi_pci_irq_del_prt(struct pci_bus *bus) |
284 | { | 286 | { |
285 | struct acpi_prt_entry *entry, *tmp; | 287 | struct acpi_prt_entry *entry, *tmp; |
286 | 288 | ||
287 | printk(KERN_DEBUG | 289 | printk(KERN_DEBUG |
288 | "ACPI: Delete PCI Interrupt Routing Table for %04x:%02x\n", | 290 | "ACPI: Delete PCI Interrupt Routing Table for %04x:%02x\n", |
289 | segment, bus); | 291 | pci_domain_nr(bus), bus->number); |
290 | spin_lock(&acpi_prt_lock); | 292 | spin_lock(&acpi_prt_lock); |
291 | list_for_each_entry_safe(entry, tmp, &acpi_prt_list, list) { | 293 | list_for_each_entry_safe(entry, tmp, &acpi_prt_list, list) { |
292 | if (segment == entry->id.segment && bus == entry->id.bus) { | 294 | if (pci_domain_nr(bus) == entry->id.segment |
295 | && bus->number == entry->id.bus) { | ||
293 | list_del(&entry->list); | 296 | list_del(&entry->list); |
294 | kfree(entry); | 297 | kfree(entry); |
295 | } | 298 | } |
@@ -401,7 +404,8 @@ int acpi_pci_irq_enable(struct pci_dev *dev) | |||
401 | /* Interrupt Line values above 0xF are forbidden */ | 404 | /* Interrupt Line values above 0xF are forbidden */ |
402 | if (dev->irq > 0 && (dev->irq <= 0xF)) { | 405 | if (dev->irq > 0 && (dev->irq <= 0xF)) { |
403 | printk(" - using IRQ %d\n", dev->irq); | 406 | printk(" - using IRQ %d\n", dev->irq); |
404 | acpi_register_gsi(dev->irq, ACPI_LEVEL_SENSITIVE, | 407 | acpi_register_gsi(&dev->dev, dev->irq, |
408 | ACPI_LEVEL_SENSITIVE, | ||
405 | ACPI_ACTIVE_LOW); | 409 | ACPI_ACTIVE_LOW); |
406 | return 0; | 410 | return 0; |
407 | } else { | 411 | } else { |
@@ -410,7 +414,7 @@ int acpi_pci_irq_enable(struct pci_dev *dev) | |||
410 | } | 414 | } |
411 | } | 415 | } |
412 | 416 | ||
413 | rc = acpi_register_gsi(gsi, triggering, polarity); | 417 | rc = acpi_register_gsi(&dev->dev, gsi, triggering, polarity); |
414 | if (rc < 0) { | 418 | if (rc < 0) { |
415 | dev_warn(&dev->dev, "PCI INT %c: failed to register GSI\n", | 419 | dev_warn(&dev->dev, "PCI INT %c: failed to register GSI\n", |
416 | pin_name(pin)); | 420 | pin_name(pin)); |
diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c index 16e0f9d3d17c..394ae89409c2 100644 --- a/drivers/acpi/pci_link.c +++ b/drivers/acpi/pci_link.c | |||
@@ -43,6 +43,8 @@ | |||
43 | #include <acpi/acpi_bus.h> | 43 | #include <acpi/acpi_bus.h> |
44 | #include <acpi/acpi_drivers.h> | 44 | #include <acpi/acpi_drivers.h> |
45 | 45 | ||
46 | #define PREFIX "ACPI: " | ||
47 | |||
46 | #define _COMPONENT ACPI_PCI_COMPONENT | 48 | #define _COMPONENT ACPI_PCI_COMPONENT |
47 | ACPI_MODULE_NAME("pci_link"); | 49 | ACPI_MODULE_NAME("pci_link"); |
48 | #define ACPI_PCI_LINK_CLASS "pci_irq_routing" | 50 | #define ACPI_PCI_LINK_CLASS "pci_irq_routing" |
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index 196f97d00956..31122214e0ec 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c | |||
@@ -36,6 +36,8 @@ | |||
36 | #include <acpi/acpi_bus.h> | 36 | #include <acpi/acpi_bus.h> |
37 | #include <acpi/acpi_drivers.h> | 37 | #include <acpi/acpi_drivers.h> |
38 | 38 | ||
39 | #define PREFIX "ACPI: " | ||
40 | |||
39 | #define _COMPONENT ACPI_PCI_COMPONENT | 41 | #define _COMPONENT ACPI_PCI_COMPONENT |
40 | ACPI_MODULE_NAME("pci_root"); | 42 | ACPI_MODULE_NAME("pci_root"); |
41 | #define ACPI_PCI_ROOT_CLASS "pci_bridge" | 43 | #define ACPI_PCI_ROOT_CLASS "pci_bridge" |
@@ -61,19 +63,6 @@ static struct acpi_driver acpi_pci_root_driver = { | |||
61 | }, | 63 | }, |
62 | }; | 64 | }; |
63 | 65 | ||
64 | struct acpi_pci_root { | ||
65 | struct list_head node; | ||
66 | struct acpi_device * device; | ||
67 | struct acpi_pci_id id; | ||
68 | struct pci_bus *bus; | ||
69 | |||
70 | u32 osc_support_set; /* _OSC state of support bits */ | ||
71 | u32 osc_control_set; /* _OSC state of control bits */ | ||
72 | u32 osc_control_qry; /* the latest _OSC query result */ | ||
73 | |||
74 | u32 osc_queried:1; /* has _OSC control been queried? */ | ||
75 | }; | ||
76 | |||
77 | static LIST_HEAD(acpi_pci_roots); | 66 | static LIST_HEAD(acpi_pci_roots); |
78 | 67 | ||
79 | static struct acpi_pci_driver *sub_driver; | 68 | static struct acpi_pci_driver *sub_driver; |
@@ -82,7 +71,7 @@ static DEFINE_MUTEX(osc_lock); | |||
82 | int acpi_pci_register_driver(struct acpi_pci_driver *driver) | 71 | int acpi_pci_register_driver(struct acpi_pci_driver *driver) |
83 | { | 72 | { |
84 | int n = 0; | 73 | int n = 0; |
85 | struct list_head *entry; | 74 | struct acpi_pci_root *root; |
86 | 75 | ||
87 | struct acpi_pci_driver **pptr = &sub_driver; | 76 | struct acpi_pci_driver **pptr = &sub_driver; |
88 | while (*pptr) | 77 | while (*pptr) |
@@ -92,9 +81,7 @@ int acpi_pci_register_driver(struct acpi_pci_driver *driver) | |||
92 | if (!driver->add) | 81 | if (!driver->add) |
93 | return 0; | 82 | return 0; |
94 | 83 | ||
95 | list_for_each(entry, &acpi_pci_roots) { | 84 | list_for_each_entry(root, &acpi_pci_roots, node) { |
96 | struct acpi_pci_root *root; | ||
97 | root = list_entry(entry, struct acpi_pci_root, node); | ||
98 | driver->add(root->device->handle); | 85 | driver->add(root->device->handle); |
99 | n++; | 86 | n++; |
100 | } | 87 | } |
@@ -106,7 +93,7 @@ EXPORT_SYMBOL(acpi_pci_register_driver); | |||
106 | 93 | ||
107 | void acpi_pci_unregister_driver(struct acpi_pci_driver *driver) | 94 | void acpi_pci_unregister_driver(struct acpi_pci_driver *driver) |
108 | { | 95 | { |
109 | struct list_head *entry; | 96 | struct acpi_pci_root *root; |
110 | 97 | ||
111 | struct acpi_pci_driver **pptr = &sub_driver; | 98 | struct acpi_pci_driver **pptr = &sub_driver; |
112 | while (*pptr) { | 99 | while (*pptr) { |
@@ -120,28 +107,48 @@ void acpi_pci_unregister_driver(struct acpi_pci_driver *driver) | |||
120 | if (!driver->remove) | 107 | if (!driver->remove) |
121 | return; | 108 | return; |
122 | 109 | ||
123 | list_for_each(entry, &acpi_pci_roots) { | 110 | list_for_each_entry(root, &acpi_pci_roots, node) |
124 | struct acpi_pci_root *root; | ||
125 | root = list_entry(entry, struct acpi_pci_root, node); | ||
126 | driver->remove(root->device->handle); | 111 | driver->remove(root->device->handle); |
127 | } | ||
128 | } | 112 | } |
129 | 113 | ||
130 | EXPORT_SYMBOL(acpi_pci_unregister_driver); | 114 | EXPORT_SYMBOL(acpi_pci_unregister_driver); |
131 | 115 | ||
132 | acpi_handle acpi_get_pci_rootbridge_handle(unsigned int seg, unsigned int bus) | 116 | acpi_handle acpi_get_pci_rootbridge_handle(unsigned int seg, unsigned int bus) |
133 | { | 117 | { |
134 | struct acpi_pci_root *tmp; | 118 | struct acpi_pci_root *root; |
135 | 119 | ||
136 | list_for_each_entry(tmp, &acpi_pci_roots, node) { | 120 | list_for_each_entry(root, &acpi_pci_roots, node) |
137 | if ((tmp->id.segment == (u16) seg) && (tmp->id.bus == (u16) bus)) | 121 | if ((root->segment == (u16) seg) && (root->bus_nr == (u16) bus)) |
138 | return tmp->device->handle; | 122 | return root->device->handle; |
139 | } | ||
140 | return NULL; | 123 | return NULL; |
141 | } | 124 | } |
142 | 125 | ||
143 | EXPORT_SYMBOL_GPL(acpi_get_pci_rootbridge_handle); | 126 | EXPORT_SYMBOL_GPL(acpi_get_pci_rootbridge_handle); |
144 | 127 | ||
128 | /** | ||
129 | * acpi_is_root_bridge - determine whether an ACPI CA node is a PCI root bridge | ||
130 | * @handle - the ACPI CA node in question. | ||
131 | * | ||
132 | * Note: we could make this API take a struct acpi_device * instead, but | ||
133 | * for now, it's more convenient to operate on an acpi_handle. | ||
134 | */ | ||
135 | int acpi_is_root_bridge(acpi_handle handle) | ||
136 | { | ||
137 | int ret; | ||
138 | struct acpi_device *device; | ||
139 | |||
140 | ret = acpi_bus_get_device(handle, &device); | ||
141 | if (ret) | ||
142 | return 0; | ||
143 | |||
144 | ret = acpi_match_device_ids(device, root_device_ids); | ||
145 | if (ret) | ||
146 | return 0; | ||
147 | else | ||
148 | return 1; | ||
149 | } | ||
150 | EXPORT_SYMBOL_GPL(acpi_is_root_bridge); | ||
151 | |||
145 | static acpi_status | 152 | static acpi_status |
146 | get_root_bridge_busnr_callback(struct acpi_resource *resource, void *data) | 153 | get_root_bridge_busnr_callback(struct acpi_resource *resource, void *data) |
147 | { | 154 | { |
@@ -161,19 +168,22 @@ get_root_bridge_busnr_callback(struct acpi_resource *resource, void *data) | |||
161 | return AE_OK; | 168 | return AE_OK; |
162 | } | 169 | } |
163 | 170 | ||
164 | static acpi_status try_get_root_bridge_busnr(acpi_handle handle, int *busnum) | 171 | static acpi_status try_get_root_bridge_busnr(acpi_handle handle, |
172 | unsigned long long *bus) | ||
165 | { | 173 | { |
166 | acpi_status status; | 174 | acpi_status status; |
175 | int busnum; | ||
167 | 176 | ||
168 | *busnum = -1; | 177 | busnum = -1; |
169 | status = | 178 | status = |
170 | acpi_walk_resources(handle, METHOD_NAME__CRS, | 179 | acpi_walk_resources(handle, METHOD_NAME__CRS, |
171 | get_root_bridge_busnr_callback, busnum); | 180 | get_root_bridge_busnr_callback, &busnum); |
172 | if (ACPI_FAILURE(status)) | 181 | if (ACPI_FAILURE(status)) |
173 | return status; | 182 | return status; |
174 | /* Check if we really get a bus number from _CRS */ | 183 | /* Check if we really get a bus number from _CRS */ |
175 | if (*busnum == -1) | 184 | if (busnum == -1) |
176 | return AE_ERROR; | 185 | return AE_ERROR; |
186 | *bus = busnum; | ||
177 | return AE_OK; | 187 | return AE_OK; |
178 | } | 188 | } |
179 | 189 | ||
@@ -295,15 +305,98 @@ static acpi_status acpi_pci_osc_support(struct acpi_pci_root *root, u32 flags) | |||
295 | return status; | 305 | return status; |
296 | } | 306 | } |
297 | 307 | ||
298 | static struct acpi_pci_root *acpi_pci_find_root(acpi_handle handle) | 308 | struct acpi_pci_root *acpi_pci_find_root(acpi_handle handle) |
299 | { | 309 | { |
300 | struct acpi_pci_root *root; | 310 | struct acpi_pci_root *root; |
311 | |||
301 | list_for_each_entry(root, &acpi_pci_roots, node) { | 312 | list_for_each_entry(root, &acpi_pci_roots, node) { |
302 | if (root->device->handle == handle) | 313 | if (root->device->handle == handle) |
303 | return root; | 314 | return root; |
304 | } | 315 | } |
305 | return NULL; | 316 | return NULL; |
306 | } | 317 | } |
318 | EXPORT_SYMBOL_GPL(acpi_pci_find_root); | ||
319 | |||
320 | struct acpi_handle_node { | ||
321 | struct list_head node; | ||
322 | acpi_handle handle; | ||
323 | }; | ||
324 | |||
325 | /** | ||
326 | * acpi_get_pci_dev - convert ACPI CA handle to struct pci_dev | ||
327 | * @handle: the handle in question | ||
328 | * | ||
329 | * Given an ACPI CA handle, the desired PCI device is located in the | ||
330 | * list of PCI devices. | ||
331 | * | ||
332 | * If the device is found, its reference count is increased and this | ||
333 | * function returns a pointer to its data structure. The caller must | ||
334 | * decrement the reference count by calling pci_dev_put(). | ||
335 | * If no device is found, %NULL is returned. | ||
336 | */ | ||
337 | struct pci_dev *acpi_get_pci_dev(acpi_handle handle) | ||
338 | { | ||
339 | int dev, fn; | ||
340 | unsigned long long adr; | ||
341 | acpi_status status; | ||
342 | acpi_handle phandle; | ||
343 | struct pci_bus *pbus; | ||
344 | struct pci_dev *pdev = NULL; | ||
345 | struct acpi_handle_node *node, *tmp; | ||
346 | struct acpi_pci_root *root; | ||
347 | LIST_HEAD(device_list); | ||
348 | |||
349 | /* | ||
350 | * Walk up the ACPI CA namespace until we reach a PCI root bridge. | ||
351 | */ | ||
352 | phandle = handle; | ||
353 | while (!acpi_is_root_bridge(phandle)) { | ||
354 | node = kzalloc(sizeof(struct acpi_handle_node), GFP_KERNEL); | ||
355 | if (!node) | ||
356 | goto out; | ||
357 | |||
358 | INIT_LIST_HEAD(&node->node); | ||
359 | node->handle = phandle; | ||
360 | list_add(&node->node, &device_list); | ||
361 | |||
362 | status = acpi_get_parent(phandle, &phandle); | ||
363 | if (ACPI_FAILURE(status)) | ||
364 | goto out; | ||
365 | } | ||
366 | |||
367 | root = acpi_pci_find_root(phandle); | ||
368 | if (!root) | ||
369 | goto out; | ||
370 | |||
371 | pbus = root->bus; | ||
372 | |||
373 | /* | ||
374 | * Now, walk back down the PCI device tree until we return to our | ||
375 | * original handle. Assumes that everything between the PCI root | ||
376 | * bridge and the device we're looking for must be a P2P bridge. | ||
377 | */ | ||
378 | list_for_each_entry(node, &device_list, node) { | ||
379 | acpi_handle hnd = node->handle; | ||
380 | status = acpi_evaluate_integer(hnd, "_ADR", NULL, &adr); | ||
381 | if (ACPI_FAILURE(status)) | ||
382 | goto out; | ||
383 | dev = (adr >> 16) & 0xffff; | ||
384 | fn = adr & 0xffff; | ||
385 | |||
386 | pdev = pci_get_slot(pbus, PCI_DEVFN(dev, fn)); | ||
387 | if (!pdev || hnd == handle) | ||
388 | break; | ||
389 | |||
390 | pbus = pdev->subordinate; | ||
391 | pci_dev_put(pdev); | ||
392 | } | ||
393 | out: | ||
394 | list_for_each_entry_safe(node, tmp, &device_list, node) | ||
395 | kfree(node); | ||
396 | |||
397 | return pdev; | ||
398 | } | ||
399 | EXPORT_SYMBOL_GPL(acpi_get_pci_dev); | ||
307 | 400 | ||
308 | /** | 401 | /** |
309 | * acpi_pci_osc_control_set - commit requested control to Firmware | 402 | * acpi_pci_osc_control_set - commit requested control to Firmware |
@@ -363,31 +456,46 @@ EXPORT_SYMBOL(acpi_pci_osc_control_set); | |||
363 | 456 | ||
364 | static int __devinit acpi_pci_root_add(struct acpi_device *device) | 457 | static int __devinit acpi_pci_root_add(struct acpi_device *device) |
365 | { | 458 | { |
366 | int result = 0; | 459 | unsigned long long segment, bus; |
367 | struct acpi_pci_root *root = NULL; | 460 | acpi_status status; |
368 | struct acpi_pci_root *tmp; | 461 | int result; |
369 | acpi_status status = AE_OK; | 462 | struct acpi_pci_root *root; |
370 | unsigned long long value = 0; | 463 | acpi_handle handle; |
371 | acpi_handle handle = NULL; | ||
372 | struct acpi_device *child; | 464 | struct acpi_device *child; |
373 | u32 flags, base_flags; | 465 | u32 flags, base_flags; |
374 | 466 | ||
467 | segment = 0; | ||
468 | status = acpi_evaluate_integer(device->handle, METHOD_NAME__SEG, NULL, | ||
469 | &segment); | ||
470 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { | ||
471 | printk(KERN_ERR PREFIX "can't evaluate _SEG\n"); | ||
472 | return -ENODEV; | ||
473 | } | ||
375 | 474 | ||
376 | if (!device) | 475 | /* Check _CRS first, then _BBN. If no _BBN, default to zero. */ |
377 | return -EINVAL; | 476 | bus = 0; |
477 | status = try_get_root_bridge_busnr(device->handle, &bus); | ||
478 | if (ACPI_FAILURE(status)) { | ||
479 | status = acpi_evaluate_integer(device->handle, METHOD_NAME__BBN, NULL, &bus); | ||
480 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { | ||
481 | printk(KERN_ERR PREFIX | ||
482 | "no bus number in _CRS and can't evaluate _BBN\n"); | ||
483 | return -ENODEV; | ||
484 | } | ||
485 | } | ||
378 | 486 | ||
379 | root = kzalloc(sizeof(struct acpi_pci_root), GFP_KERNEL); | 487 | root = kzalloc(sizeof(struct acpi_pci_root), GFP_KERNEL); |
380 | if (!root) | 488 | if (!root) |
381 | return -ENOMEM; | 489 | return -ENOMEM; |
382 | INIT_LIST_HEAD(&root->node); | ||
383 | 490 | ||
491 | INIT_LIST_HEAD(&root->node); | ||
384 | root->device = device; | 492 | root->device = device; |
493 | root->segment = segment & 0xFFFF; | ||
494 | root->bus_nr = bus & 0xFF; | ||
385 | strcpy(acpi_device_name(device), ACPI_PCI_ROOT_DEVICE_NAME); | 495 | strcpy(acpi_device_name(device), ACPI_PCI_ROOT_DEVICE_NAME); |
386 | strcpy(acpi_device_class(device), ACPI_PCI_ROOT_CLASS); | 496 | strcpy(acpi_device_class(device), ACPI_PCI_ROOT_CLASS); |
387 | device->driver_data = root; | 497 | device->driver_data = root; |
388 | 498 | ||
389 | device->ops.bind = acpi_pci_bind; | ||
390 | |||
391 | /* | 499 | /* |
392 | * All supported architectures that use ACPI have support for | 500 | * All supported architectures that use ACPI have support for |
393 | * PCI domains, so we indicate this in _OSC support capabilities. | 501 | * PCI domains, so we indicate this in _OSC support capabilities. |
@@ -395,79 +503,6 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) | |||
395 | flags = base_flags = OSC_PCI_SEGMENT_GROUPS_SUPPORT; | 503 | flags = base_flags = OSC_PCI_SEGMENT_GROUPS_SUPPORT; |
396 | acpi_pci_osc_support(root, flags); | 504 | acpi_pci_osc_support(root, flags); |
397 | 505 | ||
398 | /* | ||
399 | * Segment | ||
400 | * ------- | ||
401 | * Obtained via _SEG, if exists, otherwise assumed to be zero (0). | ||
402 | */ | ||
403 | status = acpi_evaluate_integer(device->handle, METHOD_NAME__SEG, NULL, | ||
404 | &value); | ||
405 | switch (status) { | ||
406 | case AE_OK: | ||
407 | root->id.segment = (u16) value; | ||
408 | break; | ||
409 | case AE_NOT_FOUND: | ||
410 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
411 | "Assuming segment 0 (no _SEG)\n")); | ||
412 | root->id.segment = 0; | ||
413 | break; | ||
414 | default: | ||
415 | ACPI_EXCEPTION((AE_INFO, status, "Evaluating _SEG")); | ||
416 | result = -ENODEV; | ||
417 | goto end; | ||
418 | } | ||
419 | |||
420 | /* | ||
421 | * Bus | ||
422 | * --- | ||
423 | * Obtained via _BBN, if exists, otherwise assumed to be zero (0). | ||
424 | */ | ||
425 | status = acpi_evaluate_integer(device->handle, METHOD_NAME__BBN, NULL, | ||
426 | &value); | ||
427 | switch (status) { | ||
428 | case AE_OK: | ||
429 | root->id.bus = (u16) value; | ||
430 | break; | ||
431 | case AE_NOT_FOUND: | ||
432 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Assuming bus 0 (no _BBN)\n")); | ||
433 | root->id.bus = 0; | ||
434 | break; | ||
435 | default: | ||
436 | ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BBN")); | ||
437 | result = -ENODEV; | ||
438 | goto end; | ||
439 | } | ||
440 | |||
441 | /* Some systems have wrong _BBN */ | ||
442 | list_for_each_entry(tmp, &acpi_pci_roots, node) { | ||
443 | if ((tmp->id.segment == root->id.segment) | ||
444 | && (tmp->id.bus == root->id.bus)) { | ||
445 | int bus = 0; | ||
446 | acpi_status status; | ||
447 | |||
448 | printk(KERN_ERR PREFIX | ||
449 | "Wrong _BBN value, reboot" | ||
450 | " and use option 'pci=noacpi'\n"); | ||
451 | |||
452 | status = try_get_root_bridge_busnr(device->handle, &bus); | ||
453 | if (ACPI_FAILURE(status)) | ||
454 | break; | ||
455 | if (bus != root->id.bus) { | ||
456 | printk(KERN_INFO PREFIX | ||
457 | "PCI _CRS %d overrides _BBN 0\n", bus); | ||
458 | root->id.bus = bus; | ||
459 | } | ||
460 | break; | ||
461 | } | ||
462 | } | ||
463 | /* | ||
464 | * Device & Function | ||
465 | * ----------------- | ||
466 | * Obtained from _ADR (which has already been evaluated for us). | ||
467 | */ | ||
468 | root->id.device = device->pnp.bus_address >> 16; | ||
469 | root->id.function = device->pnp.bus_address & 0xFFFF; | ||
470 | |||
471 | /* | 506 | /* |
472 | * TBD: Need PCI interface for enumeration/configuration of roots. | 507 | * TBD: Need PCI interface for enumeration/configuration of roots. |
473 | */ | 508 | */ |
@@ -477,7 +512,7 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) | |||
477 | 512 | ||
478 | printk(KERN_INFO PREFIX "%s [%s] (%04x:%02x)\n", | 513 | printk(KERN_INFO PREFIX "%s [%s] (%04x:%02x)\n", |
479 | acpi_device_name(device), acpi_device_bid(device), | 514 | acpi_device_name(device), acpi_device_bid(device), |
480 | root->id.segment, root->id.bus); | 515 | root->segment, root->bus_nr); |
481 | 516 | ||
482 | /* | 517 | /* |
483 | * Scan the Root Bridge | 518 | * Scan the Root Bridge |
@@ -486,11 +521,11 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) | |||
486 | * PCI namespace does not get created until this call is made (and | 521 | * PCI namespace does not get created until this call is made (and |
487 | * thus the root bridge's pci_dev does not exist). | 522 | * thus the root bridge's pci_dev does not exist). |
488 | */ | 523 | */ |
489 | root->bus = pci_acpi_scan_root(device, root->id.segment, root->id.bus); | 524 | root->bus = pci_acpi_scan_root(device, segment, bus); |
490 | if (!root->bus) { | 525 | if (!root->bus) { |
491 | printk(KERN_ERR PREFIX | 526 | printk(KERN_ERR PREFIX |
492 | "Bus %04x:%02x not present in PCI namespace\n", | 527 | "Bus %04x:%02x not present in PCI namespace\n", |
493 | root->id.segment, root->id.bus); | 528 | root->segment, root->bus_nr); |
494 | result = -ENODEV; | 529 | result = -ENODEV; |
495 | goto end; | 530 | goto end; |
496 | } | 531 | } |
@@ -500,7 +535,7 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) | |||
500 | * ----------------------- | 535 | * ----------------------- |
501 | * Thus binding the ACPI and PCI devices. | 536 | * Thus binding the ACPI and PCI devices. |
502 | */ | 537 | */ |
503 | result = acpi_pci_bind_root(device, &root->id, root->bus); | 538 | result = acpi_pci_bind_root(device); |
504 | if (result) | 539 | if (result) |
505 | goto end; | 540 | goto end; |
506 | 541 | ||
@@ -511,8 +546,7 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) | |||
511 | */ | 546 | */ |
512 | status = acpi_get_handle(device->handle, METHOD_NAME__PRT, &handle); | 547 | status = acpi_get_handle(device->handle, METHOD_NAME__PRT, &handle); |
513 | if (ACPI_SUCCESS(status)) | 548 | if (ACPI_SUCCESS(status)) |
514 | result = acpi_pci_irq_add_prt(device->handle, root->id.segment, | 549 | result = acpi_pci_irq_add_prt(device->handle, root->bus); |
515 | root->id.bus); | ||
516 | 550 | ||
517 | /* | 551 | /* |
518 | * Scan and bind all _ADR-Based Devices | 552 | * Scan and bind all _ADR-Based Devices |
@@ -531,42 +565,28 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) | |||
531 | if (flags != base_flags) | 565 | if (flags != base_flags) |
532 | acpi_pci_osc_support(root, flags); | 566 | acpi_pci_osc_support(root, flags); |
533 | 567 | ||
534 | end: | 568 | return 0; |
535 | if (result) { | ||
536 | if (!list_empty(&root->node)) | ||
537 | list_del(&root->node); | ||
538 | kfree(root); | ||
539 | } | ||
540 | 569 | ||
570 | end: | ||
571 | if (!list_empty(&root->node)) | ||
572 | list_del(&root->node); | ||
573 | kfree(root); | ||
541 | return result; | 574 | return result; |
542 | } | 575 | } |
543 | 576 | ||
544 | static int acpi_pci_root_start(struct acpi_device *device) | 577 | static int acpi_pci_root_start(struct acpi_device *device) |
545 | { | 578 | { |
546 | struct acpi_pci_root *root; | 579 | struct acpi_pci_root *root = acpi_driver_data(device); |
547 | 580 | ||
548 | 581 | pci_bus_add_devices(root->bus); | |
549 | list_for_each_entry(root, &acpi_pci_roots, node) { | 582 | return 0; |
550 | if (root->device == device) { | ||
551 | pci_bus_add_devices(root->bus); | ||
552 | return 0; | ||
553 | } | ||
554 | } | ||
555 | return -ENODEV; | ||
556 | } | 583 | } |
557 | 584 | ||
558 | static int acpi_pci_root_remove(struct acpi_device *device, int type) | 585 | static int acpi_pci_root_remove(struct acpi_device *device, int type) |
559 | { | 586 | { |
560 | struct acpi_pci_root *root = NULL; | 587 | struct acpi_pci_root *root = acpi_driver_data(device); |
561 | |||
562 | |||
563 | if (!device || !acpi_driver_data(device)) | ||
564 | return -EINVAL; | ||
565 | |||
566 | root = acpi_driver_data(device); | ||
567 | 588 | ||
568 | kfree(root); | 589 | kfree(root); |
569 | |||
570 | return 0; | 590 | return 0; |
571 | } | 591 | } |
572 | 592 | ||
diff --git a/drivers/acpi/pci_slot.c b/drivers/acpi/pci_slot.c index 12158e0d009b..da9d6d25cf6d 100644 --- a/drivers/acpi/pci_slot.c +++ b/drivers/acpi/pci_slot.c | |||
@@ -57,7 +57,7 @@ ACPI_MODULE_NAME("pci_slot"); | |||
57 | MY_NAME , ## arg); \ | 57 | MY_NAME , ## arg); \ |
58 | } while (0) | 58 | } while (0) |
59 | 59 | ||
60 | #define SLOT_NAME_SIZE 20 /* Inspired by #define in acpiphp.h */ | 60 | #define SLOT_NAME_SIZE 21 /* Inspired by #define in acpiphp.h */ |
61 | 61 | ||
62 | struct acpi_pci_slot { | 62 | struct acpi_pci_slot { |
63 | acpi_handle root_handle; /* handle of the root bridge */ | 63 | acpi_handle root_handle; /* handle of the root bridge */ |
@@ -149,7 +149,7 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
149 | return AE_OK; | 149 | return AE_OK; |
150 | } | 150 | } |
151 | 151 | ||
152 | snprintf(name, sizeof(name), "%u", (u32)sun); | 152 | snprintf(name, sizeof(name), "%llu", sun); |
153 | pci_slot = pci_create_slot(pci_bus, device, name, NULL); | 153 | pci_slot = pci_create_slot(pci_bus, device, name, NULL); |
154 | if (IS_ERR(pci_slot)) { | 154 | if (IS_ERR(pci_slot)) { |
155 | err("pci_create_slot returned %ld\n", PTR_ERR(pci_slot)); | 155 | err("pci_create_slot returned %ld\n", PTR_ERR(pci_slot)); |
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index 56665a63bf19..22b297916519 100644 --- a/drivers/acpi/power.c +++ b/drivers/acpi/power.c | |||
@@ -43,6 +43,9 @@ | |||
43 | #include <linux/seq_file.h> | 43 | #include <linux/seq_file.h> |
44 | #include <acpi/acpi_bus.h> | 44 | #include <acpi/acpi_bus.h> |
45 | #include <acpi/acpi_drivers.h> | 45 | #include <acpi/acpi_drivers.h> |
46 | #include "sleep.h" | ||
47 | |||
48 | #define PREFIX "ACPI: " | ||
46 | 49 | ||
47 | #define _COMPONENT ACPI_POWER_COMPONENT | 50 | #define _COMPONENT ACPI_POWER_COMPONENT |
48 | ACPI_MODULE_NAME("power"); | 51 | ACPI_MODULE_NAME("power"); |
@@ -194,7 +197,7 @@ static int acpi_power_get_list_state(struct acpi_handle_list *list, int *state) | |||
194 | 197 | ||
195 | static int acpi_power_on(acpi_handle handle, struct acpi_device *dev) | 198 | static int acpi_power_on(acpi_handle handle, struct acpi_device *dev) |
196 | { | 199 | { |
197 | int result = 0, state; | 200 | int result = 0; |
198 | int found = 0; | 201 | int found = 0; |
199 | acpi_status status = AE_OK; | 202 | acpi_status status = AE_OK; |
200 | struct acpi_power_resource *resource = NULL; | 203 | struct acpi_power_resource *resource = NULL; |
@@ -236,18 +239,6 @@ static int acpi_power_on(acpi_handle handle, struct acpi_device *dev) | |||
236 | if (ACPI_FAILURE(status)) | 239 | if (ACPI_FAILURE(status)) |
237 | return -ENODEV; | 240 | return -ENODEV; |
238 | 241 | ||
239 | if (!acpi_power_nocheck) { | ||
240 | /* | ||
241 | * If acpi_power_nocheck is set, it is unnecessary to check | ||
242 | * the power state after power transition. | ||
243 | */ | ||
244 | result = acpi_power_get_state(resource->device->handle, | ||
245 | &state); | ||
246 | if (result) | ||
247 | return result; | ||
248 | if (state != ACPI_POWER_RESOURCE_STATE_ON) | ||
249 | return -ENOEXEC; | ||
250 | } | ||
251 | /* Update the power resource's _device_ power state */ | 242 | /* Update the power resource's _device_ power state */ |
252 | resource->device->power.state = ACPI_STATE_D0; | 243 | resource->device->power.state = ACPI_STATE_D0; |
253 | 244 | ||
@@ -258,7 +249,7 @@ static int acpi_power_on(acpi_handle handle, struct acpi_device *dev) | |||
258 | 249 | ||
259 | static int acpi_power_off_device(acpi_handle handle, struct acpi_device *dev) | 250 | static int acpi_power_off_device(acpi_handle handle, struct acpi_device *dev) |
260 | { | 251 | { |
261 | int result = 0, state; | 252 | int result = 0; |
262 | acpi_status status = AE_OK; | 253 | acpi_status status = AE_OK; |
263 | struct acpi_power_resource *resource = NULL; | 254 | struct acpi_power_resource *resource = NULL; |
264 | struct list_head *node, *next; | 255 | struct list_head *node, *next; |
@@ -293,18 +284,6 @@ static int acpi_power_off_device(acpi_handle handle, struct acpi_device *dev) | |||
293 | if (ACPI_FAILURE(status)) | 284 | if (ACPI_FAILURE(status)) |
294 | return -ENODEV; | 285 | return -ENODEV; |
295 | 286 | ||
296 | if (!acpi_power_nocheck) { | ||
297 | /* | ||
298 | * If acpi_power_nocheck is set, it is unnecessary to check | ||
299 | * the power state after power transition. | ||
300 | */ | ||
301 | result = acpi_power_get_state(handle, &state); | ||
302 | if (result) | ||
303 | return result; | ||
304 | if (state != ACPI_POWER_RESOURCE_STATE_OFF) | ||
305 | return -ENOEXEC; | ||
306 | } | ||
307 | |||
308 | /* Update the power resource's _device_ power state */ | 287 | /* Update the power resource's _device_ power state */ |
309 | resource->device->power.state = ACPI_STATE_D3; | 288 | resource->device->power.state = ACPI_STATE_D3; |
310 | 289 | ||
@@ -385,17 +364,15 @@ int acpi_device_sleep_wake(struct acpi_device *dev, | |||
385 | */ | 364 | */ |
386 | int acpi_enable_wakeup_device_power(struct acpi_device *dev, int sleep_state) | 365 | int acpi_enable_wakeup_device_power(struct acpi_device *dev, int sleep_state) |
387 | { | 366 | { |
388 | int i, err; | 367 | int i, err = 0; |
389 | 368 | ||
390 | if (!dev || !dev->wakeup.flags.valid) | 369 | if (!dev || !dev->wakeup.flags.valid) |
391 | return -EINVAL; | 370 | return -EINVAL; |
392 | 371 | ||
393 | /* | 372 | mutex_lock(&acpi_device_lock); |
394 | * Do not execute the code below twice in a row without calling | 373 | |
395 | * acpi_disable_wakeup_device_power() in between for the same device | 374 | if (dev->wakeup.prepare_count++) |
396 | */ | 375 | goto out; |
397 | if (dev->wakeup.flags.prepared) | ||
398 | return 0; | ||
399 | 376 | ||
400 | /* Open power resource */ | 377 | /* Open power resource */ |
401 | for (i = 0; i < dev->wakeup.resources.count; i++) { | 378 | for (i = 0; i < dev->wakeup.resources.count; i++) { |
@@ -403,7 +380,8 @@ int acpi_enable_wakeup_device_power(struct acpi_device *dev, int sleep_state) | |||
403 | if (ret) { | 380 | if (ret) { |
404 | printk(KERN_ERR PREFIX "Transition power state\n"); | 381 | printk(KERN_ERR PREFIX "Transition power state\n"); |
405 | dev->wakeup.flags.valid = 0; | 382 | dev->wakeup.flags.valid = 0; |
406 | return -ENODEV; | 383 | err = -ENODEV; |
384 | goto err_out; | ||
407 | } | 385 | } |
408 | } | 386 | } |
409 | 387 | ||
@@ -412,9 +390,13 @@ int acpi_enable_wakeup_device_power(struct acpi_device *dev, int sleep_state) | |||
412 | * in arbitrary power state afterwards. | 390 | * in arbitrary power state afterwards. |
413 | */ | 391 | */ |
414 | err = acpi_device_sleep_wake(dev, 1, sleep_state, 3); | 392 | err = acpi_device_sleep_wake(dev, 1, sleep_state, 3); |
415 | if (!err) | ||
416 | dev->wakeup.flags.prepared = 1; | ||
417 | 393 | ||
394 | err_out: | ||
395 | if (err) | ||
396 | dev->wakeup.prepare_count = 0; | ||
397 | |||
398 | out: | ||
399 | mutex_unlock(&acpi_device_lock); | ||
418 | return err; | 400 | return err; |
419 | } | 401 | } |
420 | 402 | ||
@@ -426,35 +408,42 @@ int acpi_enable_wakeup_device_power(struct acpi_device *dev, int sleep_state) | |||
426 | */ | 408 | */ |
427 | int acpi_disable_wakeup_device_power(struct acpi_device *dev) | 409 | int acpi_disable_wakeup_device_power(struct acpi_device *dev) |
428 | { | 410 | { |
429 | int i, ret; | 411 | int i, err = 0; |
430 | 412 | ||
431 | if (!dev || !dev->wakeup.flags.valid) | 413 | if (!dev || !dev->wakeup.flags.valid) |
432 | return -EINVAL; | 414 | return -EINVAL; |
433 | 415 | ||
416 | mutex_lock(&acpi_device_lock); | ||
417 | |||
418 | if (--dev->wakeup.prepare_count > 0) | ||
419 | goto out; | ||
420 | |||
434 | /* | 421 | /* |
435 | * Do not execute the code below twice in a row without calling | 422 | * Executing the code below even if prepare_count is already zero when |
436 | * acpi_enable_wakeup_device_power() in between for the same device | 423 | * the function is called may be useful, for example for initialisation. |
437 | */ | 424 | */ |
438 | if (!dev->wakeup.flags.prepared) | 425 | if (dev->wakeup.prepare_count < 0) |
439 | return 0; | 426 | dev->wakeup.prepare_count = 0; |
440 | 427 | ||
441 | dev->wakeup.flags.prepared = 0; | 428 | err = acpi_device_sleep_wake(dev, 0, 0, 0); |
442 | 429 | if (err) | |
443 | ret = acpi_device_sleep_wake(dev, 0, 0, 0); | 430 | goto out; |
444 | if (ret) | ||
445 | return ret; | ||
446 | 431 | ||
447 | /* Close power resource */ | 432 | /* Close power resource */ |
448 | for (i = 0; i < dev->wakeup.resources.count; i++) { | 433 | for (i = 0; i < dev->wakeup.resources.count; i++) { |
449 | ret = acpi_power_off_device(dev->wakeup.resources.handles[i], dev); | 434 | int ret = acpi_power_off_device( |
435 | dev->wakeup.resources.handles[i], dev); | ||
450 | if (ret) { | 436 | if (ret) { |
451 | printk(KERN_ERR PREFIX "Transition power state\n"); | 437 | printk(KERN_ERR PREFIX "Transition power state\n"); |
452 | dev->wakeup.flags.valid = 0; | 438 | dev->wakeup.flags.valid = 0; |
453 | return -ENODEV; | 439 | err = -ENODEV; |
440 | goto out; | ||
454 | } | 441 | } |
455 | } | 442 | } |
456 | 443 | ||
457 | return ret; | 444 | out: |
445 | mutex_unlock(&acpi_device_lock); | ||
446 | return err; | ||
458 | } | 447 | } |
459 | 448 | ||
460 | /* -------------------------------------------------------------------------- | 449 | /* -------------------------------------------------------------------------- |
diff --git a/drivers/acpi/power_meter.c b/drivers/acpi/power_meter.c new file mode 100644 index 000000000000..e6bfd77986b8 --- /dev/null +++ b/drivers/acpi/power_meter.c | |||
@@ -0,0 +1,1018 @@ | |||
1 | /* | ||
2 | * A hwmon driver for ACPI 4.0 power meters | ||
3 | * Copyright (C) 2009 IBM | ||
4 | * | ||
5 | * Author: Darrick J. Wong <djwong@us.ibm.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | */ | ||
21 | |||
22 | #include <linux/module.h> | ||
23 | #include <linux/hwmon.h> | ||
24 | #include <linux/hwmon-sysfs.h> | ||
25 | #include <linux/jiffies.h> | ||
26 | #include <linux/mutex.h> | ||
27 | #include <linux/dmi.h> | ||
28 | #include <linux/kdev_t.h> | ||
29 | #include <linux/sched.h> | ||
30 | #include <linux/time.h> | ||
31 | #include <acpi/acpi_drivers.h> | ||
32 | #include <acpi/acpi_bus.h> | ||
33 | |||
34 | #define ACPI_POWER_METER_NAME "power_meter" | ||
35 | ACPI_MODULE_NAME(ACPI_POWER_METER_NAME); | ||
36 | #define ACPI_POWER_METER_DEVICE_NAME "Power Meter" | ||
37 | #define ACPI_POWER_METER_CLASS "power_meter_resource" | ||
38 | |||
39 | #define NUM_SENSORS 17 | ||
40 | |||
41 | #define POWER_METER_CAN_MEASURE (1 << 0) | ||
42 | #define POWER_METER_CAN_TRIP (1 << 1) | ||
43 | #define POWER_METER_CAN_CAP (1 << 2) | ||
44 | #define POWER_METER_CAN_NOTIFY (1 << 3) | ||
45 | #define POWER_METER_IS_BATTERY (1 << 8) | ||
46 | #define UNKNOWN_HYSTERESIS 0xFFFFFFFF | ||
47 | |||
48 | #define METER_NOTIFY_CONFIG 0x80 | ||
49 | #define METER_NOTIFY_TRIP 0x81 | ||
50 | #define METER_NOTIFY_CAP 0x82 | ||
51 | #define METER_NOTIFY_CAPPING 0x83 | ||
52 | #define METER_NOTIFY_INTERVAL 0x84 | ||
53 | |||
54 | #define POWER_AVERAGE_NAME "power1_average" | ||
55 | #define POWER_CAP_NAME "power1_cap" | ||
56 | #define POWER_AVG_INTERVAL_NAME "power1_average_interval" | ||
57 | #define POWER_ALARM_NAME "power1_alarm" | ||
58 | |||
59 | static int cap_in_hardware; | ||
60 | static int force_cap_on; | ||
61 | |||
62 | static int can_cap_in_hardware(void) | ||
63 | { | ||
64 | return force_cap_on || cap_in_hardware; | ||
65 | } | ||
66 | |||
67 | static struct acpi_device_id power_meter_ids[] = { | ||
68 | {"ACPI000D", 0}, | ||
69 | {"", 0}, | ||
70 | }; | ||
71 | MODULE_DEVICE_TABLE(acpi, power_meter_ids); | ||
72 | |||
73 | struct acpi_power_meter_capabilities { | ||
74 | acpi_integer flags; | ||
75 | acpi_integer units; | ||
76 | acpi_integer type; | ||
77 | acpi_integer accuracy; | ||
78 | acpi_integer sampling_time; | ||
79 | acpi_integer min_avg_interval; | ||
80 | acpi_integer max_avg_interval; | ||
81 | acpi_integer hysteresis; | ||
82 | acpi_integer configurable_cap; | ||
83 | acpi_integer min_cap; | ||
84 | acpi_integer max_cap; | ||
85 | }; | ||
86 | |||
87 | struct acpi_power_meter_resource { | ||
88 | struct acpi_device *acpi_dev; | ||
89 | acpi_bus_id name; | ||
90 | struct mutex lock; | ||
91 | struct device *hwmon_dev; | ||
92 | struct acpi_power_meter_capabilities caps; | ||
93 | acpi_string model_number; | ||
94 | acpi_string serial_number; | ||
95 | acpi_string oem_info; | ||
96 | acpi_integer power; | ||
97 | acpi_integer cap; | ||
98 | acpi_integer avg_interval; | ||
99 | int sensors_valid; | ||
100 | unsigned long sensors_last_updated; | ||
101 | struct sensor_device_attribute sensors[NUM_SENSORS]; | ||
102 | int num_sensors; | ||
103 | int trip[2]; | ||
104 | int num_domain_devices; | ||
105 | struct acpi_device **domain_devices; | ||
106 | struct kobject *holders_dir; | ||
107 | }; | ||
108 | |||
109 | struct ro_sensor_template { | ||
110 | char *label; | ||
111 | ssize_t (*show)(struct device *dev, | ||
112 | struct device_attribute *devattr, | ||
113 | char *buf); | ||
114 | int index; | ||
115 | }; | ||
116 | |||
117 | struct rw_sensor_template { | ||
118 | char *label; | ||
119 | ssize_t (*show)(struct device *dev, | ||
120 | struct device_attribute *devattr, | ||
121 | char *buf); | ||
122 | ssize_t (*set)(struct device *dev, | ||
123 | struct device_attribute *devattr, | ||
124 | const char *buf, size_t count); | ||
125 | int index; | ||
126 | }; | ||
127 | |||
128 | /* Averaging interval */ | ||
129 | static int update_avg_interval(struct acpi_power_meter_resource *resource) | ||
130 | { | ||
131 | unsigned long long data; | ||
132 | acpi_status status; | ||
133 | |||
134 | status = acpi_evaluate_integer(resource->acpi_dev->handle, "_GAI", | ||
135 | NULL, &data); | ||
136 | if (ACPI_FAILURE(status)) { | ||
137 | ACPI_EXCEPTION((AE_INFO, status, "Evaluating _GAI")); | ||
138 | return -ENODEV; | ||
139 | } | ||
140 | |||
141 | resource->avg_interval = data; | ||
142 | return 0; | ||
143 | } | ||
144 | |||
145 | static ssize_t show_avg_interval(struct device *dev, | ||
146 | struct device_attribute *devattr, | ||
147 | char *buf) | ||
148 | { | ||
149 | struct acpi_device *acpi_dev = to_acpi_device(dev); | ||
150 | struct acpi_power_meter_resource *resource = acpi_dev->driver_data; | ||
151 | |||
152 | mutex_lock(&resource->lock); | ||
153 | update_avg_interval(resource); | ||
154 | mutex_unlock(&resource->lock); | ||
155 | |||
156 | return sprintf(buf, "%llu\n", resource->avg_interval); | ||
157 | } | ||
158 | |||
159 | static ssize_t set_avg_interval(struct device *dev, | ||
160 | struct device_attribute *devattr, | ||
161 | const char *buf, size_t count) | ||
162 | { | ||
163 | struct acpi_device *acpi_dev = to_acpi_device(dev); | ||
164 | struct acpi_power_meter_resource *resource = acpi_dev->driver_data; | ||
165 | union acpi_object arg0 = { ACPI_TYPE_INTEGER }; | ||
166 | struct acpi_object_list args = { 1, &arg0 }; | ||
167 | int res; | ||
168 | unsigned long temp; | ||
169 | unsigned long long data; | ||
170 | acpi_status status; | ||
171 | |||
172 | res = strict_strtoul(buf, 10, &temp); | ||
173 | if (res) | ||
174 | return res; | ||
175 | |||
176 | if (temp > resource->caps.max_avg_interval || | ||
177 | temp < resource->caps.min_avg_interval) | ||
178 | return -EINVAL; | ||
179 | arg0.integer.value = temp; | ||
180 | |||
181 | mutex_lock(&resource->lock); | ||
182 | status = acpi_evaluate_integer(resource->acpi_dev->handle, "_PAI", | ||
183 | &args, &data); | ||
184 | if (!ACPI_FAILURE(status)) | ||
185 | resource->avg_interval = temp; | ||
186 | mutex_unlock(&resource->lock); | ||
187 | |||
188 | if (ACPI_FAILURE(status)) { | ||
189 | ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PAI")); | ||
190 | return -EINVAL; | ||
191 | } | ||
192 | |||
193 | /* _PAI returns 0 on success, nonzero otherwise */ | ||
194 | if (data) | ||
195 | return -EINVAL; | ||
196 | |||
197 | return count; | ||
198 | } | ||
199 | |||
200 | /* Cap functions */ | ||
201 | static int update_cap(struct acpi_power_meter_resource *resource) | ||
202 | { | ||
203 | unsigned long long data; | ||
204 | acpi_status status; | ||
205 | |||
206 | status = acpi_evaluate_integer(resource->acpi_dev->handle, "_GHL", | ||
207 | NULL, &data); | ||
208 | if (ACPI_FAILURE(status)) { | ||
209 | ACPI_EXCEPTION((AE_INFO, status, "Evaluating _GHL")); | ||
210 | return -ENODEV; | ||
211 | } | ||
212 | |||
213 | resource->cap = data; | ||
214 | return 0; | ||
215 | } | ||
216 | |||
217 | static ssize_t show_cap(struct device *dev, | ||
218 | struct device_attribute *devattr, | ||
219 | char *buf) | ||
220 | { | ||
221 | struct acpi_device *acpi_dev = to_acpi_device(dev); | ||
222 | struct acpi_power_meter_resource *resource = acpi_dev->driver_data; | ||
223 | |||
224 | mutex_lock(&resource->lock); | ||
225 | update_cap(resource); | ||
226 | mutex_unlock(&resource->lock); | ||
227 | |||
228 | return sprintf(buf, "%llu\n", resource->cap * 1000); | ||
229 | } | ||
230 | |||
231 | static ssize_t set_cap(struct device *dev, struct device_attribute *devattr, | ||
232 | const char *buf, size_t count) | ||
233 | { | ||
234 | struct acpi_device *acpi_dev = to_acpi_device(dev); | ||
235 | struct acpi_power_meter_resource *resource = acpi_dev->driver_data; | ||
236 | union acpi_object arg0 = { ACPI_TYPE_INTEGER }; | ||
237 | struct acpi_object_list args = { 1, &arg0 }; | ||
238 | int res; | ||
239 | unsigned long temp; | ||
240 | unsigned long long data; | ||
241 | acpi_status status; | ||
242 | |||
243 | res = strict_strtoul(buf, 10, &temp); | ||
244 | if (res) | ||
245 | return res; | ||
246 | |||
247 | temp /= 1000; | ||
248 | if (temp > resource->caps.max_cap || temp < resource->caps.min_cap) | ||
249 | return -EINVAL; | ||
250 | arg0.integer.value = temp; | ||
251 | |||
252 | mutex_lock(&resource->lock); | ||
253 | status = acpi_evaluate_integer(resource->acpi_dev->handle, "_SHL", | ||
254 | &args, &data); | ||
255 | if (!ACPI_FAILURE(status)) | ||
256 | resource->cap = temp; | ||
257 | mutex_unlock(&resource->lock); | ||
258 | |||
259 | if (ACPI_FAILURE(status)) { | ||
260 | ACPI_EXCEPTION((AE_INFO, status, "Evaluating _SHL")); | ||
261 | return -EINVAL; | ||
262 | } | ||
263 | |||
264 | /* _SHL returns 0 on success, nonzero otherwise */ | ||
265 | if (data) | ||
266 | return -EINVAL; | ||
267 | |||
268 | return count; | ||
269 | } | ||
270 | |||
271 | /* Power meter trip points */ | ||
272 | static int set_acpi_trip(struct acpi_power_meter_resource *resource) | ||
273 | { | ||
274 | union acpi_object arg_objs[] = { | ||
275 | {ACPI_TYPE_INTEGER}, | ||
276 | {ACPI_TYPE_INTEGER} | ||
277 | }; | ||
278 | struct acpi_object_list args = { 2, arg_objs }; | ||
279 | unsigned long long data; | ||
280 | acpi_status status; | ||
281 | |||
282 | /* Both trip levels must be set */ | ||
283 | if (resource->trip[0] < 0 || resource->trip[1] < 0) | ||
284 | return 0; | ||
285 | |||
286 | /* This driver stores min, max; ACPI wants max, min. */ | ||
287 | arg_objs[0].integer.value = resource->trip[1]; | ||
288 | arg_objs[1].integer.value = resource->trip[0]; | ||
289 | |||
290 | status = acpi_evaluate_integer(resource->acpi_dev->handle, "_PTP", | ||
291 | &args, &data); | ||
292 | if (ACPI_FAILURE(status)) { | ||
293 | ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PTP")); | ||
294 | return -EINVAL; | ||
295 | } | ||
296 | |||
297 | return data; | ||
298 | } | ||
299 | |||
300 | static ssize_t set_trip(struct device *dev, struct device_attribute *devattr, | ||
301 | const char *buf, size_t count) | ||
302 | { | ||
303 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
304 | struct acpi_device *acpi_dev = to_acpi_device(dev); | ||
305 | struct acpi_power_meter_resource *resource = acpi_dev->driver_data; | ||
306 | int res; | ||
307 | unsigned long temp; | ||
308 | |||
309 | res = strict_strtoul(buf, 10, &temp); | ||
310 | if (res) | ||
311 | return res; | ||
312 | |||
313 | temp /= 1000; | ||
314 | if (temp < 0) | ||
315 | return -EINVAL; | ||
316 | |||
317 | mutex_lock(&resource->lock); | ||
318 | resource->trip[attr->index - 7] = temp; | ||
319 | res = set_acpi_trip(resource); | ||
320 | mutex_unlock(&resource->lock); | ||
321 | |||
322 | if (res) | ||
323 | return res; | ||
324 | |||
325 | return count; | ||
326 | } | ||
327 | |||
328 | /* Power meter */ | ||
329 | static int update_meter(struct acpi_power_meter_resource *resource) | ||
330 | { | ||
331 | unsigned long long data; | ||
332 | acpi_status status; | ||
333 | unsigned long local_jiffies = jiffies; | ||
334 | |||
335 | if (time_before(local_jiffies, resource->sensors_last_updated + | ||
336 | msecs_to_jiffies(resource->caps.sampling_time)) && | ||
337 | resource->sensors_valid) | ||
338 | return 0; | ||
339 | |||
340 | status = acpi_evaluate_integer(resource->acpi_dev->handle, "_PMM", | ||
341 | NULL, &data); | ||
342 | if (ACPI_FAILURE(status)) { | ||
343 | ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PMM")); | ||
344 | return -ENODEV; | ||
345 | } | ||
346 | |||
347 | resource->power = data; | ||
348 | resource->sensors_valid = 1; | ||
349 | resource->sensors_last_updated = jiffies; | ||
350 | return 0; | ||
351 | } | ||
352 | |||
353 | static ssize_t show_power(struct device *dev, | ||
354 | struct device_attribute *devattr, | ||
355 | char *buf) | ||
356 | { | ||
357 | struct acpi_device *acpi_dev = to_acpi_device(dev); | ||
358 | struct acpi_power_meter_resource *resource = acpi_dev->driver_data; | ||
359 | |||
360 | mutex_lock(&resource->lock); | ||
361 | update_meter(resource); | ||
362 | mutex_unlock(&resource->lock); | ||
363 | |||
364 | return sprintf(buf, "%llu\n", resource->power * 1000); | ||
365 | } | ||
366 | |||
367 | /* Miscellaneous */ | ||
368 | static ssize_t show_str(struct device *dev, | ||
369 | struct device_attribute *devattr, | ||
370 | char *buf) | ||
371 | { | ||
372 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
373 | struct acpi_device *acpi_dev = to_acpi_device(dev); | ||
374 | struct acpi_power_meter_resource *resource = acpi_dev->driver_data; | ||
375 | acpi_string val; | ||
376 | |||
377 | switch (attr->index) { | ||
378 | case 0: | ||
379 | val = resource->model_number; | ||
380 | break; | ||
381 | case 1: | ||
382 | val = resource->serial_number; | ||
383 | break; | ||
384 | case 2: | ||
385 | val = resource->oem_info; | ||
386 | break; | ||
387 | default: | ||
388 | BUG(); | ||
389 | } | ||
390 | |||
391 | return sprintf(buf, "%s\n", val); | ||
392 | } | ||
393 | |||
394 | static ssize_t show_val(struct device *dev, | ||
395 | struct device_attribute *devattr, | ||
396 | char *buf) | ||
397 | { | ||
398 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
399 | struct acpi_device *acpi_dev = to_acpi_device(dev); | ||
400 | struct acpi_power_meter_resource *resource = acpi_dev->driver_data; | ||
401 | acpi_integer val = 0; | ||
402 | |||
403 | switch (attr->index) { | ||
404 | case 0: | ||
405 | val = resource->caps.min_avg_interval; | ||
406 | break; | ||
407 | case 1: | ||
408 | val = resource->caps.max_avg_interval; | ||
409 | break; | ||
410 | case 2: | ||
411 | val = resource->caps.min_cap * 1000; | ||
412 | break; | ||
413 | case 3: | ||
414 | val = resource->caps.max_cap * 1000; | ||
415 | break; | ||
416 | case 4: | ||
417 | if (resource->caps.hysteresis == UNKNOWN_HYSTERESIS) | ||
418 | return sprintf(buf, "unknown\n"); | ||
419 | |||
420 | val = resource->caps.hysteresis * 1000; | ||
421 | break; | ||
422 | case 5: | ||
423 | if (resource->caps.flags & POWER_METER_IS_BATTERY) | ||
424 | val = 1; | ||
425 | else | ||
426 | val = 0; | ||
427 | break; | ||
428 | case 6: | ||
429 | if (resource->power > resource->cap) | ||
430 | val = 1; | ||
431 | else | ||
432 | val = 0; | ||
433 | break; | ||
434 | case 7: | ||
435 | case 8: | ||
436 | if (resource->trip[attr->index - 7] < 0) | ||
437 | return sprintf(buf, "unknown\n"); | ||
438 | |||
439 | val = resource->trip[attr->index - 7] * 1000; | ||
440 | break; | ||
441 | default: | ||
442 | BUG(); | ||
443 | } | ||
444 | |||
445 | return sprintf(buf, "%llu\n", val); | ||
446 | } | ||
447 | |||
448 | static ssize_t show_accuracy(struct device *dev, | ||
449 | struct device_attribute *devattr, | ||
450 | char *buf) | ||
451 | { | ||
452 | struct acpi_device *acpi_dev = to_acpi_device(dev); | ||
453 | struct acpi_power_meter_resource *resource = acpi_dev->driver_data; | ||
454 | unsigned int acc = resource->caps.accuracy; | ||
455 | |||
456 | return sprintf(buf, "%u.%u%%\n", acc / 1000, acc % 1000); | ||
457 | } | ||
458 | |||
459 | static ssize_t show_name(struct device *dev, | ||
460 | struct device_attribute *devattr, | ||
461 | char *buf) | ||
462 | { | ||
463 | return sprintf(buf, "%s\n", ACPI_POWER_METER_NAME); | ||
464 | } | ||
465 | |||
466 | /* Sensor descriptions. If you add a sensor, update NUM_SENSORS above! */ | ||
467 | static struct ro_sensor_template meter_ro_attrs[] = { | ||
468 | {POWER_AVERAGE_NAME, show_power, 0}, | ||
469 | {"power1_accuracy", show_accuracy, 0}, | ||
470 | {"power1_average_interval_min", show_val, 0}, | ||
471 | {"power1_average_interval_max", show_val, 1}, | ||
472 | {"power1_is_battery", show_val, 5}, | ||
473 | {NULL, NULL, 0}, | ||
474 | }; | ||
475 | |||
476 | static struct rw_sensor_template meter_rw_attrs[] = { | ||
477 | {POWER_AVG_INTERVAL_NAME, show_avg_interval, set_avg_interval, 0}, | ||
478 | {NULL, NULL, NULL, 0}, | ||
479 | }; | ||
480 | |||
481 | static struct ro_sensor_template misc_cap_attrs[] = { | ||
482 | {"power1_cap_min", show_val, 2}, | ||
483 | {"power1_cap_max", show_val, 3}, | ||
484 | {"power1_cap_hyst", show_val, 4}, | ||
485 | {POWER_ALARM_NAME, show_val, 6}, | ||
486 | {NULL, NULL, 0}, | ||
487 | }; | ||
488 | |||
489 | static struct ro_sensor_template ro_cap_attrs[] = { | ||
490 | {POWER_CAP_NAME, show_cap, 0}, | ||
491 | {NULL, NULL, 0}, | ||
492 | }; | ||
493 | |||
494 | static struct rw_sensor_template rw_cap_attrs[] = { | ||
495 | {POWER_CAP_NAME, show_cap, set_cap, 0}, | ||
496 | {NULL, NULL, NULL, 0}, | ||
497 | }; | ||
498 | |||
499 | static struct rw_sensor_template trip_attrs[] = { | ||
500 | {"power1_average_min", show_val, set_trip, 7}, | ||
501 | {"power1_average_max", show_val, set_trip, 8}, | ||
502 | {NULL, NULL, NULL, 0}, | ||
503 | }; | ||
504 | |||
505 | static struct ro_sensor_template misc_attrs[] = { | ||
506 | {"name", show_name, 0}, | ||
507 | {"power1_model_number", show_str, 0}, | ||
508 | {"power1_oem_info", show_str, 2}, | ||
509 | {"power1_serial_number", show_str, 1}, | ||
510 | {NULL, NULL, 0}, | ||
511 | }; | ||
512 | |||
513 | /* Read power domain data */ | ||
514 | static void remove_domain_devices(struct acpi_power_meter_resource *resource) | ||
515 | { | ||
516 | int i; | ||
517 | |||
518 | if (!resource->num_domain_devices) | ||
519 | return; | ||
520 | |||
521 | for (i = 0; i < resource->num_domain_devices; i++) { | ||
522 | struct acpi_device *obj = resource->domain_devices[i]; | ||
523 | if (!obj) | ||
524 | continue; | ||
525 | |||
526 | sysfs_remove_link(resource->holders_dir, | ||
527 | kobject_name(&obj->dev.kobj)); | ||
528 | put_device(&obj->dev); | ||
529 | } | ||
530 | |||
531 | kfree(resource->domain_devices); | ||
532 | kobject_put(resource->holders_dir); | ||
533 | } | ||
534 | |||
535 | static int read_domain_devices(struct acpi_power_meter_resource *resource) | ||
536 | { | ||
537 | int res = 0; | ||
538 | int i; | ||
539 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
540 | union acpi_object *pss; | ||
541 | acpi_status status; | ||
542 | |||
543 | status = acpi_evaluate_object(resource->acpi_dev->handle, "_PMD", NULL, | ||
544 | &buffer); | ||
545 | if (ACPI_FAILURE(status)) { | ||
546 | ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PMD")); | ||
547 | return -ENODEV; | ||
548 | } | ||
549 | |||
550 | pss = buffer.pointer; | ||
551 | if (!pss || | ||
552 | pss->type != ACPI_TYPE_PACKAGE) { | ||
553 | dev_err(&resource->acpi_dev->dev, ACPI_POWER_METER_NAME | ||
554 | "Invalid _PMD data\n"); | ||
555 | res = -EFAULT; | ||
556 | goto end; | ||
557 | } | ||
558 | |||
559 | if (!pss->package.count) | ||
560 | goto end; | ||
561 | |||
562 | resource->domain_devices = kzalloc(sizeof(struct acpi_device *) * | ||
563 | pss->package.count, GFP_KERNEL); | ||
564 | if (!resource->domain_devices) { | ||
565 | res = -ENOMEM; | ||
566 | goto end; | ||
567 | } | ||
568 | |||
569 | resource->holders_dir = kobject_create_and_add("measures", | ||
570 | &resource->acpi_dev->dev.kobj); | ||
571 | if (!resource->holders_dir) { | ||
572 | res = -ENOMEM; | ||
573 | goto exit_free; | ||
574 | } | ||
575 | |||
576 | resource->num_domain_devices = pss->package.count; | ||
577 | |||
578 | for (i = 0; i < pss->package.count; i++) { | ||
579 | struct acpi_device *obj; | ||
580 | union acpi_object *element = &(pss->package.elements[i]); | ||
581 | |||
582 | /* Refuse non-references */ | ||
583 | if (element->type != ACPI_TYPE_LOCAL_REFERENCE) | ||
584 | continue; | ||
585 | |||
586 | /* Create a symlink to domain objects */ | ||
587 | resource->domain_devices[i] = NULL; | ||
588 | status = acpi_bus_get_device(element->reference.handle, | ||
589 | &resource->domain_devices[i]); | ||
590 | if (ACPI_FAILURE(status)) | ||
591 | continue; | ||
592 | |||
593 | obj = resource->domain_devices[i]; | ||
594 | get_device(&obj->dev); | ||
595 | |||
596 | res = sysfs_create_link(resource->holders_dir, &obj->dev.kobj, | ||
597 | kobject_name(&obj->dev.kobj)); | ||
598 | if (res) { | ||
599 | put_device(&obj->dev); | ||
600 | resource->domain_devices[i] = NULL; | ||
601 | } | ||
602 | } | ||
603 | |||
604 | res = 0; | ||
605 | goto end; | ||
606 | |||
607 | exit_free: | ||
608 | kfree(resource->domain_devices); | ||
609 | end: | ||
610 | kfree(buffer.pointer); | ||
611 | return res; | ||
612 | } | ||
613 | |||
614 | /* Registration and deregistration */ | ||
615 | static int register_ro_attrs(struct acpi_power_meter_resource *resource, | ||
616 | struct ro_sensor_template *ro) | ||
617 | { | ||
618 | struct device *dev = &resource->acpi_dev->dev; | ||
619 | struct sensor_device_attribute *sensors = | ||
620 | &resource->sensors[resource->num_sensors]; | ||
621 | int res = 0; | ||
622 | |||
623 | while (ro->label) { | ||
624 | sensors->dev_attr.attr.name = ro->label; | ||
625 | sensors->dev_attr.attr.mode = S_IRUGO; | ||
626 | sensors->dev_attr.show = ro->show; | ||
627 | sensors->index = ro->index; | ||
628 | |||
629 | res = device_create_file(dev, &sensors->dev_attr); | ||
630 | if (res) { | ||
631 | sensors->dev_attr.attr.name = NULL; | ||
632 | goto error; | ||
633 | } | ||
634 | sensors++; | ||
635 | resource->num_sensors++; | ||
636 | ro++; | ||
637 | } | ||
638 | |||
639 | error: | ||
640 | return res; | ||
641 | } | ||
642 | |||
643 | static int register_rw_attrs(struct acpi_power_meter_resource *resource, | ||
644 | struct rw_sensor_template *rw) | ||
645 | { | ||
646 | struct device *dev = &resource->acpi_dev->dev; | ||
647 | struct sensor_device_attribute *sensors = | ||
648 | &resource->sensors[resource->num_sensors]; | ||
649 | int res = 0; | ||
650 | |||
651 | while (rw->label) { | ||
652 | sensors->dev_attr.attr.name = rw->label; | ||
653 | sensors->dev_attr.attr.mode = S_IRUGO | S_IWUSR; | ||
654 | sensors->dev_attr.show = rw->show; | ||
655 | sensors->dev_attr.store = rw->set; | ||
656 | sensors->index = rw->index; | ||
657 | |||
658 | res = device_create_file(dev, &sensors->dev_attr); | ||
659 | if (res) { | ||
660 | sensors->dev_attr.attr.name = NULL; | ||
661 | goto error; | ||
662 | } | ||
663 | sensors++; | ||
664 | resource->num_sensors++; | ||
665 | rw++; | ||
666 | } | ||
667 | |||
668 | error: | ||
669 | return res; | ||
670 | } | ||
671 | |||
672 | static void remove_attrs(struct acpi_power_meter_resource *resource) | ||
673 | { | ||
674 | int i; | ||
675 | |||
676 | for (i = 0; i < resource->num_sensors; i++) { | ||
677 | if (!resource->sensors[i].dev_attr.attr.name) | ||
678 | continue; | ||
679 | device_remove_file(&resource->acpi_dev->dev, | ||
680 | &resource->sensors[i].dev_attr); | ||
681 | } | ||
682 | |||
683 | remove_domain_devices(resource); | ||
684 | |||
685 | resource->num_sensors = 0; | ||
686 | } | ||
687 | |||
688 | static int setup_attrs(struct acpi_power_meter_resource *resource) | ||
689 | { | ||
690 | int res = 0; | ||
691 | |||
692 | res = read_domain_devices(resource); | ||
693 | if (res) | ||
694 | return res; | ||
695 | |||
696 | if (resource->caps.flags & POWER_METER_CAN_MEASURE) { | ||
697 | res = register_ro_attrs(resource, meter_ro_attrs); | ||
698 | if (res) | ||
699 | goto error; | ||
700 | res = register_rw_attrs(resource, meter_rw_attrs); | ||
701 | if (res) | ||
702 | goto error; | ||
703 | } | ||
704 | |||
705 | if (resource->caps.flags & POWER_METER_CAN_CAP) { | ||
706 | if (!can_cap_in_hardware()) { | ||
707 | dev_err(&resource->acpi_dev->dev, | ||
708 | "Ignoring unsafe software power cap!\n"); | ||
709 | goto skip_unsafe_cap; | ||
710 | } | ||
711 | |||
712 | if (resource->caps.configurable_cap) { | ||
713 | res = register_rw_attrs(resource, rw_cap_attrs); | ||
714 | if (res) | ||
715 | goto error; | ||
716 | } else { | ||
717 | res = register_ro_attrs(resource, ro_cap_attrs); | ||
718 | if (res) | ||
719 | goto error; | ||
720 | } | ||
721 | res = register_ro_attrs(resource, misc_cap_attrs); | ||
722 | if (res) | ||
723 | goto error; | ||
724 | } | ||
725 | skip_unsafe_cap: | ||
726 | |||
727 | if (resource->caps.flags & POWER_METER_CAN_TRIP) { | ||
728 | res = register_rw_attrs(resource, trip_attrs); | ||
729 | if (res) | ||
730 | goto error; | ||
731 | } | ||
732 | |||
733 | res = register_ro_attrs(resource, misc_attrs); | ||
734 | if (res) | ||
735 | goto error; | ||
736 | |||
737 | return res; | ||
738 | error: | ||
739 | remove_domain_devices(resource); | ||
740 | remove_attrs(resource); | ||
741 | return res; | ||
742 | } | ||
743 | |||
744 | static void free_capabilities(struct acpi_power_meter_resource *resource) | ||
745 | { | ||
746 | acpi_string *str; | ||
747 | int i; | ||
748 | |||
749 | str = &resource->model_number; | ||
750 | for (i = 0; i < 3; i++, str++) | ||
751 | kfree(*str); | ||
752 | } | ||
753 | |||
754 | static int read_capabilities(struct acpi_power_meter_resource *resource) | ||
755 | { | ||
756 | int res = 0; | ||
757 | int i; | ||
758 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
759 | struct acpi_buffer state = { 0, NULL }; | ||
760 | struct acpi_buffer format = { sizeof("NNNNNNNNNNN"), "NNNNNNNNNNN" }; | ||
761 | union acpi_object *pss; | ||
762 | acpi_string *str; | ||
763 | acpi_status status; | ||
764 | |||
765 | status = acpi_evaluate_object(resource->acpi_dev->handle, "_PMC", NULL, | ||
766 | &buffer); | ||
767 | if (ACPI_FAILURE(status)) { | ||
768 | ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PMC")); | ||
769 | return -ENODEV; | ||
770 | } | ||
771 | |||
772 | pss = buffer.pointer; | ||
773 | if (!pss || | ||
774 | pss->type != ACPI_TYPE_PACKAGE || | ||
775 | pss->package.count != 14) { | ||
776 | dev_err(&resource->acpi_dev->dev, ACPI_POWER_METER_NAME | ||
777 | "Invalid _PMC data\n"); | ||
778 | res = -EFAULT; | ||
779 | goto end; | ||
780 | } | ||
781 | |||
782 | /* Grab all the integer data at once */ | ||
783 | state.length = sizeof(struct acpi_power_meter_capabilities); | ||
784 | state.pointer = &resource->caps; | ||
785 | |||
786 | status = acpi_extract_package(pss, &format, &state); | ||
787 | if (ACPI_FAILURE(status)) { | ||
788 | ACPI_EXCEPTION((AE_INFO, status, "Invalid data")); | ||
789 | res = -EFAULT; | ||
790 | goto end; | ||
791 | } | ||
792 | |||
793 | if (resource->caps.units) { | ||
794 | dev_err(&resource->acpi_dev->dev, ACPI_POWER_METER_NAME | ||
795 | "Unknown units %llu.\n", | ||
796 | resource->caps.units); | ||
797 | res = -EINVAL; | ||
798 | goto end; | ||
799 | } | ||
800 | |||
801 | /* Grab the string data */ | ||
802 | str = &resource->model_number; | ||
803 | |||
804 | for (i = 11; i < 14; i++) { | ||
805 | union acpi_object *element = &(pss->package.elements[i]); | ||
806 | |||
807 | if (element->type != ACPI_TYPE_STRING) { | ||
808 | res = -EINVAL; | ||
809 | goto error; | ||
810 | } | ||
811 | |||
812 | *str = kzalloc(sizeof(u8) * (element->string.length + 1), | ||
813 | GFP_KERNEL); | ||
814 | if (!*str) { | ||
815 | res = -ENOMEM; | ||
816 | goto error; | ||
817 | } | ||
818 | |||
819 | strncpy(*str, element->string.pointer, element->string.length); | ||
820 | str++; | ||
821 | } | ||
822 | |||
823 | dev_info(&resource->acpi_dev->dev, "Found ACPI power meter.\n"); | ||
824 | goto end; | ||
825 | error: | ||
826 | str = &resource->model_number; | ||
827 | for (i = 0; i < 3; i++, str++) | ||
828 | kfree(*str); | ||
829 | end: | ||
830 | kfree(buffer.pointer); | ||
831 | return res; | ||
832 | } | ||
833 | |||
834 | /* Handle ACPI event notifications */ | ||
835 | static void acpi_power_meter_notify(struct acpi_device *device, u32 event) | ||
836 | { | ||
837 | struct acpi_power_meter_resource *resource; | ||
838 | int res; | ||
839 | |||
840 | if (!device || !acpi_driver_data(device)) | ||
841 | return; | ||
842 | |||
843 | resource = acpi_driver_data(device); | ||
844 | |||
845 | mutex_lock(&resource->lock); | ||
846 | switch (event) { | ||
847 | case METER_NOTIFY_CONFIG: | ||
848 | free_capabilities(resource); | ||
849 | res = read_capabilities(resource); | ||
850 | if (res) | ||
851 | break; | ||
852 | |||
853 | remove_attrs(resource); | ||
854 | setup_attrs(resource); | ||
855 | break; | ||
856 | case METER_NOTIFY_TRIP: | ||
857 | sysfs_notify(&device->dev.kobj, NULL, POWER_AVERAGE_NAME); | ||
858 | update_meter(resource); | ||
859 | break; | ||
860 | case METER_NOTIFY_CAP: | ||
861 | sysfs_notify(&device->dev.kobj, NULL, POWER_CAP_NAME); | ||
862 | update_cap(resource); | ||
863 | break; | ||
864 | case METER_NOTIFY_INTERVAL: | ||
865 | sysfs_notify(&device->dev.kobj, NULL, POWER_AVG_INTERVAL_NAME); | ||
866 | update_avg_interval(resource); | ||
867 | break; | ||
868 | case METER_NOTIFY_CAPPING: | ||
869 | sysfs_notify(&device->dev.kobj, NULL, POWER_ALARM_NAME); | ||
870 | dev_info(&device->dev, "Capping in progress.\n"); | ||
871 | break; | ||
872 | default: | ||
873 | BUG(); | ||
874 | } | ||
875 | mutex_unlock(&resource->lock); | ||
876 | |||
877 | acpi_bus_generate_netlink_event(ACPI_POWER_METER_CLASS, | ||
878 | dev_name(&device->dev), event, 0); | ||
879 | } | ||
880 | |||
881 | static int acpi_power_meter_add(struct acpi_device *device) | ||
882 | { | ||
883 | int res; | ||
884 | struct acpi_power_meter_resource *resource; | ||
885 | |||
886 | if (!device) | ||
887 | return -EINVAL; | ||
888 | |||
889 | resource = kzalloc(sizeof(struct acpi_power_meter_resource), | ||
890 | GFP_KERNEL); | ||
891 | if (!resource) | ||
892 | return -ENOMEM; | ||
893 | |||
894 | resource->sensors_valid = 0; | ||
895 | resource->acpi_dev = device; | ||
896 | mutex_init(&resource->lock); | ||
897 | strcpy(acpi_device_name(device), ACPI_POWER_METER_DEVICE_NAME); | ||
898 | strcpy(acpi_device_class(device), ACPI_POWER_METER_CLASS); | ||
899 | device->driver_data = resource; | ||
900 | |||
901 | free_capabilities(resource); | ||
902 | res = read_capabilities(resource); | ||
903 | if (res) | ||
904 | goto exit_free; | ||
905 | |||
906 | resource->trip[0] = resource->trip[1] = -1; | ||
907 | |||
908 | res = setup_attrs(resource); | ||
909 | if (res) | ||
910 | goto exit_free; | ||
911 | |||
912 | resource->hwmon_dev = hwmon_device_register(&device->dev); | ||
913 | if (IS_ERR(resource->hwmon_dev)) { | ||
914 | res = PTR_ERR(resource->hwmon_dev); | ||
915 | goto exit_remove; | ||
916 | } | ||
917 | |||
918 | res = 0; | ||
919 | goto exit; | ||
920 | |||
921 | exit_remove: | ||
922 | remove_attrs(resource); | ||
923 | exit_free: | ||
924 | kfree(resource); | ||
925 | exit: | ||
926 | return res; | ||
927 | } | ||
928 | |||
929 | static int acpi_power_meter_remove(struct acpi_device *device, int type) | ||
930 | { | ||
931 | struct acpi_power_meter_resource *resource; | ||
932 | |||
933 | if (!device || !acpi_driver_data(device)) | ||
934 | return -EINVAL; | ||
935 | |||
936 | resource = acpi_driver_data(device); | ||
937 | hwmon_device_unregister(resource->hwmon_dev); | ||
938 | |||
939 | free_capabilities(resource); | ||
940 | remove_attrs(resource); | ||
941 | |||
942 | kfree(resource); | ||
943 | return 0; | ||
944 | } | ||
945 | |||
946 | static int acpi_power_meter_resume(struct acpi_device *device) | ||
947 | { | ||
948 | struct acpi_power_meter_resource *resource; | ||
949 | |||
950 | if (!device || !acpi_driver_data(device)) | ||
951 | return -EINVAL; | ||
952 | |||
953 | resource = acpi_driver_data(device); | ||
954 | free_capabilities(resource); | ||
955 | read_capabilities(resource); | ||
956 | |||
957 | return 0; | ||
958 | } | ||
959 | |||
960 | static struct acpi_driver acpi_power_meter_driver = { | ||
961 | .name = "power_meter", | ||
962 | .class = ACPI_POWER_METER_CLASS, | ||
963 | .ids = power_meter_ids, | ||
964 | .ops = { | ||
965 | .add = acpi_power_meter_add, | ||
966 | .remove = acpi_power_meter_remove, | ||
967 | .resume = acpi_power_meter_resume, | ||
968 | .notify = acpi_power_meter_notify, | ||
969 | }, | ||
970 | }; | ||
971 | |||
972 | /* Module init/exit routines */ | ||
973 | static int __init enable_cap_knobs(const struct dmi_system_id *d) | ||
974 | { | ||
975 | cap_in_hardware = 1; | ||
976 | return 0; | ||
977 | } | ||
978 | |||
979 | static struct dmi_system_id __initdata pm_dmi_table[] = { | ||
980 | { | ||
981 | enable_cap_knobs, "IBM Active Energy Manager", | ||
982 | { | ||
983 | DMI_MATCH(DMI_SYS_VENDOR, "IBM") | ||
984 | }, | ||
985 | }, | ||
986 | {} | ||
987 | }; | ||
988 | |||
989 | static int __init acpi_power_meter_init(void) | ||
990 | { | ||
991 | int result; | ||
992 | |||
993 | if (acpi_disabled) | ||
994 | return -ENODEV; | ||
995 | |||
996 | dmi_check_system(pm_dmi_table); | ||
997 | |||
998 | result = acpi_bus_register_driver(&acpi_power_meter_driver); | ||
999 | if (result < 0) | ||
1000 | return -ENODEV; | ||
1001 | |||
1002 | return 0; | ||
1003 | } | ||
1004 | |||
1005 | static void __exit acpi_power_meter_exit(void) | ||
1006 | { | ||
1007 | acpi_bus_unregister_driver(&acpi_power_meter_driver); | ||
1008 | } | ||
1009 | |||
1010 | MODULE_AUTHOR("Darrick J. Wong <djwong@us.ibm.com>"); | ||
1011 | MODULE_DESCRIPTION("ACPI 4.0 power meter driver"); | ||
1012 | MODULE_LICENSE("GPL"); | ||
1013 | |||
1014 | module_param(force_cap_on, bool, 0644); | ||
1015 | MODULE_PARM_DESC(force_cap_on, "Enable power cap even it is unsafe to do so."); | ||
1016 | |||
1017 | module_init(acpi_power_meter_init); | ||
1018 | module_exit(acpi_power_meter_exit); | ||
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index 1b166c1be167..c2d4d6e09364 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c | |||
@@ -59,6 +59,8 @@ | |||
59 | #include <acpi/acpi_drivers.h> | 59 | #include <acpi/acpi_drivers.h> |
60 | #include <acpi/processor.h> | 60 | #include <acpi/processor.h> |
61 | 61 | ||
62 | #define PREFIX "ACPI: " | ||
63 | |||
62 | #define ACPI_PROCESSOR_CLASS "processor" | 64 | #define ACPI_PROCESSOR_CLASS "processor" |
63 | #define ACPI_PROCESSOR_DEVICE_NAME "Processor" | 65 | #define ACPI_PROCESSOR_DEVICE_NAME "Processor" |
64 | #define ACPI_PROCESSOR_FILE_INFO "info" | 66 | #define ACPI_PROCESSOR_FILE_INFO "info" |
@@ -79,7 +81,6 @@ MODULE_DESCRIPTION("ACPI Processor Driver"); | |||
79 | MODULE_LICENSE("GPL"); | 81 | MODULE_LICENSE("GPL"); |
80 | 82 | ||
81 | static int acpi_processor_add(struct acpi_device *device); | 83 | static int acpi_processor_add(struct acpi_device *device); |
82 | static int acpi_processor_start(struct acpi_device *device); | ||
83 | static int acpi_processor_remove(struct acpi_device *device, int type); | 84 | static int acpi_processor_remove(struct acpi_device *device, int type); |
84 | #ifdef CONFIG_ACPI_PROCFS | 85 | #ifdef CONFIG_ACPI_PROCFS |
85 | static int acpi_processor_info_open_fs(struct inode *inode, struct file *file); | 86 | static int acpi_processor_info_open_fs(struct inode *inode, struct file *file); |
@@ -91,7 +92,7 @@ static int acpi_processor_handle_eject(struct acpi_processor *pr); | |||
91 | 92 | ||
92 | static const struct acpi_device_id processor_device_ids[] = { | 93 | static const struct acpi_device_id processor_device_ids[] = { |
93 | {ACPI_PROCESSOR_OBJECT_HID, 0}, | 94 | {ACPI_PROCESSOR_OBJECT_HID, 0}, |
94 | {ACPI_PROCESSOR_HID, 0}, | 95 | {"ACPI0007", 0}, |
95 | {"", 0}, | 96 | {"", 0}, |
96 | }; | 97 | }; |
97 | MODULE_DEVICE_TABLE(acpi, processor_device_ids); | 98 | MODULE_DEVICE_TABLE(acpi, processor_device_ids); |
@@ -103,7 +104,6 @@ static struct acpi_driver acpi_processor_driver = { | |||
103 | .ops = { | 104 | .ops = { |
104 | .add = acpi_processor_add, | 105 | .add = acpi_processor_add, |
105 | .remove = acpi_processor_remove, | 106 | .remove = acpi_processor_remove, |
106 | .start = acpi_processor_start, | ||
107 | .suspend = acpi_processor_suspend, | 107 | .suspend = acpi_processor_suspend, |
108 | .resume = acpi_processor_resume, | 108 | .resume = acpi_processor_resume, |
109 | .notify = acpi_processor_notify, | 109 | .notify = acpi_processor_notify, |
@@ -609,7 +609,21 @@ static int acpi_processor_get_info(struct acpi_device *device) | |||
609 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 609 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
610 | "No bus mastering arbitration control\n")); | 610 | "No bus mastering arbitration control\n")); |
611 | 611 | ||
612 | if (!strcmp(acpi_device_hid(device), ACPI_PROCESSOR_HID)) { | 612 | if (!strcmp(acpi_device_hid(device), ACPI_PROCESSOR_OBJECT_HID)) { |
613 | /* Declared with "Processor" statement; match ProcessorID */ | ||
614 | status = acpi_evaluate_object(pr->handle, NULL, NULL, &buffer); | ||
615 | if (ACPI_FAILURE(status)) { | ||
616 | printk(KERN_ERR PREFIX "Evaluating processor object\n"); | ||
617 | return -ENODEV; | ||
618 | } | ||
619 | |||
620 | /* | ||
621 | * TBD: Synch processor ID (via LAPIC/LSAPIC structures) on SMP. | ||
622 | * >>> 'acpi_get_processor_id(acpi_id, &id)' in | ||
623 | * arch/xxx/acpi.c | ||
624 | */ | ||
625 | pr->acpi_id = object.processor.proc_id; | ||
626 | } else { | ||
613 | /* | 627 | /* |
614 | * Declared with "Device" statement; match _UID. | 628 | * Declared with "Device" statement; match _UID. |
615 | * Note that we don't handle string _UIDs yet. | 629 | * Note that we don't handle string _UIDs yet. |
@@ -624,20 +638,6 @@ static int acpi_processor_get_info(struct acpi_device *device) | |||
624 | } | 638 | } |
625 | device_declaration = 1; | 639 | device_declaration = 1; |
626 | pr->acpi_id = value; | 640 | pr->acpi_id = value; |
627 | } else { | ||
628 | /* Declared with "Processor" statement; match ProcessorID */ | ||
629 | status = acpi_evaluate_object(pr->handle, NULL, NULL, &buffer); | ||
630 | if (ACPI_FAILURE(status)) { | ||
631 | printk(KERN_ERR PREFIX "Evaluating processor object\n"); | ||
632 | return -ENODEV; | ||
633 | } | ||
634 | |||
635 | /* | ||
636 | * TBD: Synch processor ID (via LAPIC/LSAPIC structures) on SMP. | ||
637 | * >>> 'acpi_get_processor_id(acpi_id, &id)' in | ||
638 | * arch/xxx/acpi.c | ||
639 | */ | ||
640 | pr->acpi_id = object.processor.proc_id; | ||
641 | } | 641 | } |
642 | cpu_index = get_cpu_id(pr->handle, device_declaration, pr->acpi_id); | 642 | cpu_index = get_cpu_id(pr->handle, device_declaration, pr->acpi_id); |
643 | 643 | ||
@@ -662,7 +662,16 @@ static int acpi_processor_get_info(struct acpi_device *device) | |||
662 | return -ENODEV; | 662 | return -ENODEV; |
663 | } | 663 | } |
664 | } | 664 | } |
665 | 665 | /* | |
666 | * On some boxes several processors use the same processor bus id. | ||
667 | * But they are located in different scope. For example: | ||
668 | * \_SB.SCK0.CPU0 | ||
669 | * \_SB.SCK1.CPU0 | ||
670 | * Rename the processor device bus id. And the new bus id will be | ||
671 | * generated as the following format: | ||
672 | * CPU+CPU ID. | ||
673 | */ | ||
674 | sprintf(acpi_device_bid(device), "CPU%X", pr->id); | ||
666 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Processor [%d:%d]\n", pr->id, | 675 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Processor [%d:%d]\n", pr->id, |
667 | pr->acpi_id)); | 676 | pr->acpi_id)); |
668 | 677 | ||
@@ -702,90 +711,6 @@ static int acpi_processor_get_info(struct acpi_device *device) | |||
702 | 711 | ||
703 | static DEFINE_PER_CPU(void *, processor_device_array); | 712 | static DEFINE_PER_CPU(void *, processor_device_array); |
704 | 713 | ||
705 | static int __cpuinit acpi_processor_start(struct acpi_device *device) | ||
706 | { | ||
707 | int result = 0; | ||
708 | struct acpi_processor *pr; | ||
709 | struct sys_device *sysdev; | ||
710 | |||
711 | pr = acpi_driver_data(device); | ||
712 | |||
713 | result = acpi_processor_get_info(device); | ||
714 | if (result) { | ||
715 | /* Processor is physically not present */ | ||
716 | return 0; | ||
717 | } | ||
718 | |||
719 | BUG_ON((pr->id >= nr_cpu_ids) || (pr->id < 0)); | ||
720 | |||
721 | /* | ||
722 | * Buggy BIOS check | ||
723 | * ACPI id of processors can be reported wrongly by the BIOS. | ||
724 | * Don't trust it blindly | ||
725 | */ | ||
726 | if (per_cpu(processor_device_array, pr->id) != NULL && | ||
727 | per_cpu(processor_device_array, pr->id) != device) { | ||
728 | printk(KERN_WARNING "BIOS reported wrong ACPI id " | ||
729 | "for the processor\n"); | ||
730 | return -ENODEV; | ||
731 | } | ||
732 | per_cpu(processor_device_array, pr->id) = device; | ||
733 | |||
734 | per_cpu(processors, pr->id) = pr; | ||
735 | |||
736 | result = acpi_processor_add_fs(device); | ||
737 | if (result) | ||
738 | goto end; | ||
739 | |||
740 | sysdev = get_cpu_sysdev(pr->id); | ||
741 | if (sysfs_create_link(&device->dev.kobj, &sysdev->kobj, "sysdev")) | ||
742 | return -EFAULT; | ||
743 | |||
744 | /* _PDC call should be done before doing anything else (if reqd.). */ | ||
745 | arch_acpi_processor_init_pdc(pr); | ||
746 | acpi_processor_set_pdc(pr); | ||
747 | #ifdef CONFIG_CPU_FREQ | ||
748 | acpi_processor_ppc_has_changed(pr); | ||
749 | #endif | ||
750 | acpi_processor_get_throttling_info(pr); | ||
751 | acpi_processor_get_limit_info(pr); | ||
752 | |||
753 | |||
754 | acpi_processor_power_init(pr, device); | ||
755 | |||
756 | pr->cdev = thermal_cooling_device_register("Processor", device, | ||
757 | &processor_cooling_ops); | ||
758 | if (IS_ERR(pr->cdev)) { | ||
759 | result = PTR_ERR(pr->cdev); | ||
760 | goto end; | ||
761 | } | ||
762 | |||
763 | dev_info(&device->dev, "registered as cooling_device%d\n", | ||
764 | pr->cdev->id); | ||
765 | |||
766 | result = sysfs_create_link(&device->dev.kobj, | ||
767 | &pr->cdev->device.kobj, | ||
768 | "thermal_cooling"); | ||
769 | if (result) | ||
770 | printk(KERN_ERR PREFIX "Create sysfs link\n"); | ||
771 | result = sysfs_create_link(&pr->cdev->device.kobj, | ||
772 | &device->dev.kobj, | ||
773 | "device"); | ||
774 | if (result) | ||
775 | printk(KERN_ERR PREFIX "Create sysfs link\n"); | ||
776 | |||
777 | if (pr->flags.throttling) { | ||
778 | printk(KERN_INFO PREFIX "%s [%s] (supports", | ||
779 | acpi_device_name(device), acpi_device_bid(device)); | ||
780 | printk(" %d throttling states", pr->throttling.state_count); | ||
781 | printk(")\n"); | ||
782 | } | ||
783 | |||
784 | end: | ||
785 | |||
786 | return result; | ||
787 | } | ||
788 | |||
789 | static void acpi_processor_notify(struct acpi_device *device, u32 event) | 714 | static void acpi_processor_notify(struct acpi_device *device, u32 event) |
790 | { | 715 | { |
791 | struct acpi_processor *pr = acpi_driver_data(device); | 716 | struct acpi_processor *pr = acpi_driver_data(device); |
@@ -848,10 +773,8 @@ static struct notifier_block acpi_cpu_notifier = | |||
848 | static int acpi_processor_add(struct acpi_device *device) | 773 | static int acpi_processor_add(struct acpi_device *device) |
849 | { | 774 | { |
850 | struct acpi_processor *pr = NULL; | 775 | struct acpi_processor *pr = NULL; |
851 | 776 | int result = 0; | |
852 | 777 | struct sys_device *sysdev; | |
853 | if (!device) | ||
854 | return -EINVAL; | ||
855 | 778 | ||
856 | pr = kzalloc(sizeof(struct acpi_processor), GFP_KERNEL); | 779 | pr = kzalloc(sizeof(struct acpi_processor), GFP_KERNEL); |
857 | if (!pr) | 780 | if (!pr) |
@@ -867,7 +790,100 @@ static int acpi_processor_add(struct acpi_device *device) | |||
867 | strcpy(acpi_device_class(device), ACPI_PROCESSOR_CLASS); | 790 | strcpy(acpi_device_class(device), ACPI_PROCESSOR_CLASS); |
868 | device->driver_data = pr; | 791 | device->driver_data = pr; |
869 | 792 | ||
793 | result = acpi_processor_get_info(device); | ||
794 | if (result) { | ||
795 | /* Processor is physically not present */ | ||
796 | return 0; | ||
797 | } | ||
798 | |||
799 | BUG_ON((pr->id >= nr_cpu_ids) || (pr->id < 0)); | ||
800 | |||
801 | /* | ||
802 | * Buggy BIOS check | ||
803 | * ACPI id of processors can be reported wrongly by the BIOS. | ||
804 | * Don't trust it blindly | ||
805 | */ | ||
806 | if (per_cpu(processor_device_array, pr->id) != NULL && | ||
807 | per_cpu(processor_device_array, pr->id) != device) { | ||
808 | printk(KERN_WARNING "BIOS reported wrong ACPI id " | ||
809 | "for the processor\n"); | ||
810 | result = -ENODEV; | ||
811 | goto err_free_cpumask; | ||
812 | } | ||
813 | per_cpu(processor_device_array, pr->id) = device; | ||
814 | |||
815 | per_cpu(processors, pr->id) = pr; | ||
816 | |||
817 | result = acpi_processor_add_fs(device); | ||
818 | if (result) | ||
819 | goto err_free_cpumask; | ||
820 | |||
821 | sysdev = get_cpu_sysdev(pr->id); | ||
822 | if (sysfs_create_link(&device->dev.kobj, &sysdev->kobj, "sysdev")) { | ||
823 | result = -EFAULT; | ||
824 | goto err_remove_fs; | ||
825 | } | ||
826 | |||
827 | /* _PDC call should be done before doing anything else (if reqd.). */ | ||
828 | arch_acpi_processor_init_pdc(pr); | ||
829 | acpi_processor_set_pdc(pr); | ||
830 | arch_acpi_processor_cleanup_pdc(pr); | ||
831 | |||
832 | #ifdef CONFIG_CPU_FREQ | ||
833 | acpi_processor_ppc_has_changed(pr); | ||
834 | #endif | ||
835 | acpi_processor_get_throttling_info(pr); | ||
836 | acpi_processor_get_limit_info(pr); | ||
837 | |||
838 | |||
839 | acpi_processor_power_init(pr, device); | ||
840 | |||
841 | pr->cdev = thermal_cooling_device_register("Processor", device, | ||
842 | &processor_cooling_ops); | ||
843 | if (IS_ERR(pr->cdev)) { | ||
844 | result = PTR_ERR(pr->cdev); | ||
845 | goto err_power_exit; | ||
846 | } | ||
847 | |||
848 | dev_info(&device->dev, "registered as cooling_device%d\n", | ||
849 | pr->cdev->id); | ||
850 | |||
851 | result = sysfs_create_link(&device->dev.kobj, | ||
852 | &pr->cdev->device.kobj, | ||
853 | "thermal_cooling"); | ||
854 | if (result) { | ||
855 | printk(KERN_ERR PREFIX "Create sysfs link\n"); | ||
856 | goto err_thermal_unregister; | ||
857 | } | ||
858 | result = sysfs_create_link(&pr->cdev->device.kobj, | ||
859 | &device->dev.kobj, | ||
860 | "device"); | ||
861 | if (result) { | ||
862 | printk(KERN_ERR PREFIX "Create sysfs link\n"); | ||
863 | goto err_remove_sysfs; | ||
864 | } | ||
865 | |||
866 | if (pr->flags.throttling) { | ||
867 | printk(KERN_INFO PREFIX "%s [%s] (supports", | ||
868 | acpi_device_name(device), acpi_device_bid(device)); | ||
869 | printk(" %d throttling states", pr->throttling.state_count); | ||
870 | printk(")\n"); | ||
871 | } | ||
872 | |||
870 | return 0; | 873 | return 0; |
874 | |||
875 | err_remove_sysfs: | ||
876 | sysfs_remove_link(&device->dev.kobj, "thermal_cooling"); | ||
877 | err_thermal_unregister: | ||
878 | thermal_cooling_device_unregister(pr->cdev); | ||
879 | err_power_exit: | ||
880 | acpi_processor_power_exit(pr, device); | ||
881 | err_remove_fs: | ||
882 | acpi_processor_remove_fs(device); | ||
883 | err_free_cpumask: | ||
884 | free_cpumask_var(pr->throttling.shared_cpu_map); | ||
885 | |||
886 | return result; | ||
871 | } | 887 | } |
872 | 888 | ||
873 | static int acpi_processor_remove(struct acpi_device *device, int type) | 889 | static int acpi_processor_remove(struct acpi_device *device, int type) |
@@ -944,7 +960,6 @@ int acpi_processor_device_add(acpi_handle handle, struct acpi_device **device) | |||
944 | { | 960 | { |
945 | acpi_handle phandle; | 961 | acpi_handle phandle; |
946 | struct acpi_device *pdev; | 962 | struct acpi_device *pdev; |
947 | struct acpi_processor *pr; | ||
948 | 963 | ||
949 | 964 | ||
950 | if (acpi_get_parent(handle, &phandle)) { | 965 | if (acpi_get_parent(handle, &phandle)) { |
@@ -959,15 +974,6 @@ int acpi_processor_device_add(acpi_handle handle, struct acpi_device **device) | |||
959 | return -ENODEV; | 974 | return -ENODEV; |
960 | } | 975 | } |
961 | 976 | ||
962 | acpi_bus_start(*device); | ||
963 | |||
964 | pr = acpi_driver_data(*device); | ||
965 | if (!pr) | ||
966 | return -ENODEV; | ||
967 | |||
968 | if ((pr->id >= 0) && (pr->id < nr_cpu_ids)) { | ||
969 | kobject_uevent(&(*device)->dev.kobj, KOBJ_ONLINE); | ||
970 | } | ||
971 | return 0; | 977 | return 0; |
972 | } | 978 | } |
973 | 979 | ||
@@ -997,25 +1003,6 @@ static void __ref acpi_processor_hotplug_notify(acpi_handle handle, | |||
997 | "Unable to add the device\n"); | 1003 | "Unable to add the device\n"); |
998 | break; | 1004 | break; |
999 | } | 1005 | } |
1000 | |||
1001 | pr = acpi_driver_data(device); | ||
1002 | if (!pr) { | ||
1003 | printk(KERN_ERR PREFIX "Driver data is NULL\n"); | ||
1004 | break; | ||
1005 | } | ||
1006 | |||
1007 | if (pr->id >= 0 && (pr->id < nr_cpu_ids)) { | ||
1008 | kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE); | ||
1009 | break; | ||
1010 | } | ||
1011 | |||
1012 | result = acpi_processor_start(device); | ||
1013 | if ((!result) && ((pr->id >= 0) && (pr->id < nr_cpu_ids))) { | ||
1014 | kobject_uevent(&device->dev.kobj, KOBJ_ONLINE); | ||
1015 | } else { | ||
1016 | printk(KERN_ERR PREFIX "Device [%s] failed to start\n", | ||
1017 | acpi_device_bid(device)); | ||
1018 | } | ||
1019 | break; | 1006 | break; |
1020 | case ACPI_NOTIFY_EJECT_REQUEST: | 1007 | case ACPI_NOTIFY_EJECT_REQUEST: |
1021 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 1008 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
@@ -1032,9 +1019,6 @@ static void __ref acpi_processor_hotplug_notify(acpi_handle handle, | |||
1032 | "Driver data is NULL, dropping EJECT\n"); | 1019 | "Driver data is NULL, dropping EJECT\n"); |
1033 | return; | 1020 | return; |
1034 | } | 1021 | } |
1035 | |||
1036 | if ((pr->id < nr_cpu_ids) && (cpu_present(pr->id))) | ||
1037 | kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE); | ||
1038 | break; | 1022 | break; |
1039 | default: | 1023 | default: |
1040 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 1024 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
@@ -1153,6 +1137,9 @@ static int __init acpi_processor_init(void) | |||
1153 | { | 1137 | { |
1154 | int result = 0; | 1138 | int result = 0; |
1155 | 1139 | ||
1140 | if (acpi_disabled) | ||
1141 | return 0; | ||
1142 | |||
1156 | memset(&errata, 0, sizeof(errata)); | 1143 | memset(&errata, 0, sizeof(errata)); |
1157 | 1144 | ||
1158 | #ifdef CONFIG_SMP | 1145 | #ifdef CONFIG_SMP |
@@ -1201,6 +1188,9 @@ out_proc: | |||
1201 | 1188 | ||
1202 | static void __exit acpi_processor_exit(void) | 1189 | static void __exit acpi_processor_exit(void) |
1203 | { | 1190 | { |
1191 | if (acpi_disabled) | ||
1192 | return; | ||
1193 | |||
1204 | acpi_processor_ppc_exit(); | 1194 | acpi_processor_ppc_exit(); |
1205 | 1195 | ||
1206 | acpi_thermal_cpufreq_exit(); | 1196 | acpi_thermal_cpufreq_exit(); |
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index b85d9f022716..cc61a6220102 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c | |||
@@ -60,6 +60,8 @@ | |||
60 | #include <acpi/processor.h> | 60 | #include <acpi/processor.h> |
61 | #include <asm/processor.h> | 61 | #include <asm/processor.h> |
62 | 62 | ||
63 | #define PREFIX "ACPI: " | ||
64 | |||
63 | #define ACPI_PROCESSOR_CLASS "processor" | 65 | #define ACPI_PROCESSOR_CLASS "processor" |
64 | #define _COMPONENT ACPI_PROCESSOR_COMPONENT | 66 | #define _COMPONENT ACPI_PROCESSOR_COMPONENT |
65 | ACPI_MODULE_NAME("processor_idle"); | 67 | ACPI_MODULE_NAME("processor_idle"); |
@@ -139,7 +141,7 @@ static void acpi_safe_halt(void) | |||
139 | * are affected too. We pick the most conservative approach: we assume | 141 | * are affected too. We pick the most conservative approach: we assume |
140 | * that the local APIC stops in both C2 and C3. | 142 | * that the local APIC stops in both C2 and C3. |
141 | */ | 143 | */ |
142 | static void acpi_timer_check_state(int state, struct acpi_processor *pr, | 144 | static void lapic_timer_check_state(int state, struct acpi_processor *pr, |
143 | struct acpi_processor_cx *cx) | 145 | struct acpi_processor_cx *cx) |
144 | { | 146 | { |
145 | struct acpi_processor_power *pwr = &pr->power; | 147 | struct acpi_processor_power *pwr = &pr->power; |
@@ -162,8 +164,9 @@ static void acpi_timer_check_state(int state, struct acpi_processor *pr, | |||
162 | pr->power.timer_broadcast_on_state = state; | 164 | pr->power.timer_broadcast_on_state = state; |
163 | } | 165 | } |
164 | 166 | ||
165 | static void acpi_propagate_timer_broadcast(struct acpi_processor *pr) | 167 | static void lapic_timer_propagate_broadcast(void *arg) |
166 | { | 168 | { |
169 | struct acpi_processor *pr = (struct acpi_processor *) arg; | ||
167 | unsigned long reason; | 170 | unsigned long reason; |
168 | 171 | ||
169 | reason = pr->power.timer_broadcast_on_state < INT_MAX ? | 172 | reason = pr->power.timer_broadcast_on_state < INT_MAX ? |
@@ -173,7 +176,7 @@ static void acpi_propagate_timer_broadcast(struct acpi_processor *pr) | |||
173 | } | 176 | } |
174 | 177 | ||
175 | /* Power(C) State timer broadcast control */ | 178 | /* Power(C) State timer broadcast control */ |
176 | static void acpi_state_timer_broadcast(struct acpi_processor *pr, | 179 | static void lapic_timer_state_broadcast(struct acpi_processor *pr, |
177 | struct acpi_processor_cx *cx, | 180 | struct acpi_processor_cx *cx, |
178 | int broadcast) | 181 | int broadcast) |
179 | { | 182 | { |
@@ -190,10 +193,10 @@ static void acpi_state_timer_broadcast(struct acpi_processor *pr, | |||
190 | 193 | ||
191 | #else | 194 | #else |
192 | 195 | ||
193 | static void acpi_timer_check_state(int state, struct acpi_processor *pr, | 196 | static void lapic_timer_check_state(int state, struct acpi_processor *pr, |
194 | struct acpi_processor_cx *cstate) { } | 197 | struct acpi_processor_cx *cstate) { } |
195 | static void acpi_propagate_timer_broadcast(struct acpi_processor *pr) { } | 198 | static void lapic_timer_propagate_broadcast(struct acpi_processor *pr) { } |
196 | static void acpi_state_timer_broadcast(struct acpi_processor *pr, | 199 | static void lapic_timer_state_broadcast(struct acpi_processor *pr, |
197 | struct acpi_processor_cx *cx, | 200 | struct acpi_processor_cx *cx, |
198 | int broadcast) | 201 | int broadcast) |
199 | { | 202 | { |
@@ -515,7 +518,8 @@ static void acpi_processor_power_verify_c2(struct acpi_processor_cx *cx) | |||
515 | static void acpi_processor_power_verify_c3(struct acpi_processor *pr, | 518 | static void acpi_processor_power_verify_c3(struct acpi_processor *pr, |
516 | struct acpi_processor_cx *cx) | 519 | struct acpi_processor_cx *cx) |
517 | { | 520 | { |
518 | static int bm_check_flag; | 521 | static int bm_check_flag = -1; |
522 | static int bm_control_flag = -1; | ||
519 | 523 | ||
520 | 524 | ||
521 | if (!cx->address) | 525 | if (!cx->address) |
@@ -545,12 +549,14 @@ static void acpi_processor_power_verify_c3(struct acpi_processor *pr, | |||
545 | } | 549 | } |
546 | 550 | ||
547 | /* All the logic here assumes flags.bm_check is same across all CPUs */ | 551 | /* All the logic here assumes flags.bm_check is same across all CPUs */ |
548 | if (!bm_check_flag) { | 552 | if (bm_check_flag == -1) { |
549 | /* Determine whether bm_check is needed based on CPU */ | 553 | /* Determine whether bm_check is needed based on CPU */ |
550 | acpi_processor_power_init_bm_check(&(pr->flags), pr->id); | 554 | acpi_processor_power_init_bm_check(&(pr->flags), pr->id); |
551 | bm_check_flag = pr->flags.bm_check; | 555 | bm_check_flag = pr->flags.bm_check; |
556 | bm_control_flag = pr->flags.bm_control; | ||
552 | } else { | 557 | } else { |
553 | pr->flags.bm_check = bm_check_flag; | 558 | pr->flags.bm_check = bm_check_flag; |
559 | pr->flags.bm_control = bm_control_flag; | ||
554 | } | 560 | } |
555 | 561 | ||
556 | if (pr->flags.bm_check) { | 562 | if (pr->flags.bm_check) { |
@@ -614,29 +620,26 @@ static int acpi_processor_power_verify(struct acpi_processor *pr) | |||
614 | switch (cx->type) { | 620 | switch (cx->type) { |
615 | case ACPI_STATE_C1: | 621 | case ACPI_STATE_C1: |
616 | cx->valid = 1; | 622 | cx->valid = 1; |
617 | acpi_timer_check_state(i, pr, cx); | ||
618 | break; | 623 | break; |
619 | 624 | ||
620 | case ACPI_STATE_C2: | 625 | case ACPI_STATE_C2: |
621 | acpi_processor_power_verify_c2(cx); | 626 | acpi_processor_power_verify_c2(cx); |
622 | if (cx->valid) | ||
623 | acpi_timer_check_state(i, pr, cx); | ||
624 | break; | 627 | break; |
625 | 628 | ||
626 | case ACPI_STATE_C3: | 629 | case ACPI_STATE_C3: |
627 | acpi_processor_power_verify_c3(pr, cx); | 630 | acpi_processor_power_verify_c3(pr, cx); |
628 | if (cx->valid) | ||
629 | acpi_timer_check_state(i, pr, cx); | ||
630 | break; | 631 | break; |
631 | } | 632 | } |
632 | if (cx->valid) | 633 | if (!cx->valid) |
633 | tsc_check_state(cx->type); | 634 | continue; |
634 | 635 | ||
635 | if (cx->valid) | 636 | lapic_timer_check_state(i, pr, cx); |
636 | working++; | 637 | tsc_check_state(cx->type); |
638 | working++; | ||
637 | } | 639 | } |
638 | 640 | ||
639 | acpi_propagate_timer_broadcast(pr); | 641 | smp_call_function_single(pr->id, lapic_timer_propagate_broadcast, |
642 | pr, 1); | ||
640 | 643 | ||
641 | return (working); | 644 | return (working); |
642 | } | 645 | } |
@@ -840,7 +843,7 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev, | |||
840 | return 0; | 843 | return 0; |
841 | } | 844 | } |
842 | 845 | ||
843 | acpi_state_timer_broadcast(pr, cx, 1); | 846 | lapic_timer_state_broadcast(pr, cx, 1); |
844 | kt1 = ktime_get_real(); | 847 | kt1 = ktime_get_real(); |
845 | acpi_idle_do_entry(cx); | 848 | acpi_idle_do_entry(cx); |
846 | kt2 = ktime_get_real(); | 849 | kt2 = ktime_get_real(); |
@@ -848,7 +851,7 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev, | |||
848 | 851 | ||
849 | local_irq_enable(); | 852 | local_irq_enable(); |
850 | cx->usage++; | 853 | cx->usage++; |
851 | acpi_state_timer_broadcast(pr, cx, 0); | 854 | lapic_timer_state_broadcast(pr, cx, 0); |
852 | 855 | ||
853 | return idle_time; | 856 | return idle_time; |
854 | } | 857 | } |
@@ -893,7 +896,7 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, | |||
893 | * Must be done before busmaster disable as we might need to | 896 | * Must be done before busmaster disable as we might need to |
894 | * access HPET ! | 897 | * access HPET ! |
895 | */ | 898 | */ |
896 | acpi_state_timer_broadcast(pr, cx, 1); | 899 | lapic_timer_state_broadcast(pr, cx, 1); |
897 | 900 | ||
898 | if (cx->type == ACPI_STATE_C3) | 901 | if (cx->type == ACPI_STATE_C3) |
899 | ACPI_FLUSH_CPU_CACHE(); | 902 | ACPI_FLUSH_CPU_CACHE(); |
@@ -915,7 +918,7 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, | |||
915 | 918 | ||
916 | cx->usage++; | 919 | cx->usage++; |
917 | 920 | ||
918 | acpi_state_timer_broadcast(pr, cx, 0); | 921 | lapic_timer_state_broadcast(pr, cx, 0); |
919 | cx->time += sleep_ticks; | 922 | cx->time += sleep_ticks; |
920 | return idle_time; | 923 | return idle_time; |
921 | } | 924 | } |
@@ -982,7 +985,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, | |||
982 | * Must be done before busmaster disable as we might need to | 985 | * Must be done before busmaster disable as we might need to |
983 | * access HPET ! | 986 | * access HPET ! |
984 | */ | 987 | */ |
985 | acpi_state_timer_broadcast(pr, cx, 1); | 988 | lapic_timer_state_broadcast(pr, cx, 1); |
986 | 989 | ||
987 | kt1 = ktime_get_real(); | 990 | kt1 = ktime_get_real(); |
988 | /* | 991 | /* |
@@ -1027,7 +1030,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, | |||
1027 | 1030 | ||
1028 | cx->usage++; | 1031 | cx->usage++; |
1029 | 1032 | ||
1030 | acpi_state_timer_broadcast(pr, cx, 0); | 1033 | lapic_timer_state_broadcast(pr, cx, 0); |
1031 | cx->time += sleep_ticks; | 1034 | cx->time += sleep_ticks; |
1032 | return idle_time; | 1035 | return idle_time; |
1033 | } | 1036 | } |
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index 60e543d3234e..11088cf10319 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c | |||
@@ -39,6 +39,8 @@ | |||
39 | #include <acpi/acpi_drivers.h> | 39 | #include <acpi/acpi_drivers.h> |
40 | #include <acpi/processor.h> | 40 | #include <acpi/processor.h> |
41 | 41 | ||
42 | #define PREFIX "ACPI: " | ||
43 | |||
42 | #define ACPI_PROCESSOR_CLASS "processor" | 44 | #define ACPI_PROCESSOR_CLASS "processor" |
43 | #define ACPI_PROCESSOR_FILE_PERFORMANCE "performance" | 45 | #define ACPI_PROCESSOR_FILE_PERFORMANCE "performance" |
44 | #define _COMPONENT ACPI_PROCESSOR_COMPONENT | 46 | #define _COMPONENT ACPI_PROCESSOR_COMPONENT |
diff --git a/drivers/acpi/processor_thermal.c b/drivers/acpi/processor_thermal.c index 07e26140e977..140c5c5b423c 100644 --- a/drivers/acpi/processor_thermal.c +++ b/drivers/acpi/processor_thermal.c | |||
@@ -40,6 +40,8 @@ | |||
40 | #include <acpi/processor.h> | 40 | #include <acpi/processor.h> |
41 | #include <acpi/acpi_drivers.h> | 41 | #include <acpi/acpi_drivers.h> |
42 | 42 | ||
43 | #define PREFIX "ACPI: " | ||
44 | |||
43 | #define ACPI_PROCESSOR_CLASS "processor" | 45 | #define ACPI_PROCESSOR_CLASS "processor" |
44 | #define _COMPONENT ACPI_PROCESSOR_COMPONENT | 46 | #define _COMPONENT ACPI_PROCESSOR_COMPONENT |
45 | ACPI_MODULE_NAME("processor_thermal"); | 47 | ACPI_MODULE_NAME("processor_thermal"); |
@@ -66,7 +68,7 @@ static int acpi_processor_apply_limit(struct acpi_processor *pr) | |||
66 | if (pr->limit.thermal.tx > tx) | 68 | if (pr->limit.thermal.tx > tx) |
67 | tx = pr->limit.thermal.tx; | 69 | tx = pr->limit.thermal.tx; |
68 | 70 | ||
69 | result = acpi_processor_set_throttling(pr, tx); | 71 | result = acpi_processor_set_throttling(pr, tx, false); |
70 | if (result) | 72 | if (result) |
71 | goto end; | 73 | goto end; |
72 | } | 74 | } |
@@ -421,12 +423,12 @@ processor_set_cur_state(struct thermal_cooling_device *cdev, | |||
421 | 423 | ||
422 | if (state <= max_pstate) { | 424 | if (state <= max_pstate) { |
423 | if (pr->flags.throttling && pr->throttling.state) | 425 | if (pr->flags.throttling && pr->throttling.state) |
424 | result = acpi_processor_set_throttling(pr, 0); | 426 | result = acpi_processor_set_throttling(pr, 0, false); |
425 | cpufreq_set_cur_state(pr->id, state); | 427 | cpufreq_set_cur_state(pr->id, state); |
426 | } else { | 428 | } else { |
427 | cpufreq_set_cur_state(pr->id, max_pstate); | 429 | cpufreq_set_cur_state(pr->id, max_pstate); |
428 | result = acpi_processor_set_throttling(pr, | 430 | result = acpi_processor_set_throttling(pr, |
429 | state - max_pstate); | 431 | state - max_pstate, false); |
430 | } | 432 | } |
431 | return result; | 433 | return result; |
432 | } | 434 | } |
diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c index 16560014f7bd..ce7cf3bc5101 100644 --- a/drivers/acpi/processor_throttling.c +++ b/drivers/acpi/processor_throttling.c | |||
@@ -41,6 +41,8 @@ | |||
41 | #include <acpi/acpi_drivers.h> | 41 | #include <acpi/acpi_drivers.h> |
42 | #include <acpi/processor.h> | 42 | #include <acpi/processor.h> |
43 | 43 | ||
44 | #define PREFIX "ACPI: " | ||
45 | |||
44 | #define ACPI_PROCESSOR_CLASS "processor" | 46 | #define ACPI_PROCESSOR_CLASS "processor" |
45 | #define _COMPONENT ACPI_PROCESSOR_COMPONENT | 47 | #define _COMPONENT ACPI_PROCESSOR_COMPONENT |
46 | ACPI_MODULE_NAME("processor_throttling"); | 48 | ACPI_MODULE_NAME("processor_throttling"); |
@@ -62,7 +64,8 @@ struct throttling_tstate { | |||
62 | #define THROTTLING_POSTCHANGE (2) | 64 | #define THROTTLING_POSTCHANGE (2) |
63 | 65 | ||
64 | static int acpi_processor_get_throttling(struct acpi_processor *pr); | 66 | static int acpi_processor_get_throttling(struct acpi_processor *pr); |
65 | int acpi_processor_set_throttling(struct acpi_processor *pr, int state); | 67 | int acpi_processor_set_throttling(struct acpi_processor *pr, |
68 | int state, bool force); | ||
66 | 69 | ||
67 | static int acpi_processor_update_tsd_coord(void) | 70 | static int acpi_processor_update_tsd_coord(void) |
68 | { | 71 | { |
@@ -361,7 +364,7 @@ int acpi_processor_tstate_has_changed(struct acpi_processor *pr) | |||
361 | */ | 364 | */ |
362 | target_state = throttling_limit; | 365 | target_state = throttling_limit; |
363 | } | 366 | } |
364 | return acpi_processor_set_throttling(pr, target_state); | 367 | return acpi_processor_set_throttling(pr, target_state, false); |
365 | } | 368 | } |
366 | 369 | ||
367 | /* | 370 | /* |
@@ -839,10 +842,10 @@ static int acpi_processor_get_throttling_ptc(struct acpi_processor *pr) | |||
839 | if (ret >= 0) { | 842 | if (ret >= 0) { |
840 | state = acpi_get_throttling_state(pr, value); | 843 | state = acpi_get_throttling_state(pr, value); |
841 | if (state == -1) { | 844 | if (state == -1) { |
842 | ACPI_WARNING((AE_INFO, | 845 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
843 | "Invalid throttling state, reset")); | 846 | "Invalid throttling state, reset\n")); |
844 | state = 0; | 847 | state = 0; |
845 | ret = acpi_processor_set_throttling(pr, state); | 848 | ret = acpi_processor_set_throttling(pr, state, true); |
846 | if (ret) | 849 | if (ret) |
847 | return ret; | 850 | return ret; |
848 | } | 851 | } |
@@ -915,7 +918,7 @@ static int acpi_processor_get_fadt_info(struct acpi_processor *pr) | |||
915 | } | 918 | } |
916 | 919 | ||
917 | static int acpi_processor_set_throttling_fadt(struct acpi_processor *pr, | 920 | static int acpi_processor_set_throttling_fadt(struct acpi_processor *pr, |
918 | int state) | 921 | int state, bool force) |
919 | { | 922 | { |
920 | u32 value = 0; | 923 | u32 value = 0; |
921 | u32 duty_mask = 0; | 924 | u32 duty_mask = 0; |
@@ -930,7 +933,7 @@ static int acpi_processor_set_throttling_fadt(struct acpi_processor *pr, | |||
930 | if (!pr->flags.throttling) | 933 | if (!pr->flags.throttling) |
931 | return -ENODEV; | 934 | return -ENODEV; |
932 | 935 | ||
933 | if (state == pr->throttling.state) | 936 | if (!force && (state == pr->throttling.state)) |
934 | return 0; | 937 | return 0; |
935 | 938 | ||
936 | if (state < pr->throttling_platform_limit) | 939 | if (state < pr->throttling_platform_limit) |
@@ -988,7 +991,7 @@ static int acpi_processor_set_throttling_fadt(struct acpi_processor *pr, | |||
988 | } | 991 | } |
989 | 992 | ||
990 | static int acpi_processor_set_throttling_ptc(struct acpi_processor *pr, | 993 | static int acpi_processor_set_throttling_ptc(struct acpi_processor *pr, |
991 | int state) | 994 | int state, bool force) |
992 | { | 995 | { |
993 | int ret; | 996 | int ret; |
994 | acpi_integer value; | 997 | acpi_integer value; |
@@ -1002,7 +1005,7 @@ static int acpi_processor_set_throttling_ptc(struct acpi_processor *pr, | |||
1002 | if (!pr->flags.throttling) | 1005 | if (!pr->flags.throttling) |
1003 | return -ENODEV; | 1006 | return -ENODEV; |
1004 | 1007 | ||
1005 | if (state == pr->throttling.state) | 1008 | if (!force && (state == pr->throttling.state)) |
1006 | return 0; | 1009 | return 0; |
1007 | 1010 | ||
1008 | if (state < pr->throttling_platform_limit) | 1011 | if (state < pr->throttling_platform_limit) |
@@ -1018,7 +1021,8 @@ static int acpi_processor_set_throttling_ptc(struct acpi_processor *pr, | |||
1018 | return 0; | 1021 | return 0; |
1019 | } | 1022 | } |
1020 | 1023 | ||
1021 | int acpi_processor_set_throttling(struct acpi_processor *pr, int state) | 1024 | int acpi_processor_set_throttling(struct acpi_processor *pr, |
1025 | int state, bool force) | ||
1022 | { | 1026 | { |
1023 | cpumask_var_t saved_mask; | 1027 | cpumask_var_t saved_mask; |
1024 | int ret = 0; | 1028 | int ret = 0; |
@@ -1070,7 +1074,7 @@ int acpi_processor_set_throttling(struct acpi_processor *pr, int state) | |||
1070 | /* FIXME: use work_on_cpu() */ | 1074 | /* FIXME: use work_on_cpu() */ |
1071 | set_cpus_allowed_ptr(current, cpumask_of(pr->id)); | 1075 | set_cpus_allowed_ptr(current, cpumask_of(pr->id)); |
1072 | ret = p_throttling->acpi_processor_set_throttling(pr, | 1076 | ret = p_throttling->acpi_processor_set_throttling(pr, |
1073 | t_state.target_state); | 1077 | t_state.target_state, force); |
1074 | } else { | 1078 | } else { |
1075 | /* | 1079 | /* |
1076 | * When the T-state coordination is SW_ALL or HW_ALL, | 1080 | * When the T-state coordination is SW_ALL or HW_ALL, |
@@ -1103,7 +1107,7 @@ int acpi_processor_set_throttling(struct acpi_processor *pr, int state) | |||
1103 | set_cpus_allowed_ptr(current, cpumask_of(i)); | 1107 | set_cpus_allowed_ptr(current, cpumask_of(i)); |
1104 | ret = match_pr->throttling. | 1108 | ret = match_pr->throttling. |
1105 | acpi_processor_set_throttling( | 1109 | acpi_processor_set_throttling( |
1106 | match_pr, t_state.target_state); | 1110 | match_pr, t_state.target_state, force); |
1107 | } | 1111 | } |
1108 | } | 1112 | } |
1109 | /* | 1113 | /* |
@@ -1201,7 +1205,7 @@ int acpi_processor_get_throttling_info(struct acpi_processor *pr) | |||
1201 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 1205 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
1202 | "Disabling throttling (was T%d)\n", | 1206 | "Disabling throttling (was T%d)\n", |
1203 | pr->throttling.state)); | 1207 | pr->throttling.state)); |
1204 | result = acpi_processor_set_throttling(pr, 0); | 1208 | result = acpi_processor_set_throttling(pr, 0, false); |
1205 | if (result) | 1209 | if (result) |
1206 | goto end; | 1210 | goto end; |
1207 | } | 1211 | } |
@@ -1307,7 +1311,7 @@ static ssize_t acpi_processor_write_throttling(struct file *file, | |||
1307 | if (strcmp(tmpbuf, charp) != 0) | 1311 | if (strcmp(tmpbuf, charp) != 0) |
1308 | return -EINVAL; | 1312 | return -EINVAL; |
1309 | 1313 | ||
1310 | result = acpi_processor_set_throttling(pr, state_val); | 1314 | result = acpi_processor_set_throttling(pr, state_val, false); |
1311 | if (result) | 1315 | if (result) |
1312 | return result; | 1316 | return result; |
1313 | 1317 | ||
diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c index 4b214b74ebaa..52b9db8afc20 100644 --- a/drivers/acpi/sbs.c +++ b/drivers/acpi/sbs.c | |||
@@ -46,6 +46,8 @@ | |||
46 | 46 | ||
47 | #include "sbshc.h" | 47 | #include "sbshc.h" |
48 | 48 | ||
49 | #define PREFIX "ACPI: " | ||
50 | |||
49 | #define ACPI_SBS_CLASS "sbs" | 51 | #define ACPI_SBS_CLASS "sbs" |
50 | #define ACPI_AC_CLASS "ac_adapter" | 52 | #define ACPI_AC_CLASS "ac_adapter" |
51 | #define ACPI_BATTERY_CLASS "battery" | 53 | #define ACPI_BATTERY_CLASS "battery" |
diff --git a/drivers/acpi/sbshc.c b/drivers/acpi/sbshc.c index 0619734895b2..d9339806df45 100644 --- a/drivers/acpi/sbshc.c +++ b/drivers/acpi/sbshc.c | |||
@@ -15,6 +15,8 @@ | |||
15 | #include <linux/interrupt.h> | 15 | #include <linux/interrupt.h> |
16 | #include "sbshc.h" | 16 | #include "sbshc.h" |
17 | 17 | ||
18 | #define PREFIX "ACPI: " | ||
19 | |||
18 | #define ACPI_SMB_HC_CLASS "smbus_host_controller" | 20 | #define ACPI_SMB_HC_CLASS "smbus_host_controller" |
19 | #define ACPI_SMB_HC_DEVICE_NAME "ACPI SMBus HC" | 21 | #define ACPI_SMB_HC_DEVICE_NAME "ACPI SMBus HC" |
20 | 22 | ||
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 8ff510b91d88..7b90900b2118 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
@@ -60,13 +60,13 @@ static int create_modalias(struct acpi_device *acpi_dev, char *modalias, | |||
60 | } | 60 | } |
61 | 61 | ||
62 | if (acpi_dev->flags.compatible_ids) { | 62 | if (acpi_dev->flags.compatible_ids) { |
63 | struct acpi_compatible_id_list *cid_list; | 63 | struct acpica_device_id_list *cid_list; |
64 | int i; | 64 | int i; |
65 | 65 | ||
66 | cid_list = acpi_dev->pnp.cid_list; | 66 | cid_list = acpi_dev->pnp.cid_list; |
67 | for (i = 0; i < cid_list->count; i++) { | 67 | for (i = 0; i < cid_list->count; i++) { |
68 | count = snprintf(&modalias[len], size, "%s:", | 68 | count = snprintf(&modalias[len], size, "%s:", |
69 | cid_list->id[i].value); | 69 | cid_list->ids[i].string); |
70 | if (count < 0 || count >= size) { | 70 | if (count < 0 || count >= size) { |
71 | printk(KERN_ERR PREFIX "%s cid[%i] exceeds event buffer size", | 71 | printk(KERN_ERR PREFIX "%s cid[%i] exceeds event buffer size", |
72 | acpi_dev->pnp.device_name, i); | 72 | acpi_dev->pnp.device_name, i); |
@@ -95,7 +95,7 @@ acpi_device_modalias_show(struct device *dev, struct device_attribute *attr, cha | |||
95 | } | 95 | } |
96 | static DEVICE_ATTR(modalias, 0444, acpi_device_modalias_show, NULL); | 96 | static DEVICE_ATTR(modalias, 0444, acpi_device_modalias_show, NULL); |
97 | 97 | ||
98 | static int acpi_bus_hot_remove_device(void *context) | 98 | static void acpi_bus_hot_remove_device(void *context) |
99 | { | 99 | { |
100 | struct acpi_device *device; | 100 | struct acpi_device *device; |
101 | acpi_handle handle = context; | 101 | acpi_handle handle = context; |
@@ -104,10 +104,10 @@ static int acpi_bus_hot_remove_device(void *context) | |||
104 | acpi_status status = AE_OK; | 104 | acpi_status status = AE_OK; |
105 | 105 | ||
106 | if (acpi_bus_get_device(handle, &device)) | 106 | if (acpi_bus_get_device(handle, &device)) |
107 | return 0; | 107 | return; |
108 | 108 | ||
109 | if (!device) | 109 | if (!device) |
110 | return 0; | 110 | return; |
111 | 111 | ||
112 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 112 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
113 | "Hot-removing device %s...\n", dev_name(&device->dev))); | 113 | "Hot-removing device %s...\n", dev_name(&device->dev))); |
@@ -115,7 +115,7 @@ static int acpi_bus_hot_remove_device(void *context) | |||
115 | if (acpi_bus_trim(device, 1)) { | 115 | if (acpi_bus_trim(device, 1)) { |
116 | printk(KERN_ERR PREFIX | 116 | printk(KERN_ERR PREFIX |
117 | "Removing device failed\n"); | 117 | "Removing device failed\n"); |
118 | return -1; | 118 | return; |
119 | } | 119 | } |
120 | 120 | ||
121 | /* power off device */ | 121 | /* power off device */ |
@@ -142,9 +142,10 @@ static int acpi_bus_hot_remove_device(void *context) | |||
142 | */ | 142 | */ |
143 | status = acpi_evaluate_object(handle, "_EJ0", &arg_list, NULL); | 143 | status = acpi_evaluate_object(handle, "_EJ0", &arg_list, NULL); |
144 | if (ACPI_FAILURE(status)) | 144 | if (ACPI_FAILURE(status)) |
145 | return -ENODEV; | 145 | printk(KERN_WARNING PREFIX |
146 | "Eject device failed\n"); | ||
146 | 147 | ||
147 | return 0; | 148 | return; |
148 | } | 149 | } |
149 | 150 | ||
150 | static ssize_t | 151 | static ssize_t |
@@ -155,7 +156,6 @@ acpi_eject_store(struct device *d, struct device_attribute *attr, | |||
155 | acpi_status status; | 156 | acpi_status status; |
156 | acpi_object_type type = 0; | 157 | acpi_object_type type = 0; |
157 | struct acpi_device *acpi_device = to_acpi_device(d); | 158 | struct acpi_device *acpi_device = to_acpi_device(d); |
158 | struct task_struct *task; | ||
159 | 159 | ||
160 | if ((!count) || (buf[0] != '1')) { | 160 | if ((!count) || (buf[0] != '1')) { |
161 | return -EINVAL; | 161 | return -EINVAL; |
@@ -172,11 +172,7 @@ acpi_eject_store(struct device *d, struct device_attribute *attr, | |||
172 | goto err; | 172 | goto err; |
173 | } | 173 | } |
174 | 174 | ||
175 | /* remove the device in another thread to fix the deadlock issue */ | 175 | acpi_os_hotplug_execute(acpi_bus_hot_remove_device, acpi_device->handle); |
176 | task = kthread_run(acpi_bus_hot_remove_device, | ||
177 | acpi_device->handle, "acpi_hot_remove_device"); | ||
178 | if (IS_ERR(task)) | ||
179 | ret = PTR_ERR(task); | ||
180 | err: | 176 | err: |
181 | return ret; | 177 | return ret; |
182 | } | 178 | } |
@@ -198,12 +194,12 @@ acpi_device_path_show(struct device *dev, struct device_attribute *attr, char *b | |||
198 | int result; | 194 | int result; |
199 | 195 | ||
200 | result = acpi_get_name(acpi_dev->handle, ACPI_FULL_PATHNAME, &path); | 196 | result = acpi_get_name(acpi_dev->handle, ACPI_FULL_PATHNAME, &path); |
201 | if(result) | 197 | if (result) |
202 | goto end; | 198 | goto end; |
203 | 199 | ||
204 | result = sprintf(buf, "%s\n", (char*)path.pointer); | 200 | result = sprintf(buf, "%s\n", (char*)path.pointer); |
205 | kfree(path.pointer); | 201 | kfree(path.pointer); |
206 | end: | 202 | end: |
207 | return result; | 203 | return result; |
208 | } | 204 | } |
209 | static DEVICE_ATTR(path, 0444, acpi_device_path_show, NULL); | 205 | static DEVICE_ATTR(path, 0444, acpi_device_path_show, NULL); |
@@ -217,21 +213,21 @@ static int acpi_device_setup_files(struct acpi_device *dev) | |||
217 | /* | 213 | /* |
218 | * Devices gotten from FADT don't have a "path" attribute | 214 | * Devices gotten from FADT don't have a "path" attribute |
219 | */ | 215 | */ |
220 | if(dev->handle) { | 216 | if (dev->handle) { |
221 | result = device_create_file(&dev->dev, &dev_attr_path); | 217 | result = device_create_file(&dev->dev, &dev_attr_path); |
222 | if(result) | 218 | if (result) |
223 | goto end; | 219 | goto end; |
224 | } | 220 | } |
225 | 221 | ||
226 | if(dev->flags.hardware_id) { | 222 | if (dev->flags.hardware_id) { |
227 | result = device_create_file(&dev->dev, &dev_attr_hid); | 223 | result = device_create_file(&dev->dev, &dev_attr_hid); |
228 | if(result) | 224 | if (result) |
229 | goto end; | 225 | goto end; |
230 | } | 226 | } |
231 | 227 | ||
232 | if (dev->flags.hardware_id || dev->flags.compatible_ids){ | 228 | if (dev->flags.hardware_id || dev->flags.compatible_ids) { |
233 | result = device_create_file(&dev->dev, &dev_attr_modalias); | 229 | result = device_create_file(&dev->dev, &dev_attr_modalias); |
234 | if(result) | 230 | if (result) |
235 | goto end; | 231 | goto end; |
236 | } | 232 | } |
237 | 233 | ||
@@ -242,7 +238,7 @@ static int acpi_device_setup_files(struct acpi_device *dev) | |||
242 | status = acpi_get_handle(dev->handle, "_EJ0", &temp); | 238 | status = acpi_get_handle(dev->handle, "_EJ0", &temp); |
243 | if (ACPI_SUCCESS(status)) | 239 | if (ACPI_SUCCESS(status)) |
244 | result = device_create_file(&dev->dev, &dev_attr_eject); | 240 | result = device_create_file(&dev->dev, &dev_attr_eject); |
245 | end: | 241 | end: |
246 | return result; | 242 | return result; |
247 | } | 243 | } |
248 | 244 | ||
@@ -262,9 +258,9 @@ static void acpi_device_remove_files(struct acpi_device *dev) | |||
262 | if (dev->flags.hardware_id || dev->flags.compatible_ids) | 258 | if (dev->flags.hardware_id || dev->flags.compatible_ids) |
263 | device_remove_file(&dev->dev, &dev_attr_modalias); | 259 | device_remove_file(&dev->dev, &dev_attr_modalias); |
264 | 260 | ||
265 | if(dev->flags.hardware_id) | 261 | if (dev->flags.hardware_id) |
266 | device_remove_file(&dev->dev, &dev_attr_hid); | 262 | device_remove_file(&dev->dev, &dev_attr_hid); |
267 | if(dev->handle) | 263 | if (dev->handle) |
268 | device_remove_file(&dev->dev, &dev_attr_path); | 264 | device_remove_file(&dev->dev, &dev_attr_path); |
269 | } | 265 | } |
270 | /* -------------------------------------------------------------------------- | 266 | /* -------------------------------------------------------------------------- |
@@ -291,14 +287,14 @@ int acpi_match_device_ids(struct acpi_device *device, | |||
291 | } | 287 | } |
292 | 288 | ||
293 | if (device->flags.compatible_ids) { | 289 | if (device->flags.compatible_ids) { |
294 | struct acpi_compatible_id_list *cid_list = device->pnp.cid_list; | 290 | struct acpica_device_id_list *cid_list = device->pnp.cid_list; |
295 | int i; | 291 | int i; |
296 | 292 | ||
297 | for (id = ids; id->id[0]; id++) { | 293 | for (id = ids; id->id[0]; id++) { |
298 | /* compare multiple _CID entries against driver ids */ | 294 | /* compare multiple _CID entries against driver ids */ |
299 | for (i = 0; i < cid_list->count; i++) { | 295 | for (i = 0; i < cid_list->count; i++) { |
300 | if (!strcmp((char*)id->id, | 296 | if (!strcmp((char*)id->id, |
301 | cid_list->id[i].value)) | 297 | cid_list->ids[i].string)) |
302 | return 0; | 298 | return 0; |
303 | } | 299 | } |
304 | } | 300 | } |
@@ -313,6 +309,10 @@ static void acpi_device_release(struct device *dev) | |||
313 | struct acpi_device *acpi_dev = to_acpi_device(dev); | 309 | struct acpi_device *acpi_dev = to_acpi_device(dev); |
314 | 310 | ||
315 | kfree(acpi_dev->pnp.cid_list); | 311 | kfree(acpi_dev->pnp.cid_list); |
312 | if (acpi_dev->flags.hardware_id) | ||
313 | kfree(acpi_dev->pnp.hardware_id); | ||
314 | if (acpi_dev->flags.unique_id) | ||
315 | kfree(acpi_dev->pnp.unique_id); | ||
316 | kfree(acpi_dev); | 316 | kfree(acpi_dev); |
317 | } | 317 | } |
318 | 318 | ||
@@ -430,9 +430,6 @@ static int acpi_device_probe(struct device * dev) | |||
430 | if (acpi_drv->ops.notify) { | 430 | if (acpi_drv->ops.notify) { |
431 | ret = acpi_device_install_notify_handler(acpi_dev); | 431 | ret = acpi_device_install_notify_handler(acpi_dev); |
432 | if (ret) { | 432 | if (ret) { |
433 | if (acpi_drv->ops.stop) | ||
434 | acpi_drv->ops.stop(acpi_dev, | ||
435 | acpi_dev->removal_type); | ||
436 | if (acpi_drv->ops.remove) | 433 | if (acpi_drv->ops.remove) |
437 | acpi_drv->ops.remove(acpi_dev, | 434 | acpi_drv->ops.remove(acpi_dev, |
438 | acpi_dev->removal_type); | 435 | acpi_dev->removal_type); |
@@ -456,8 +453,6 @@ static int acpi_device_remove(struct device * dev) | |||
456 | if (acpi_drv) { | 453 | if (acpi_drv) { |
457 | if (acpi_drv->ops.notify) | 454 | if (acpi_drv->ops.notify) |
458 | acpi_device_remove_notify_handler(acpi_dev); | 455 | acpi_device_remove_notify_handler(acpi_dev); |
459 | if (acpi_drv->ops.stop) | ||
460 | acpi_drv->ops.stop(acpi_dev, acpi_dev->removal_type); | ||
461 | if (acpi_drv->ops.remove) | 456 | if (acpi_drv->ops.remove) |
462 | acpi_drv->ops.remove(acpi_dev, acpi_dev->removal_type); | 457 | acpi_drv->ops.remove(acpi_dev, acpi_dev->removal_type); |
463 | } | 458 | } |
@@ -512,7 +507,7 @@ static int acpi_device_register(struct acpi_device *device, | |||
512 | break; | 507 | break; |
513 | } | 508 | } |
514 | } | 509 | } |
515 | if(!found) { | 510 | if (!found) { |
516 | acpi_device_bus_id = new_bus_id; | 511 | acpi_device_bus_id = new_bus_id; |
517 | strcpy(acpi_device_bus_id->bus_id, device->flags.hardware_id ? device->pnp.hardware_id : "device"); | 512 | strcpy(acpi_device_bus_id->bus_id, device->flags.hardware_id ? device->pnp.hardware_id : "device"); |
518 | acpi_device_bus_id->instance_no = 0; | 513 | acpi_device_bus_id->instance_no = 0; |
@@ -530,22 +525,21 @@ static int acpi_device_register(struct acpi_device *device, | |||
530 | if (device->parent) | 525 | if (device->parent) |
531 | device->dev.parent = &parent->dev; | 526 | device->dev.parent = &parent->dev; |
532 | device->dev.bus = &acpi_bus_type; | 527 | device->dev.bus = &acpi_bus_type; |
533 | device_initialize(&device->dev); | ||
534 | device->dev.release = &acpi_device_release; | 528 | device->dev.release = &acpi_device_release; |
535 | result = device_add(&device->dev); | 529 | result = device_register(&device->dev); |
536 | if(result) { | 530 | if (result) { |
537 | dev_err(&device->dev, "Error adding device\n"); | 531 | dev_err(&device->dev, "Error registering device\n"); |
538 | goto end; | 532 | goto end; |
539 | } | 533 | } |
540 | 534 | ||
541 | result = acpi_device_setup_files(device); | 535 | result = acpi_device_setup_files(device); |
542 | if(result) | 536 | if (result) |
543 | printk(KERN_ERR PREFIX "Error creating sysfs interface for device %s\n", | 537 | printk(KERN_ERR PREFIX "Error creating sysfs interface for device %s\n", |
544 | dev_name(&device->dev)); | 538 | dev_name(&device->dev)); |
545 | 539 | ||
546 | device->removal_type = ACPI_BUS_REMOVAL_NORMAL; | 540 | device->removal_type = ACPI_BUS_REMOVAL_NORMAL; |
547 | return 0; | 541 | return 0; |
548 | end: | 542 | end: |
549 | mutex_lock(&acpi_device_lock); | 543 | mutex_lock(&acpi_device_lock); |
550 | if (device->parent) | 544 | if (device->parent) |
551 | list_del(&device->node); | 545 | list_del(&device->node); |
@@ -577,7 +571,7 @@ static void acpi_device_unregister(struct acpi_device *device, int type) | |||
577 | * @device: the device to add and initialize | 571 | * @device: the device to add and initialize |
578 | * @driver: driver for the device | 572 | * @driver: driver for the device |
579 | * | 573 | * |
580 | * Used to initialize a device via its device driver. Called whenever a | 574 | * Used to initialize a device via its device driver. Called whenever a |
581 | * driver is bound to a device. Invokes the driver's add() ops. | 575 | * driver is bound to a device. Invokes the driver's add() ops. |
582 | */ | 576 | */ |
583 | static int | 577 | static int |
@@ -585,7 +579,6 @@ acpi_bus_driver_init(struct acpi_device *device, struct acpi_driver *driver) | |||
585 | { | 579 | { |
586 | int result = 0; | 580 | int result = 0; |
587 | 581 | ||
588 | |||
589 | if (!device || !driver) | 582 | if (!device || !driver) |
590 | return -EINVAL; | 583 | return -EINVAL; |
591 | 584 | ||
@@ -693,7 +686,7 @@ acpi_bus_get_ejd(acpi_handle handle, acpi_handle *ejd) | |||
693 | } | 686 | } |
694 | EXPORT_SYMBOL_GPL(acpi_bus_get_ejd); | 687 | EXPORT_SYMBOL_GPL(acpi_bus_get_ejd); |
695 | 688 | ||
696 | void acpi_bus_data_handler(acpi_handle handle, u32 function, void *context) | 689 | void acpi_bus_data_handler(acpi_handle handle, void *context) |
697 | { | 690 | { |
698 | 691 | ||
699 | /* TBD */ | 692 | /* TBD */ |
@@ -787,6 +780,7 @@ static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device) | |||
787 | kfree(buffer.pointer); | 780 | kfree(buffer.pointer); |
788 | 781 | ||
789 | device->wakeup.flags.valid = 1; | 782 | device->wakeup.flags.valid = 1; |
783 | device->wakeup.prepare_count = 0; | ||
790 | /* Call _PSW/_DSW object to disable its ability to wake the sleeping | 784 | /* Call _PSW/_DSW object to disable its ability to wake the sleeping |
791 | * system for the ACPI device with the _PRW object. | 785 | * system for the ACPI device with the _PRW object. |
792 | * The _PSW object is depreciated in ACPI 3.0 and is replaced by _DSW. | 786 | * The _PSW object is depreciated in ACPI 3.0 and is replaced by _DSW. |
@@ -802,7 +796,7 @@ static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device) | |||
802 | if (!acpi_match_device_ids(device, button_device_ids)) | 796 | if (!acpi_match_device_ids(device, button_device_ids)) |
803 | device->wakeup.flags.run_wake = 1; | 797 | device->wakeup.flags.run_wake = 1; |
804 | 798 | ||
805 | end: | 799 | end: |
806 | if (ACPI_FAILURE(status)) | 800 | if (ACPI_FAILURE(status)) |
807 | device->flags.wake_capable = 0; | 801 | device->flags.wake_capable = 0; |
808 | return 0; | 802 | return 0; |
@@ -1005,33 +999,89 @@ static int acpi_dock_match(struct acpi_device *device) | |||
1005 | return acpi_get_handle(device->handle, "_DCK", &tmp); | 999 | return acpi_get_handle(device->handle, "_DCK", &tmp); |
1006 | } | 1000 | } |
1007 | 1001 | ||
1002 | static struct acpica_device_id_list* | ||
1003 | acpi_add_cid( | ||
1004 | struct acpi_device_info *info, | ||
1005 | struct acpica_device_id *new_cid) | ||
1006 | { | ||
1007 | struct acpica_device_id_list *cid; | ||
1008 | char *next_id_string; | ||
1009 | acpi_size cid_length; | ||
1010 | acpi_size new_cid_length; | ||
1011 | u32 i; | ||
1012 | |||
1013 | |||
1014 | /* Allocate new CID list with room for the new CID */ | ||
1015 | |||
1016 | if (!new_cid) | ||
1017 | new_cid_length = info->compatible_id_list.list_size; | ||
1018 | else if (info->compatible_id_list.list_size) | ||
1019 | new_cid_length = info->compatible_id_list.list_size + | ||
1020 | new_cid->length + sizeof(struct acpica_device_id); | ||
1021 | else | ||
1022 | new_cid_length = sizeof(struct acpica_device_id_list) + new_cid->length; | ||
1023 | |||
1024 | cid = ACPI_ALLOCATE_ZEROED(new_cid_length); | ||
1025 | if (!cid) { | ||
1026 | return NULL; | ||
1027 | } | ||
1028 | |||
1029 | cid->list_size = new_cid_length; | ||
1030 | cid->count = info->compatible_id_list.count; | ||
1031 | if (new_cid) | ||
1032 | cid->count++; | ||
1033 | next_id_string = (char *) cid->ids + (cid->count * sizeof(struct acpica_device_id)); | ||
1034 | |||
1035 | /* Copy all existing CIDs */ | ||
1036 | |||
1037 | for (i = 0; i < info->compatible_id_list.count; i++) { | ||
1038 | cid_length = info->compatible_id_list.ids[i].length; | ||
1039 | cid->ids[i].string = next_id_string; | ||
1040 | cid->ids[i].length = cid_length; | ||
1041 | |||
1042 | ACPI_MEMCPY(next_id_string, info->compatible_id_list.ids[i].string, | ||
1043 | cid_length); | ||
1044 | |||
1045 | next_id_string += cid_length; | ||
1046 | } | ||
1047 | |||
1048 | /* Append the new CID */ | ||
1049 | |||
1050 | if (new_cid) { | ||
1051 | cid->ids[i].string = next_id_string; | ||
1052 | cid->ids[i].length = new_cid->length; | ||
1053 | |||
1054 | ACPI_MEMCPY(next_id_string, new_cid->string, new_cid->length); | ||
1055 | } | ||
1056 | |||
1057 | return cid; | ||
1058 | } | ||
1059 | |||
1008 | static void acpi_device_set_id(struct acpi_device *device, | 1060 | static void acpi_device_set_id(struct acpi_device *device, |
1009 | struct acpi_device *parent, acpi_handle handle, | 1061 | struct acpi_device *parent, acpi_handle handle, |
1010 | int type) | 1062 | int type) |
1011 | { | 1063 | { |
1012 | struct acpi_device_info *info; | 1064 | struct acpi_device_info *info = NULL; |
1013 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
1014 | char *hid = NULL; | 1065 | char *hid = NULL; |
1015 | char *uid = NULL; | 1066 | char *uid = NULL; |
1016 | struct acpi_compatible_id_list *cid_list = NULL; | 1067 | struct acpica_device_id_list *cid_list = NULL; |
1017 | const char *cid_add = NULL; | 1068 | char *cid_add = NULL; |
1018 | acpi_status status; | 1069 | acpi_status status; |
1019 | 1070 | ||
1020 | switch (type) { | 1071 | switch (type) { |
1021 | case ACPI_BUS_TYPE_DEVICE: | 1072 | case ACPI_BUS_TYPE_DEVICE: |
1022 | status = acpi_get_object_info(handle, &buffer); | 1073 | status = acpi_get_object_info(handle, &info); |
1023 | if (ACPI_FAILURE(status)) { | 1074 | if (ACPI_FAILURE(status)) { |
1024 | printk(KERN_ERR PREFIX "%s: Error reading device info\n", __func__); | 1075 | printk(KERN_ERR PREFIX "%s: Error reading device info\n", __func__); |
1025 | return; | 1076 | return; |
1026 | } | 1077 | } |
1027 | 1078 | ||
1028 | info = buffer.pointer; | ||
1029 | if (info->valid & ACPI_VALID_HID) | 1079 | if (info->valid & ACPI_VALID_HID) |
1030 | hid = info->hardware_id.value; | 1080 | hid = info->hardware_id.string; |
1031 | if (info->valid & ACPI_VALID_UID) | 1081 | if (info->valid & ACPI_VALID_UID) |
1032 | uid = info->unique_id.value; | 1082 | uid = info->unique_id.string; |
1033 | if (info->valid & ACPI_VALID_CID) | 1083 | if (info->valid & ACPI_VALID_CID) |
1034 | cid_list = &info->compatibility_id; | 1084 | cid_list = &info->compatible_id_list; |
1035 | if (info->valid & ACPI_VALID_ADR) { | 1085 | if (info->valid & ACPI_VALID_ADR) { |
1036 | device->pnp.bus_address = info->address; | 1086 | device->pnp.bus_address = info->address; |
1037 | device->flags.bus_address = 1; | 1087 | device->flags.bus_address = 1; |
@@ -1070,7 +1120,7 @@ static void acpi_device_set_id(struct acpi_device *device, | |||
1070 | break; | 1120 | break; |
1071 | } | 1121 | } |
1072 | 1122 | ||
1073 | /* | 1123 | /* |
1074 | * \_SB | 1124 | * \_SB |
1075 | * ---- | 1125 | * ---- |
1076 | * Fix for the system root bus device -- the only root-level device. | 1126 | * Fix for the system root bus device -- the only root-level device. |
@@ -1082,55 +1132,46 @@ static void acpi_device_set_id(struct acpi_device *device, | |||
1082 | } | 1132 | } |
1083 | 1133 | ||
1084 | if (hid) { | 1134 | if (hid) { |
1085 | strcpy(device->pnp.hardware_id, hid); | 1135 | device->pnp.hardware_id = ACPI_ALLOCATE_ZEROED(strlen (hid) + 1); |
1086 | device->flags.hardware_id = 1; | 1136 | if (device->pnp.hardware_id) { |
1137 | strcpy(device->pnp.hardware_id, hid); | ||
1138 | device->flags.hardware_id = 1; | ||
1139 | } | ||
1087 | } | 1140 | } |
1141 | if (!device->flags.hardware_id) | ||
1142 | device->pnp.hardware_id = ""; | ||
1143 | |||
1088 | if (uid) { | 1144 | if (uid) { |
1089 | strcpy(device->pnp.unique_id, uid); | 1145 | device->pnp.unique_id = ACPI_ALLOCATE_ZEROED(strlen (uid) + 1); |
1090 | device->flags.unique_id = 1; | 1146 | if (device->pnp.unique_id) { |
1147 | strcpy(device->pnp.unique_id, uid); | ||
1148 | device->flags.unique_id = 1; | ||
1149 | } | ||
1091 | } | 1150 | } |
1151 | if (!device->flags.unique_id) | ||
1152 | device->pnp.unique_id = ""; | ||
1153 | |||
1092 | if (cid_list || cid_add) { | 1154 | if (cid_list || cid_add) { |
1093 | struct acpi_compatible_id_list *list; | 1155 | struct acpica_device_id_list *list; |
1094 | int size = 0; | 1156 | |
1095 | int count = 0; | 1157 | if (cid_add) { |
1096 | 1158 | struct acpica_device_id cid; | |
1097 | if (cid_list) { | 1159 | cid.length = strlen (cid_add) + 1; |
1098 | size = cid_list->size; | 1160 | cid.string = cid_add; |
1099 | } else if (cid_add) { | 1161 | |
1100 | size = sizeof(struct acpi_compatible_id_list); | 1162 | list = acpi_add_cid(info, &cid); |
1101 | cid_list = ACPI_ALLOCATE_ZEROED((acpi_size) size); | 1163 | } else { |
1102 | if (!cid_list) { | 1164 | list = acpi_add_cid(info, NULL); |
1103 | printk(KERN_ERR "Memory allocation error\n"); | ||
1104 | kfree(buffer.pointer); | ||
1105 | return; | ||
1106 | } else { | ||
1107 | cid_list->count = 0; | ||
1108 | cid_list->size = size; | ||
1109 | } | ||
1110 | } | 1165 | } |
1111 | if (cid_add) | ||
1112 | size += sizeof(struct acpi_compatible_id); | ||
1113 | list = kmalloc(size, GFP_KERNEL); | ||
1114 | 1166 | ||
1115 | if (list) { | 1167 | if (list) { |
1116 | if (cid_list) { | ||
1117 | memcpy(list, cid_list, cid_list->size); | ||
1118 | count = cid_list->count; | ||
1119 | } | ||
1120 | if (cid_add) { | ||
1121 | strncpy(list->id[count].value, cid_add, | ||
1122 | ACPI_MAX_CID_LENGTH); | ||
1123 | count++; | ||
1124 | device->flags.compatible_ids = 1; | ||
1125 | } | ||
1126 | list->size = size; | ||
1127 | list->count = count; | ||
1128 | device->pnp.cid_list = list; | 1168 | device->pnp.cid_list = list; |
1129 | } else | 1169 | if (cid_add) |
1130 | printk(KERN_ERR PREFIX "Memory allocation error\n"); | 1170 | device->flags.compatible_ids = 1; |
1171 | } | ||
1131 | } | 1172 | } |
1132 | 1173 | ||
1133 | kfree(buffer.pointer); | 1174 | kfree(info); |
1134 | } | 1175 | } |
1135 | 1176 | ||
1136 | static int acpi_device_set_context(struct acpi_device *device, int type) | 1177 | static int acpi_device_set_context(struct acpi_device *device, int type) |
@@ -1270,16 +1311,6 @@ acpi_add_single_object(struct acpi_device **child, | |||
1270 | acpi_device_set_id(device, parent, handle, type); | 1311 | acpi_device_set_id(device, parent, handle, type); |
1271 | 1312 | ||
1272 | /* | 1313 | /* |
1273 | * The ACPI device is attached to acpi handle before getting | ||
1274 | * the power/wakeup/peformance flags. Otherwise OS can't get | ||
1275 | * the corresponding ACPI device by the acpi handle in the course | ||
1276 | * of getting the power/wakeup/performance flags. | ||
1277 | */ | ||
1278 | result = acpi_device_set_context(device, type); | ||
1279 | if (result) | ||
1280 | goto end; | ||
1281 | |||
1282 | /* | ||
1283 | * Power Management | 1314 | * Power Management |
1284 | * ---------------- | 1315 | * ---------------- |
1285 | */ | 1316 | */ |
@@ -1309,6 +1340,8 @@ acpi_add_single_object(struct acpi_device **child, | |||
1309 | goto end; | 1340 | goto end; |
1310 | } | 1341 | } |
1311 | 1342 | ||
1343 | if ((result = acpi_device_set_context(device, type))) | ||
1344 | goto end; | ||
1312 | 1345 | ||
1313 | result = acpi_device_register(device, parent); | 1346 | result = acpi_device_register(device, parent); |
1314 | 1347 | ||
@@ -1320,13 +1353,11 @@ acpi_add_single_object(struct acpi_device **child, | |||
1320 | device->parent->ops.bind(device); | 1353 | device->parent->ops.bind(device); |
1321 | } | 1354 | } |
1322 | 1355 | ||
1323 | end: | 1356 | end: |
1324 | if (!result) | 1357 | if (!result) |
1325 | *child = device; | 1358 | *child = device; |
1326 | else { | 1359 | else |
1327 | kfree(device->pnp.cid_list); | 1360 | acpi_device_release(&device->dev); |
1328 | kfree(device); | ||
1329 | } | ||
1330 | 1361 | ||
1331 | return result; | 1362 | return result; |
1332 | } | 1363 | } |
@@ -1464,7 +1495,6 @@ acpi_bus_add(struct acpi_device **child, | |||
1464 | 1495 | ||
1465 | return result; | 1496 | return result; |
1466 | } | 1497 | } |
1467 | |||
1468 | EXPORT_SYMBOL(acpi_bus_add); | 1498 | EXPORT_SYMBOL(acpi_bus_add); |
1469 | 1499 | ||
1470 | int acpi_bus_start(struct acpi_device *device) | 1500 | int acpi_bus_start(struct acpi_device *device) |
@@ -1484,7 +1514,6 @@ int acpi_bus_start(struct acpi_device *device) | |||
1484 | } | 1514 | } |
1485 | return result; | 1515 | return result; |
1486 | } | 1516 | } |
1487 | |||
1488 | EXPORT_SYMBOL(acpi_bus_start); | 1517 | EXPORT_SYMBOL(acpi_bus_start); |
1489 | 1518 | ||
1490 | int acpi_bus_trim(struct acpi_device *start, int rmdevice) | 1519 | int acpi_bus_trim(struct acpi_device *start, int rmdevice) |
@@ -1542,7 +1571,6 @@ int acpi_bus_trim(struct acpi_device *start, int rmdevice) | |||
1542 | } | 1571 | } |
1543 | EXPORT_SYMBOL_GPL(acpi_bus_trim); | 1572 | EXPORT_SYMBOL_GPL(acpi_bus_trim); |
1544 | 1573 | ||
1545 | |||
1546 | static int acpi_bus_scan_fixed(struct acpi_device *root) | 1574 | static int acpi_bus_scan_fixed(struct acpi_device *root) |
1547 | { | 1575 | { |
1548 | int result = 0; | 1576 | int result = 0; |
@@ -1610,6 +1638,6 @@ int __init acpi_scan_init(void) | |||
1610 | if (result) | 1638 | if (result) |
1611 | acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL); | 1639 | acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL); |
1612 | 1640 | ||
1613 | Done: | 1641 | Done: |
1614 | return result; | 1642 | return result; |
1615 | } | 1643 | } |
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 01574a066534..a90afcc723ab 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c | |||
@@ -397,6 +397,22 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = { | |||
397 | }, | 397 | }, |
398 | }, | 398 | }, |
399 | { | 399 | { |
400 | .callback = init_set_sci_en_on_resume, | ||
401 | .ident = "Hewlett-Packard HP G7000 Notebook PC", | ||
402 | .matches = { | ||
403 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
404 | DMI_MATCH(DMI_PRODUCT_NAME, "HP G7000 Notebook PC"), | ||
405 | }, | ||
406 | }, | ||
407 | { | ||
408 | .callback = init_set_sci_en_on_resume, | ||
409 | .ident = "Hewlett-Packard HP Pavilion dv3 Notebook PC", | ||
410 | .matches = { | ||
411 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
412 | DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv3 Notebook PC"), | ||
413 | }, | ||
414 | }, | ||
415 | { | ||
400 | .callback = init_old_suspend_ordering, | 416 | .callback = init_old_suspend_ordering, |
401 | .ident = "Panasonic CF51-2L", | 417 | .ident = "Panasonic CF51-2L", |
402 | .matches = { | 418 | .matches = { |
@@ -681,19 +697,25 @@ int acpi_pm_device_sleep_wake(struct device *dev, bool enable) | |||
681 | { | 697 | { |
682 | acpi_handle handle; | 698 | acpi_handle handle; |
683 | struct acpi_device *adev; | 699 | struct acpi_device *adev; |
700 | int error; | ||
684 | 701 | ||
685 | if (!device_may_wakeup(dev)) | 702 | if (!device_can_wakeup(dev)) |
686 | return -EINVAL; | 703 | return -EINVAL; |
687 | 704 | ||
688 | handle = DEVICE_ACPI_HANDLE(dev); | 705 | handle = DEVICE_ACPI_HANDLE(dev); |
689 | if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &adev))) { | 706 | if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &adev))) { |
690 | printk(KERN_DEBUG "ACPI handle has no context!\n"); | 707 | dev_dbg(dev, "ACPI handle has no context in %s!\n", __func__); |
691 | return -ENODEV; | 708 | return -ENODEV; |
692 | } | 709 | } |
693 | 710 | ||
694 | return enable ? | 711 | error = enable ? |
695 | acpi_enable_wakeup_device_power(adev, acpi_target_sleep_state) : | 712 | acpi_enable_wakeup_device_power(adev, acpi_target_sleep_state) : |
696 | acpi_disable_wakeup_device_power(adev); | 713 | acpi_disable_wakeup_device_power(adev); |
714 | if (!error) | ||
715 | dev_info(dev, "wake-up capability %s by ACPI\n", | ||
716 | enable ? "enabled" : "disabled"); | ||
717 | |||
718 | return error; | ||
697 | } | 719 | } |
698 | #endif | 720 | #endif |
699 | 721 | ||
diff --git a/drivers/acpi/system.c b/drivers/acpi/system.c index 0944daec064f..d11282975f35 100644 --- a/drivers/acpi/system.c +++ b/drivers/acpi/system.c | |||
@@ -31,6 +31,8 @@ | |||
31 | 31 | ||
32 | #include <acpi/acpi_drivers.h> | 32 | #include <acpi/acpi_drivers.h> |
33 | 33 | ||
34 | #define PREFIX "ACPI: " | ||
35 | |||
34 | #define _COMPONENT ACPI_SYSTEM_COMPONENT | 36 | #define _COMPONENT ACPI_SYSTEM_COMPONENT |
35 | ACPI_MODULE_NAME("system"); | 37 | ACPI_MODULE_NAME("system"); |
36 | 38 | ||
@@ -121,7 +123,7 @@ static void acpi_table_attr_init(struct acpi_table_attr *table_attr, | |||
121 | table_attr->attr.size = 0; | 123 | table_attr->attr.size = 0; |
122 | table_attr->attr.read = acpi_table_show; | 124 | table_attr->attr.read = acpi_table_show; |
123 | table_attr->attr.attr.name = table_attr->name; | 125 | table_attr->attr.attr.name = table_attr->name; |
124 | table_attr->attr.attr.mode = 0444; | 126 | table_attr->attr.attr.mode = 0400; |
125 | 127 | ||
126 | return; | 128 | return; |
127 | } | 129 | } |
diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c index 646d39c031ca..f336bca7c450 100644 --- a/drivers/acpi/tables.c +++ b/drivers/acpi/tables.c | |||
@@ -213,6 +213,9 @@ acpi_table_parse_entries(char *id, | |||
213 | unsigned long table_end; | 213 | unsigned long table_end; |
214 | acpi_size tbl_size; | 214 | acpi_size tbl_size; |
215 | 215 | ||
216 | if (acpi_disabled) | ||
217 | return -ENODEV; | ||
218 | |||
216 | if (!handler) | 219 | if (!handler) |
217 | return -EINVAL; | 220 | return -EINVAL; |
218 | 221 | ||
@@ -277,6 +280,9 @@ int __init acpi_table_parse(char *id, acpi_table_handler handler) | |||
277 | struct acpi_table_header *table = NULL; | 280 | struct acpi_table_header *table = NULL; |
278 | acpi_size tbl_size; | 281 | acpi_size tbl_size; |
279 | 282 | ||
283 | if (acpi_disabled) | ||
284 | return -ENODEV; | ||
285 | |||
280 | if (!handler) | 286 | if (!handler) |
281 | return -EINVAL; | 287 | return -EINVAL; |
282 | 288 | ||
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 564ea1424288..65f67815902a 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c | |||
@@ -47,6 +47,8 @@ | |||
47 | #include <acpi/acpi_bus.h> | 47 | #include <acpi/acpi_bus.h> |
48 | #include <acpi/acpi_drivers.h> | 48 | #include <acpi/acpi_drivers.h> |
49 | 49 | ||
50 | #define PREFIX "ACPI: " | ||
51 | |||
50 | #define ACPI_THERMAL_CLASS "thermal_zone" | 52 | #define ACPI_THERMAL_CLASS "thermal_zone" |
51 | #define ACPI_THERMAL_DEVICE_NAME "Thermal Zone" | 53 | #define ACPI_THERMAL_DEVICE_NAME "Thermal Zone" |
52 | #define ACPI_THERMAL_FILE_STATE "state" | 54 | #define ACPI_THERMAL_FILE_STATE "state" |
diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c index f844941089bb..811fec10462b 100644 --- a/drivers/acpi/utils.c +++ b/drivers/acpi/utils.c | |||
@@ -30,6 +30,8 @@ | |||
30 | #include <acpi/acpi_bus.h> | 30 | #include <acpi/acpi_bus.h> |
31 | #include <acpi/acpi_drivers.h> | 31 | #include <acpi/acpi_drivers.h> |
32 | 32 | ||
33 | #include "internal.h" | ||
34 | |||
33 | #define _COMPONENT ACPI_BUS_COMPONENT | 35 | #define _COMPONENT ACPI_BUS_COMPONENT |
34 | ACPI_MODULE_NAME("utils"); | 36 | ACPI_MODULE_NAME("utils"); |
35 | 37 | ||
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 1bdfb37377e3..9b578b53252d 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c | |||
@@ -44,6 +44,8 @@ | |||
44 | #include <acpi/acpi_bus.h> | 44 | #include <acpi/acpi_bus.h> |
45 | #include <acpi/acpi_drivers.h> | 45 | #include <acpi/acpi_drivers.h> |
46 | 46 | ||
47 | #define PREFIX "ACPI: " | ||
48 | |||
47 | #define ACPI_VIDEO_CLASS "video" | 49 | #define ACPI_VIDEO_CLASS "video" |
48 | #define ACPI_VIDEO_BUS_NAME "Video Bus" | 50 | #define ACPI_VIDEO_BUS_NAME "Video Bus" |
49 | #define ACPI_VIDEO_DEVICE_NAME "Video Device" | 51 | #define ACPI_VIDEO_DEVICE_NAME "Video Device" |
@@ -76,6 +78,7 @@ MODULE_LICENSE("GPL"); | |||
76 | static int brightness_switch_enabled = 1; | 78 | static int brightness_switch_enabled = 1; |
77 | module_param(brightness_switch_enabled, bool, 0644); | 79 | module_param(brightness_switch_enabled, bool, 0644); |
78 | 80 | ||
81 | static int register_count = 0; | ||
79 | static int acpi_video_bus_add(struct acpi_device *device); | 82 | static int acpi_video_bus_add(struct acpi_device *device); |
80 | static int acpi_video_bus_remove(struct acpi_device *device, int type); | 83 | static int acpi_video_bus_remove(struct acpi_device *device, int type); |
81 | static int acpi_video_resume(struct acpi_device *device); | 84 | static int acpi_video_resume(struct acpi_device *device); |
@@ -586,6 +589,14 @@ static struct dmi_system_id video_dmi_table[] __initdata = { | |||
586 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5315"), | 589 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5315"), |
587 | }, | 590 | }, |
588 | }, | 591 | }, |
592 | { | ||
593 | .callback = video_set_bqc_offset, | ||
594 | .ident = "Acer Aspire 7720", | ||
595 | .matches = { | ||
596 | DMI_MATCH(DMI_BOARD_VENDOR, "Acer"), | ||
597 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 7720"), | ||
598 | }, | ||
599 | }, | ||
589 | {} | 600 | {} |
590 | }; | 601 | }; |
591 | 602 | ||
@@ -976,6 +987,11 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) | |||
976 | device->backlight->props.max_brightness = device->brightness->count-3; | 987 | device->backlight->props.max_brightness = device->brightness->count-3; |
977 | kfree(name); | 988 | kfree(name); |
978 | 989 | ||
990 | result = sysfs_create_link(&device->backlight->dev.kobj, | ||
991 | &device->dev->dev.kobj, "device"); | ||
992 | if (result) | ||
993 | printk(KERN_ERR PREFIX "Create sysfs link\n"); | ||
994 | |||
979 | device->cdev = thermal_cooling_device_register("LCD", | 995 | device->cdev = thermal_cooling_device_register("LCD", |
980 | device->dev, &video_cooling_ops); | 996 | device->dev, &video_cooling_ops); |
981 | if (IS_ERR(device->cdev)) | 997 | if (IS_ERR(device->cdev)) |
@@ -1054,15 +1070,15 @@ static void acpi_video_bus_find_cap(struct acpi_video_bus *video) | |||
1054 | static int acpi_video_bus_check(struct acpi_video_bus *video) | 1070 | static int acpi_video_bus_check(struct acpi_video_bus *video) |
1055 | { | 1071 | { |
1056 | acpi_status status = -ENOENT; | 1072 | acpi_status status = -ENOENT; |
1057 | struct device *dev; | 1073 | struct pci_dev *dev; |
1058 | 1074 | ||
1059 | if (!video) | 1075 | if (!video) |
1060 | return -EINVAL; | 1076 | return -EINVAL; |
1061 | 1077 | ||
1062 | dev = acpi_get_physical_pci_device(video->device->handle); | 1078 | dev = acpi_get_pci_dev(video->device->handle); |
1063 | if (!dev) | 1079 | if (!dev) |
1064 | return -ENODEV; | 1080 | return -ENODEV; |
1065 | put_device(dev); | 1081 | pci_dev_put(dev); |
1066 | 1082 | ||
1067 | /* Since there is no HID, CID and so on for VGA driver, we have | 1083 | /* Since there is no HID, CID and so on for VGA driver, we have |
1068 | * to check well known required nodes. | 1084 | * to check well known required nodes. |
@@ -1990,7 +2006,11 @@ static int acpi_video_bus_put_one_device(struct acpi_video_device *device) | |||
1990 | status = acpi_remove_notify_handler(device->dev->handle, | 2006 | status = acpi_remove_notify_handler(device->dev->handle, |
1991 | ACPI_DEVICE_NOTIFY, | 2007 | ACPI_DEVICE_NOTIFY, |
1992 | acpi_video_device_notify); | 2008 | acpi_video_device_notify); |
1993 | backlight_device_unregister(device->backlight); | 2009 | if (device->backlight) { |
2010 | sysfs_remove_link(&device->backlight->dev.kobj, "device"); | ||
2011 | backlight_device_unregister(device->backlight); | ||
2012 | device->backlight = NULL; | ||
2013 | } | ||
1994 | if (device->cdev) { | 2014 | if (device->cdev) { |
1995 | sysfs_remove_link(&device->dev->dev.kobj, | 2015 | sysfs_remove_link(&device->dev->dev.kobj, |
1996 | "thermal_cooling"); | 2016 | "thermal_cooling"); |
@@ -2318,6 +2338,13 @@ static int __init intel_opregion_present(void) | |||
2318 | int acpi_video_register(void) | 2338 | int acpi_video_register(void) |
2319 | { | 2339 | { |
2320 | int result = 0; | 2340 | int result = 0; |
2341 | if (register_count) { | ||
2342 | /* | ||
2343 | * if the function of acpi_video_register is already called, | ||
2344 | * don't register the acpi_vide_bus again and return no error. | ||
2345 | */ | ||
2346 | return 0; | ||
2347 | } | ||
2321 | 2348 | ||
2322 | acpi_video_dir = proc_mkdir(ACPI_VIDEO_CLASS, acpi_root_dir); | 2349 | acpi_video_dir = proc_mkdir(ACPI_VIDEO_CLASS, acpi_root_dir); |
2323 | if (!acpi_video_dir) | 2350 | if (!acpi_video_dir) |
@@ -2329,10 +2356,35 @@ int acpi_video_register(void) | |||
2329 | return -ENODEV; | 2356 | return -ENODEV; |
2330 | } | 2357 | } |
2331 | 2358 | ||
2359 | /* | ||
2360 | * When the acpi_video_bus is loaded successfully, increase | ||
2361 | * the counter reference. | ||
2362 | */ | ||
2363 | register_count = 1; | ||
2364 | |||
2332 | return 0; | 2365 | return 0; |
2333 | } | 2366 | } |
2334 | EXPORT_SYMBOL(acpi_video_register); | 2367 | EXPORT_SYMBOL(acpi_video_register); |
2335 | 2368 | ||
2369 | void acpi_video_unregister(void) | ||
2370 | { | ||
2371 | if (!register_count) { | ||
2372 | /* | ||
2373 | * If the acpi video bus is already unloaded, don't | ||
2374 | * unload it again and return directly. | ||
2375 | */ | ||
2376 | return; | ||
2377 | } | ||
2378 | acpi_bus_unregister_driver(&acpi_video_bus); | ||
2379 | |||
2380 | remove_proc_entry(ACPI_VIDEO_CLASS, acpi_root_dir); | ||
2381 | |||
2382 | register_count = 0; | ||
2383 | |||
2384 | return; | ||
2385 | } | ||
2386 | EXPORT_SYMBOL(acpi_video_unregister); | ||
2387 | |||
2336 | /* | 2388 | /* |
2337 | * This is kind of nasty. Hardware using Intel chipsets may require | 2389 | * This is kind of nasty. Hardware using Intel chipsets may require |
2338 | * the video opregion code to be run first in order to initialise | 2390 | * the video opregion code to be run first in order to initialise |
@@ -2350,16 +2402,12 @@ static int __init acpi_video_init(void) | |||
2350 | return acpi_video_register(); | 2402 | return acpi_video_register(); |
2351 | } | 2403 | } |
2352 | 2404 | ||
2353 | void acpi_video_exit(void) | 2405 | static void __exit acpi_video_exit(void) |
2354 | { | 2406 | { |
2355 | 2407 | acpi_video_unregister(); | |
2356 | acpi_bus_unregister_driver(&acpi_video_bus); | ||
2357 | |||
2358 | remove_proc_entry(ACPI_VIDEO_CLASS, acpi_root_dir); | ||
2359 | 2408 | ||
2360 | return; | 2409 | return; |
2361 | } | 2410 | } |
2362 | EXPORT_SYMBOL(acpi_video_exit); | ||
2363 | 2411 | ||
2364 | module_init(acpi_video_init); | 2412 | module_init(acpi_video_init); |
2365 | module_exit(acpi_video_exit); | 2413 | module_exit(acpi_video_exit); |
diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c index 09737275e25f..7032f25da9b5 100644 --- a/drivers/acpi/video_detect.c +++ b/drivers/acpi/video_detect.c | |||
@@ -10,7 +10,7 @@ | |||
10 | * assinged | 10 | * assinged |
11 | * | 11 | * |
12 | * After PCI devices are glued with ACPI devices | 12 | * After PCI devices are glued with ACPI devices |
13 | * acpi_get_physical_pci_device() can be called to identify ACPI graphics | 13 | * acpi_get_pci_dev() can be called to identify ACPI graphics |
14 | * devices for which a real graphics card is plugged in | 14 | * devices for which a real graphics card is plugged in |
15 | * | 15 | * |
16 | * Now acpi_video_get_capabilities() can be called to check which | 16 | * Now acpi_video_get_capabilities() can be called to check which |
@@ -36,6 +36,9 @@ | |||
36 | 36 | ||
37 | #include <linux/acpi.h> | 37 | #include <linux/acpi.h> |
38 | #include <linux/dmi.h> | 38 | #include <linux/dmi.h> |
39 | #include <linux/pci.h> | ||
40 | |||
41 | #define PREFIX "ACPI: " | ||
39 | 42 | ||
40 | ACPI_MODULE_NAME("video"); | 43 | ACPI_MODULE_NAME("video"); |
41 | #define _COMPONENT ACPI_VIDEO_COMPONENT | 44 | #define _COMPONENT ACPI_VIDEO_COMPONENT |
@@ -109,7 +112,7 @@ static acpi_status | |||
109 | find_video(acpi_handle handle, u32 lvl, void *context, void **rv) | 112 | find_video(acpi_handle handle, u32 lvl, void *context, void **rv) |
110 | { | 113 | { |
111 | long *cap = context; | 114 | long *cap = context; |
112 | struct device *dev; | 115 | struct pci_dev *dev; |
113 | struct acpi_device *acpi_dev; | 116 | struct acpi_device *acpi_dev; |
114 | 117 | ||
115 | const struct acpi_device_id video_ids[] = { | 118 | const struct acpi_device_id video_ids[] = { |
@@ -120,10 +123,10 @@ find_video(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
120 | return AE_OK; | 123 | return AE_OK; |
121 | 124 | ||
122 | if (!acpi_match_device_ids(acpi_dev, video_ids)) { | 125 | if (!acpi_match_device_ids(acpi_dev, video_ids)) { |
123 | dev = acpi_get_physical_pci_device(handle); | 126 | dev = acpi_get_pci_dev(handle); |
124 | if (!dev) | 127 | if (!dev) |
125 | return AE_OK; | 128 | return AE_OK; |
126 | put_device(dev); | 129 | pci_dev_put(dev); |
127 | *cap |= acpi_is_video_device(acpi_dev); | 130 | *cap |= acpi_is_video_device(acpi_dev); |
128 | } | 131 | } |
129 | return AE_OK; | 132 | return AE_OK; |
diff --git a/drivers/acpi/wakeup.c b/drivers/acpi/wakeup.c index 88725dcdf8bc..e0ee0c036f5a 100644 --- a/drivers/acpi/wakeup.c +++ b/drivers/acpi/wakeup.c | |||
@@ -68,7 +68,7 @@ void acpi_enable_wakeup_device(u8 sleep_state) | |||
68 | /* If users want to disable run-wake GPE, | 68 | /* If users want to disable run-wake GPE, |
69 | * we only disable it for wake and leave it for runtime | 69 | * we only disable it for wake and leave it for runtime |
70 | */ | 70 | */ |
71 | if ((!dev->wakeup.state.enabled && !dev->wakeup.flags.prepared) | 71 | if ((!dev->wakeup.state.enabled && !dev->wakeup.prepare_count) |
72 | || sleep_state > (u32) dev->wakeup.sleep_state) { | 72 | || sleep_state > (u32) dev->wakeup.sleep_state) { |
73 | if (dev->wakeup.flags.run_wake) { | 73 | if (dev->wakeup.flags.run_wake) { |
74 | /* set_gpe_type will disable GPE, leave it like that */ | 74 | /* set_gpe_type will disable GPE, leave it like that */ |
@@ -100,7 +100,7 @@ void acpi_disable_wakeup_device(u8 sleep_state) | |||
100 | if (!dev->wakeup.flags.valid) | 100 | if (!dev->wakeup.flags.valid) |
101 | continue; | 101 | continue; |
102 | 102 | ||
103 | if ((!dev->wakeup.state.enabled && !dev->wakeup.flags.prepared) | 103 | if ((!dev->wakeup.state.enabled && !dev->wakeup.prepare_count) |
104 | || sleep_state > (u32) dev->wakeup.sleep_state) { | 104 | || sleep_state > (u32) dev->wakeup.sleep_state) { |
105 | if (dev->wakeup.flags.run_wake) { | 105 | if (dev->wakeup.flags.run_wake) { |
106 | acpi_set_gpe_type(dev->wakeup.gpe_device, | 106 | acpi_set_gpe_type(dev->wakeup.gpe_device, |