diff options
Diffstat (limited to 'drivers/acpi')
94 files changed, 4445 insertions, 1914 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 7ec7d88c5999..dd8729d674e5 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig | |||
@@ -60,7 +60,11 @@ config ACPI_PROCFS | |||
60 | /proc/acpi/fadt (/sys/firmware/acpi/tables/FACP) | 60 | /proc/acpi/fadt (/sys/firmware/acpi/tables/FACP) |
61 | /proc/acpi/debug_layer (/sys/module/acpi/parameters/debug_layer) | 61 | /proc/acpi/debug_layer (/sys/module/acpi/parameters/debug_layer) |
62 | /proc/acpi/debug_level (/sys/module/acpi/parameters/debug_level) | 62 | /proc/acpi/debug_level (/sys/module/acpi/parameters/debug_level) |
63 | 63 | /proc/acpi/processor/*/power (/sys/devices/system/cpu/*/cpuidle/*) | |
64 | /proc/acpi/processor/*/performance (/sys/devices/system/cpu/*/ | ||
65 | cpufreq/*) | ||
66 | /proc/acpi/processor/*/throttling (/sys/class/thermal/ | ||
67 | cooling_device*/*) | ||
64 | This option has no effect on /proc/acpi/ files | 68 | This option has no effect on /proc/acpi/ files |
65 | and functions which do not yet exist in /sys. | 69 | and functions which do not yet exist in /sys. |
66 | 70 | ||
@@ -82,6 +86,17 @@ config ACPI_PROCFS_POWER | |||
82 | 86 | ||
83 | 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/ |
84 | 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 | |||
85 | config ACPI_SYSFS_POWER | 100 | config ACPI_SYSFS_POWER |
86 | bool "Future power /sys interface" | 101 | bool "Future power /sys interface" |
87 | select POWER_SUPPLY | 102 | select POWER_SUPPLY |
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 0df8fcb687d6..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" |
diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c index 9a62224cc278..28ccdbc05ac8 100644 --- a/drivers/acpi/acpi_memhotplug.c +++ b/drivers/acpi/acpi_memhotplug.c | |||
@@ -53,7 +53,6 @@ MODULE_LICENSE("GPL"); | |||
53 | 53 | ||
54 | static int acpi_memory_device_add(struct acpi_device *device); | 54 | static int acpi_memory_device_add(struct acpi_device *device); |
55 | 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); |
56 | static int acpi_memory_device_start(struct acpi_device *device); | ||
57 | 56 | ||
58 | static const struct acpi_device_id memory_device_ids[] = { | 57 | static const struct acpi_device_id memory_device_ids[] = { |
59 | {ACPI_MEMORY_DEVICE_HID, 0}, | 58 | {ACPI_MEMORY_DEVICE_HID, 0}, |
@@ -68,7 +67,6 @@ static struct acpi_driver acpi_memory_device_driver = { | |||
68 | .ops = { | 67 | .ops = { |
69 | .add = acpi_memory_device_add, | 68 | .add = acpi_memory_device_add, |
70 | .remove = acpi_memory_device_remove, | 69 | .remove = acpi_memory_device_remove, |
71 | .start = acpi_memory_device_start, | ||
72 | }, | 70 | }, |
73 | }; | 71 | }; |
74 | 72 | ||
@@ -431,28 +429,6 @@ static int acpi_memory_device_add(struct acpi_device *device) | |||
431 | 429 | ||
432 | printk(KERN_DEBUG "%s \n", acpi_device_name(device)); | 430 | printk(KERN_DEBUG "%s \n", acpi_device_name(device)); |
433 | 431 | ||
434 | return result; | ||
435 | } | ||
436 | |||
437 | static int acpi_memory_device_remove(struct acpi_device *device, int type) | ||
438 | { | ||
439 | struct acpi_memory_device *mem_device = NULL; | ||
440 | |||
441 | |||
442 | if (!device || !acpi_driver_data(device)) | ||
443 | return -EINVAL; | ||
444 | |||
445 | mem_device = acpi_driver_data(device); | ||
446 | kfree(mem_device); | ||
447 | |||
448 | return 0; | ||
449 | } | ||
450 | |||
451 | static int acpi_memory_device_start (struct acpi_device *device) | ||
452 | { | ||
453 | struct acpi_memory_device *mem_device; | ||
454 | int result = 0; | ||
455 | |||
456 | /* | 432 | /* |
457 | * Early boot code has recognized memory area by EFI/E820. | 433 | * Early boot code has recognized memory area by EFI/E820. |
458 | * 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 |
@@ -462,8 +438,6 @@ static int acpi_memory_device_start (struct acpi_device *device) | |||
462 | if (!acpi_hotmem_initialized) | 438 | if (!acpi_hotmem_initialized) |
463 | return 0; | 439 | return 0; |
464 | 440 | ||
465 | mem_device = acpi_driver_data(device); | ||
466 | |||
467 | if (!acpi_memory_check_device(mem_device)) { | 441 | if (!acpi_memory_check_device(mem_device)) { |
468 | /* call add_memory func */ | 442 | /* call add_memory func */ |
469 | result = acpi_memory_enable_device(mem_device); | 443 | result = acpi_memory_enable_device(mem_device); |
@@ -474,6 +448,20 @@ static int acpi_memory_device_start (struct acpi_device *device) | |||
474 | return result; | 448 | return result; |
475 | } | 449 | } |
476 | 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 | |||
477 | /* | 465 | /* |
478 | * Helper function to check for memory device | 466 | * Helper function to check for memory device |
479 | */ | 467 | */ |
@@ -481,26 +469,23 @@ static acpi_status is_memory_device(acpi_handle handle) | |||
481 | { | 469 | { |
482 | char *hardware_id; | 470 | char *hardware_id; |
483 | acpi_status status; | 471 | acpi_status status; |
484 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
485 | struct acpi_device_info *info; | 472 | struct acpi_device_info *info; |
486 | 473 | ||
487 | 474 | status = acpi_get_object_info(handle, &info); | |
488 | status = acpi_get_object_info(handle, &buffer); | ||
489 | if (ACPI_FAILURE(status)) | 475 | if (ACPI_FAILURE(status)) |
490 | return status; | 476 | return status; |
491 | 477 | ||
492 | info = buffer.pointer; | ||
493 | if (!(info->valid & ACPI_VALID_HID)) { | 478 | if (!(info->valid & ACPI_VALID_HID)) { |
494 | kfree(buffer.pointer); | 479 | kfree(info); |
495 | return AE_ERROR; | 480 | return AE_ERROR; |
496 | } | 481 | } |
497 | 482 | ||
498 | hardware_id = info->hardware_id.value; | 483 | hardware_id = info->hardware_id.string; |
499 | if ((hardware_id == NULL) || | 484 | if ((hardware_id == NULL) || |
500 | (strcmp(hardware_id, ACPI_MEMORY_DEVICE_HID))) | 485 | (strcmp(hardware_id, ACPI_MEMORY_DEVICE_HID))) |
501 | status = AE_ERROR; | 486 | status = AE_ERROR; |
502 | 487 | ||
503 | kfree(buffer.pointer); | 488 | kfree(info); |
504 | return status; | 489 | return status; |
505 | } | 490 | } |
506 | 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/acglobal.h b/drivers/acpi/acpica/acglobal.h index 3d87362d17ed..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 | * |
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 ee986edfa0da..81e64f478679 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h | |||
@@ -369,6 +369,19 @@ union acpi_predefined_info { | |||
369 | struct acpi_package_info3 ret_info3; | 369 | struct acpi_package_info3 ret_info3; |
370 | }; | 370 | }; |
371 | 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 | |||
372 | /* | 385 | /* |
373 | * Bitmapped return value types | 386 | * Bitmapped return value types |
374 | * 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 |
@@ -885,6 +898,9 @@ struct acpi_bit_register_info { | |||
885 | #define ACPI_OSI_WIN_XP_SP2 0x05 | 898 | #define ACPI_OSI_WIN_XP_SP2 0x05 |
886 | #define ACPI_OSI_WINSRV_2003_SP1 0x06 | 899 | #define ACPI_OSI_WINSRV_2003_SP1 0x06 |
887 | #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 | ||
888 | 904 | ||
889 | #define ACPI_ALWAYS_ILLEGAL 0x00 | 905 | #define ACPI_ALWAYS_ILLEGAL 0x00 |
890 | 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 94cdc2b8cb93..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 | */ |
@@ -144,6 +152,8 @@ struct acpi_namespace_node *acpi_ns_create_node(u32 name); | |||
144 | 152 | ||
145 | void acpi_ns_delete_node(struct acpi_namespace_node *node); | 153 | void acpi_ns_delete_node(struct acpi_namespace_node *node); |
146 | 154 | ||
155 | void acpi_ns_remove_node(struct acpi_namespace_node *node); | ||
156 | |||
147 | void | 157 | void |
148 | acpi_ns_delete_namespace_subtree(struct acpi_namespace_node *parent_handle); | 158 | acpi_ns_delete_namespace_subtree(struct acpi_namespace_node *parent_handle); |
149 | 159 | ||
@@ -186,6 +196,8 @@ acpi_ns_dump_objects(acpi_object_type type, | |||
186 | */ | 196 | */ |
187 | acpi_status acpi_ns_evaluate(struct acpi_evaluate_info *info); | 197 | acpi_status acpi_ns_evaluate(struct acpi_evaluate_info *info); |
188 | 198 | ||
199 | void acpi_ns_exec_module_code_list(void); | ||
200 | |||
189 | /* | 201 | /* |
190 | * nspredef - Support for predefined/reserved names | 202 | * nspredef - Support for predefined/reserved names |
191 | */ | 203 | */ |
@@ -260,6 +272,19 @@ acpi_ns_get_attached_data(struct acpi_namespace_node *node, | |||
260 | acpi_object_handler handler, void **data); | 272 | acpi_object_handler handler, void **data); |
261 | 273 | ||
262 | /* | 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 | /* | ||
263 | * nssearch - Namespace searching and entry | 288 | * nssearch - Namespace searching and entry |
264 | */ | 289 | */ |
265 | acpi_status | 290 | acpi_status |
diff --git a/drivers/acpi/acpica/acobject.h b/drivers/acpi/acpica/acobject.h index eb6f038b03d9..b39d682a2140 100644 --- a/drivers/acpi/acpica/acobject.h +++ b/drivers/acpi/acpica/acobject.h | |||
@@ -98,6 +98,7 @@ | |||
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 */ | 100 | #define AOPOBJ_INVALID 0x40 /* Used if host OS won't allow an op_region address */ |
101 | #define AOPOBJ_MODULE_LEVEL 0x80 | ||
101 | 102 | ||
102 | /****************************************************************************** | 103 | /****************************************************************************** |
103 | * | 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 067f967eb389..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; |
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 02e6caad4a76..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 | ||
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/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/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/exconfig.c b/drivers/acpi/acpica/exconfig.c index 277fd609611a..24afef81af39 100644 --- a/drivers/acpi/acpica/exconfig.c +++ b/drivers/acpi/acpica/exconfig.c | |||
@@ -110,8 +110,15 @@ acpi_ex_add_table(u32 table_index, | |||
110 | if (ACPI_FAILURE(status)) { | 110 | if (ACPI_FAILURE(status)) { |
111 | acpi_ut_remove_reference(obj_desc); | 111 | acpi_ut_remove_reference(obj_desc); |
112 | *ddb_handle = NULL; | 112 | *ddb_handle = NULL; |
113 | return_ACPI_STATUS(status); | ||
113 | } | 114 | } |
114 | 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 | |||
115 | return_ACPI_STATUS(status); | 122 | return_ACPI_STATUS(status); |
116 | } | 123 | } |
117 | 124 | ||
diff --git a/drivers/acpi/acpica/exdump.c b/drivers/acpi/acpica/exdump.c index ec524614e708..de3446372ddc 100644 --- a/drivers/acpi/acpica/exdump.c +++ b/drivers/acpi/acpica/exdump.c | |||
@@ -418,9 +418,9 @@ acpi_ex_dump_object(union acpi_operand_object *obj_desc, | |||
418 | case ACPI_EXD_REFERENCE: | 418 | case ACPI_EXD_REFERENCE: |
419 | 419 | ||
420 | acpi_ex_out_string("Class Name", | 420 | acpi_ex_out_string("Class Name", |
421 | (char *) | 421 | ACPI_CAST_PTR(char, |
422 | acpi_ut_get_reference_name | 422 | acpi_ut_get_reference_name |
423 | (obj_desc)); | 423 | (obj_desc))); |
424 | acpi_ex_dump_reference_obj(obj_desc); | 424 | acpi_ex_dump_reference_obj(obj_desc); |
425 | break; | 425 | break; |
426 | 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 6687be167f5f..d7b3b418fb45 100644 --- a/drivers/acpi/acpica/exfldio.c +++ b/drivers/acpi/acpica/exfldio.c | |||
@@ -120,12 +120,13 @@ acpi_ex_setup_region(union acpi_operand_object *obj_desc, | |||
120 | } | 120 | } |
121 | 121 | ||
122 | /* | 122 | /* |
123 | * 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 |
124 | * and the request cannot be directly validated | 124 | * and the request cannot be directly validated |
125 | */ | 125 | */ |
126 | 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) { | ||
127 | 128 | ||
128 | /* SMBus has a non-linear address space */ | 129 | /* SMBus or IPMI has a non-linear address space */ |
129 | 130 | ||
130 | return_ACPI_STATUS(AE_OK); | 131 | return_ACPI_STATUS(AE_OK); |
131 | } | 132 | } |
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 23d5505cb1f7..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 |
@@ -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 efc971ab7d65..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)); |
@@ -433,7 +467,7 @@ void acpi_ns_delete_namespace_by_owner(acpi_owner_id owner_id) | |||
433 | 467 | ||
434 | if (deletion_node) { | 468 | if (deletion_node) { |
435 | acpi_ns_delete_children(deletion_node); | 469 | acpi_ns_delete_children(deletion_node); |
436 | acpi_ns_delete_node(deletion_node); | 470 | acpi_ns_remove_node(deletion_node); |
437 | deletion_node = NULL; | 471 | deletion_node = NULL; |
438 | } | 472 | } |
439 | 473 | ||
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/nspredef.c b/drivers/acpi/acpica/nspredef.c index 7f8e066b12a3..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,12 +138,13 @@ 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) { |
@@ -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,46 +183,67 @@ 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, | 233 | } |
229 | predefined); | 234 | |
235 | check_validation_status: | ||
236 | /* | ||
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; | ||
230 | } | 243 | } |
244 | ACPI_FREE(data); | ||
231 | 245 | ||
232 | exit: | 246 | cleanup: |
233 | ACPI_FREE(pathname); | 247 | ACPI_FREE(pathname); |
234 | return (status); | 248 | return (status); |
235 | } | 249 | } |
@@ -268,64 +282,58 @@ acpi_ns_check_parameter_count(char *pathname, | |||
268 | param_count = node->object->method.param_count; | 282 | param_count = node->object->method.param_count; |
269 | } | 283 | } |
270 | 284 | ||
271 | /* Argument count check for non-predefined methods/objects */ | ||
272 | |||
273 | if (!predefined) { | 285 | if (!predefined) { |
274 | /* | 286 | /* |
287 | * Check the parameter count for non-predefined methods/objects. | ||
288 | * | ||
275 | * 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 |
276 | * caller. An incorrect number of arguments may not cause the method | 290 | * caller. An incorrect number of arguments may not cause the method |
277 | * 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 |
278 | * 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. |
279 | */ | 293 | */ |
280 | if (user_param_count < param_count) { | 294 | if (user_param_count < param_count) { |
281 | ACPI_WARNING((AE_INFO, | 295 | ACPI_WARN_PREDEFINED((AE_INFO, pathname, |
282 | "%s: Insufficient arguments - needs %d, found %d", | 296 | ACPI_WARN_ALWAYS, |
283 | pathname, param_count, user_param_count)); | 297 | "Insufficient arguments - needs %u, found %u", |
298 | param_count, user_param_count)); | ||
284 | } else if (user_param_count > param_count) { | 299 | } else if (user_param_count > param_count) { |
285 | ACPI_WARNING((AE_INFO, | 300 | ACPI_WARN_PREDEFINED((AE_INFO, pathname, |
286 | "%s: Excess arguments - needs %d, found %d", | 301 | ACPI_WARN_ALWAYS, |
287 | pathname, param_count, user_param_count)); | 302 | "Excess arguments - needs %u, found %u", |
303 | param_count, user_param_count)); | ||
288 | } | 304 | } |
289 | return; | 305 | return; |
290 | } | 306 | } |
291 | 307 | ||
292 | /* Allow two different legal argument counts (_SCP, etc.) */ | 308 | /* |
293 | 309 | * Validate the user-supplied parameter count. | |
310 | * Allow two different legal argument counts (_SCP, etc.) | ||
311 | */ | ||
294 | required_params_current = predefined->info.param_count & 0x0F; | 312 | required_params_current = predefined->info.param_count & 0x0F; |
295 | required_params_old = predefined->info.param_count >> 4; | 313 | required_params_old = predefined->info.param_count >> 4; |
296 | 314 | ||
297 | if (user_param_count != ACPI_UINT32_MAX) { | 315 | if (user_param_count != ACPI_UINT32_MAX) { |
298 | |||
299 | /* Validate the user-supplied parameter count */ | ||
300 | |||
301 | if ((user_param_count != required_params_current) && | 316 | if ((user_param_count != required_params_current) && |
302 | (user_param_count != required_params_old)) { | 317 | (user_param_count != required_params_old)) { |
303 | ACPI_WARNING((AE_INFO, | 318 | ACPI_WARN_PREDEFINED((AE_INFO, pathname, |
304 | "%s: Parameter count mismatch - " | 319 | ACPI_WARN_ALWAYS, |
305 | "caller passed %d, ACPI requires %d", | 320 | "Parameter count mismatch - " |
306 | pathname, user_param_count, | 321 | "caller passed %u, ACPI requires %u", |
307 | required_params_current)); | 322 | user_param_count, |
323 | required_params_current)); | ||
308 | } | 324 | } |
309 | } | 325 | } |
310 | 326 | ||
311 | /* | 327 | /* |
312 | * Only validate the argument count on the first successful evaluation of | ||
313 | * the method. This ensures that any warnings will only be emitted during | ||
314 | * the very first evaluation of the method/object. | ||
315 | */ | ||
316 | if (node->flags & ANOBJ_EVALUATED) { | ||
317 | return; | ||
318 | } | ||
319 | |||
320 | /* | ||
321 | * 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 |
322 | * this predefined name. | 329 | * this predefined name (parameter count as defined by the ACPI |
330 | * specification) | ||
323 | */ | 331 | */ |
324 | if ((param_count != required_params_current) && | 332 | if ((param_count != required_params_current) && |
325 | (param_count != required_params_old)) { | 333 | (param_count != required_params_old)) { |
326 | ACPI_WARNING((AE_INFO, | 334 | ACPI_WARN_PREDEFINED((AE_INFO, pathname, node->flags, |
327 | "%s: Parameter count mismatch - ASL declared %d, ACPI requires %d", | 335 | "Parameter count mismatch - ASL declared %u, ACPI requires %u", |
328 | pathname, param_count, required_params_current)); | 336 | param_count, required_params_current)); |
329 | } | 337 | } |
330 | } | 338 | } |
331 | 339 | ||
@@ -358,9 +366,6 @@ const union acpi_predefined_info *acpi_ns_check_for_predefined_name(struct | |||
358 | this_name = predefined_names; | 366 | this_name = predefined_names; |
359 | while (this_name->info.name[0]) { | 367 | while (this_name->info.name[0]) { |
360 | if (ACPI_COMPARE_NAME(node->name.ascii, this_name->info.name)) { | 368 | if (ACPI_COMPARE_NAME(node->name.ascii, this_name->info.name)) { |
361 | |||
362 | /* Return pointer to this table entry */ | ||
363 | |||
364 | return (this_name); | 369 | return (this_name); |
365 | } | 370 | } |
366 | 371 | ||
@@ -375,17 +380,16 @@ const union acpi_predefined_info *acpi_ns_check_for_predefined_name(struct | |||
375 | this_name++; | 380 | this_name++; |
376 | } | 381 | } |
377 | 382 | ||
378 | return (NULL); | 383 | return (NULL); /* Not found */ |
379 | } | 384 | } |
380 | 385 | ||
381 | /******************************************************************************* | 386 | /******************************************************************************* |
382 | * | 387 | * |
383 | * FUNCTION: acpi_ns_check_package | 388 | * FUNCTION: acpi_ns_check_package |
384 | * | 389 | * |
385 | * PARAMETERS: Pathname - Full pathname to the node (for error msgs) | 390 | * PARAMETERS: Data - Pointer to validation data structure |
386 | * return_object_ptr - Pointer to the object returned from the | 391 | * return_object_ptr - Pointer to the object returned from the |
387 | * evaluation of a method or object | 392 | * evaluation of a method or object |
388 | * Predefined - Pointer to entry in predefined name table | ||
389 | * | 393 | * |
390 | * RETURN: Status | 394 | * RETURN: Status |
391 | * | 395 | * |
@@ -395,30 +399,26 @@ const union acpi_predefined_info *acpi_ns_check_for_predefined_name(struct | |||
395 | ******************************************************************************/ | 399 | ******************************************************************************/ |
396 | 400 | ||
397 | static acpi_status | 401 | static acpi_status |
398 | acpi_ns_check_package(char *pathname, | 402 | acpi_ns_check_package(struct acpi_predefined_data *data, |
399 | union acpi_operand_object **return_object_ptr, | 403 | union acpi_operand_object **return_object_ptr) |
400 | const union acpi_predefined_info *predefined) | ||
401 | { | 404 | { |
402 | union acpi_operand_object *return_object = *return_object_ptr; | 405 | union acpi_operand_object *return_object = *return_object_ptr; |
403 | const union acpi_predefined_info *package; | 406 | const union acpi_predefined_info *package; |
404 | union acpi_operand_object *sub_package; | ||
405 | union acpi_operand_object **elements; | 407 | union acpi_operand_object **elements; |
406 | union acpi_operand_object **sub_elements; | 408 | acpi_status status = AE_OK; |
407 | acpi_status status; | ||
408 | u32 expected_count; | 409 | u32 expected_count; |
409 | u32 count; | 410 | u32 count; |
410 | u32 i; | 411 | u32 i; |
411 | u32 j; | ||
412 | 412 | ||
413 | ACPI_FUNCTION_NAME(ns_check_package); | 413 | ACPI_FUNCTION_NAME(ns_check_package); |
414 | 414 | ||
415 | /* 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 */ |
416 | 416 | ||
417 | package = predefined + 1; | 417 | package = data->predefined + 1; |
418 | 418 | ||
419 | ACPI_DEBUG_PRINT((ACPI_DB_NAMES, | 419 | ACPI_DEBUG_PRINT((ACPI_DB_NAMES, |
420 | "%s Validating return Package of Type %X, Count %X\n", | 420 | "%s Validating return Package of Type %X, Count %X\n", |
421 | pathname, package->ret_info.type, | 421 | data->pathname, package->ret_info.type, |
422 | return_object->package.count)); | 422 | return_object->package.count)); |
423 | 423 | ||
424 | /* Extract package count and elements array */ | 424 | /* Extract package count and elements array */ |
@@ -429,9 +429,8 @@ acpi_ns_check_package(char *pathname, | |||
429 | /* The package must have at least one element, else invalid */ | 429 | /* The package must have at least one element, else invalid */ |
430 | 430 | ||
431 | if (!count) { | 431 | if (!count) { |
432 | ACPI_WARNING((AE_INFO, | 432 | ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags, |
433 | "%s: Return Package has no elements (empty)", | 433 | "Return Package has no elements (empty)")); |
434 | pathname)); | ||
435 | 434 | ||
436 | return (AE_AML_OPERAND_VALUE); | 435 | return (AE_AML_OPERAND_VALUE); |
437 | } | 436 | } |
@@ -456,15 +455,16 @@ acpi_ns_check_package(char *pathname, | |||
456 | if (count < expected_count) { | 455 | if (count < expected_count) { |
457 | goto package_too_small; | 456 | goto package_too_small; |
458 | } else if (count > expected_count) { | 457 | } else if (count > expected_count) { |
459 | ACPI_WARNING((AE_INFO, | 458 | ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, |
460 | "%s: Return Package is larger than needed - " | 459 | data->node_flags, |
461 | "found %u, expected %u", pathname, count, | 460 | "Return Package is larger than needed - " |
462 | expected_count)); | 461 | "found %u, expected %u", count, |
462 | expected_count)); | ||
463 | } | 463 | } |
464 | 464 | ||
465 | /* Validate all elements of the returned package */ | 465 | /* Validate all elements of the returned package */ |
466 | 466 | ||
467 | status = acpi_ns_check_package_elements(pathname, elements, | 467 | status = acpi_ns_check_package_elements(data, elements, |
468 | package->ret_info. | 468 | package->ret_info. |
469 | object_type1, | 469 | object_type1, |
470 | package->ret_info. | 470 | package->ret_info. |
@@ -473,9 +473,6 @@ acpi_ns_check_package(char *pathname, | |||
473 | object_type2, | 473 | object_type2, |
474 | package->ret_info. | 474 | package->ret_info. |
475 | count2, 0); | 475 | count2, 0); |
476 | if (ACPI_FAILURE(status)) { | ||
477 | return (status); | ||
478 | } | ||
479 | break; | 476 | break; |
480 | 477 | ||
481 | case ACPI_PTYPE1_VAR: | 478 | case ACPI_PTYPE1_VAR: |
@@ -485,7 +482,7 @@ acpi_ns_check_package(char *pathname, | |||
485 | * elements must be of the same type | 482 | * elements must be of the same type |
486 | */ | 483 | */ |
487 | for (i = 0; i < count; i++) { | 484 | for (i = 0; i < count; i++) { |
488 | status = acpi_ns_check_object_type(pathname, elements, | 485 | status = acpi_ns_check_object_type(data, elements, |
489 | package->ret_info. | 486 | package->ret_info. |
490 | object_type1, i); | 487 | object_type1, i); |
491 | if (ACPI_FAILURE(status)) { | 488 | if (ACPI_FAILURE(status)) { |
@@ -517,8 +514,7 @@ acpi_ns_check_package(char *pathname, | |||
517 | /* These are the required package elements (0, 1, or 2) */ | 514 | /* These are the required package elements (0, 1, or 2) */ |
518 | 515 | ||
519 | status = | 516 | status = |
520 | acpi_ns_check_object_type(pathname, | 517 | acpi_ns_check_object_type(data, elements, |
521 | elements, | ||
522 | package-> | 518 | package-> |
523 | ret_info3. | 519 | ret_info3. |
524 | object_type[i], | 520 | object_type[i], |
@@ -530,8 +526,7 @@ acpi_ns_check_package(char *pathname, | |||
530 | /* These are the optional package elements */ | 526 | /* These are the optional package elements */ |
531 | 527 | ||
532 | status = | 528 | status = |
533 | acpi_ns_check_object_type(pathname, | 529 | acpi_ns_check_object_type(data, elements, |
534 | elements, | ||
535 | package-> | 530 | package-> |
536 | ret_info3. | 531 | ret_info3. |
537 | tail_object_type, | 532 | tail_object_type, |
@@ -544,11 +539,30 @@ acpi_ns_check_package(char *pathname, | |||
544 | } | 539 | } |
545 | break; | 540 | break; |
546 | 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 | |||
547 | case ACPI_PTYPE2_PKG_COUNT: | 561 | case ACPI_PTYPE2_PKG_COUNT: |
548 | 562 | ||
549 | /* First element is the (Integer) count of sub-packages to follow */ | 563 | /* First element is the (Integer) count of sub-packages to follow */ |
550 | 564 | ||
551 | status = acpi_ns_check_object_type(pathname, elements, | 565 | status = acpi_ns_check_object_type(data, elements, |
552 | ACPI_RTYPE_INTEGER, 0); | 566 | ACPI_RTYPE_INTEGER, 0); |
553 | if (ACPI_FAILURE(status)) { | 567 | if (ACPI_FAILURE(status)) { |
554 | return (status); | 568 | return (status); |
@@ -566,9 +580,11 @@ acpi_ns_check_package(char *pathname, | |||
566 | count = expected_count; | 580 | count = expected_count; |
567 | elements++; | 581 | elements++; |
568 | 582 | ||
569 | /* Now we can walk the sub-packages */ | 583 | /* Examine the sub-packages */ |
570 | 584 | ||
571 | /*lint -fallthrough */ | 585 | status = |
586 | acpi_ns_check_package_list(data, package, elements, count); | ||
587 | break; | ||
572 | 588 | ||
573 | case ACPI_PTYPE2: | 589 | case ACPI_PTYPE2: |
574 | case ACPI_PTYPE2_FIXED: | 590 | case ACPI_PTYPE2_FIXED: |
@@ -576,176 +592,240 @@ acpi_ns_check_package(char *pathname, | |||
576 | case ACPI_PTYPE2_COUNT: | 592 | case ACPI_PTYPE2_COUNT: |
577 | 593 | ||
578 | /* | 594 | /* |
579 | * These types all return a single package that consists of a variable | 595 | * These types all return a single Package that consists of a |
580 | * 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. | ||
581 | */ | 603 | */ |
582 | for (i = 0; i < count; i++) { | 604 | if ((*elements)->common.type != ACPI_TYPE_PACKAGE) { |
583 | sub_package = *elements; | ||
584 | sub_elements = sub_package->package.elements; | ||
585 | 605 | ||
586 | /* Each sub-object must be of type Package */ | 606 | /* Create the new outer package and populate it */ |
587 | 607 | ||
588 | status = | 608 | status = |
589 | acpi_ns_check_object_type(pathname, &sub_package, | 609 | acpi_ns_repair_package_list(data, |
590 | ACPI_RTYPE_PACKAGE, i); | 610 | return_object_ptr); |
591 | if (ACPI_FAILURE(status)) { | 611 | if (ACPI_FAILURE(status)) { |
592 | return (status); | 612 | return (status); |
593 | } | 613 | } |
594 | 614 | ||
595 | /* Examine the different types of sub-packages */ | 615 | /* Update locals to point to the new package (of 1 element) */ |
596 | 616 | ||
597 | switch (package->ret_info.type) { | 617 | return_object = *return_object_ptr; |
598 | case ACPI_PTYPE2: | 618 | elements = return_object->package.elements; |
599 | case ACPI_PTYPE2_PKG_COUNT: | 619 | count = 1; |
620 | } | ||
600 | 621 | ||
601 | /* Each subpackage has a fixed number of elements */ | 622 | /* Examine the sub-packages */ |
602 | 623 | ||
603 | expected_count = | 624 | status = |
604 | package->ret_info.count1 + | 625 | acpi_ns_check_package_list(data, package, elements, count); |
605 | package->ret_info.count2; | 626 | break; |
606 | if (sub_package->package.count != | ||
607 | expected_count) { | ||
608 | count = sub_package->package.count; | ||
609 | goto package_too_small; | ||
610 | } | ||
611 | 627 | ||
612 | status = | 628 | default: |
613 | acpi_ns_check_package_elements(pathname, | ||
614 | sub_elements, | ||
615 | package-> | ||
616 | ret_info. | ||
617 | object_type1, | ||
618 | package-> | ||
619 | ret_info. | ||
620 | count1, | ||
621 | package-> | ||
622 | ret_info. | ||
623 | object_type2, | ||
624 | package-> | ||
625 | ret_info. | ||
626 | count2, 0); | ||
627 | if (ACPI_FAILURE(status)) { | ||
628 | return (status); | ||
629 | } | ||
630 | break; | ||
631 | 629 | ||
632 | case ACPI_PTYPE2_FIXED: | 630 | /* Should not get here if predefined info table is correct */ |
633 | 631 | ||
634 | /* 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)); | ||
635 | 635 | ||
636 | expected_count = package->ret_info2.count; | 636 | return (AE_AML_INTERNAL); |
637 | if (sub_package->package.count < expected_count) { | 637 | } |
638 | count = sub_package->package.count; | ||
639 | goto package_too_small; | ||
640 | } | ||
641 | 638 | ||
642 | /* Check the type of each sub-package element */ | 639 | return (status); |
643 | 640 | ||
644 | for (j = 0; j < expected_count; j++) { | 641 | package_too_small: |
645 | status = | ||
646 | acpi_ns_check_object_type(pathname, | ||
647 | &sub_elements[j], | ||
648 | package->ret_info2.object_type[j], j); | ||
649 | if (ACPI_FAILURE(status)) { | ||
650 | return (status); | ||
651 | } | ||
652 | } | ||
653 | break; | ||
654 | 642 | ||
655 | case ACPI_PTYPE2_MIN: | 643 | /* Error exit for the case with an incorrect package count */ |
656 | 644 | ||
657 | /* 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)); | ||
658 | 648 | ||
659 | expected_count = package->ret_info.count1; | 649 | return (AE_AML_OPERAND_VALUE); |
660 | if (sub_package->package.count < expected_count) { | 650 | } |
661 | count = sub_package->package.count; | ||
662 | goto package_too_small; | ||
663 | } | ||
664 | 651 | ||
665 | /* 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 | ******************************************************************************/ | ||
666 | 667 | ||
667 | status = | 668 | static acpi_status |
668 | acpi_ns_check_package_elements(pathname, | 669 | acpi_ns_check_package_list(struct acpi_predefined_data *data, |
669 | sub_elements, | 670 | const union acpi_predefined_info *package, |
670 | package-> | 671 | union acpi_operand_object **elements, u32 count) |
671 | ret_info. | 672 | { |
672 | object_type1, | 673 | union acpi_operand_object *sub_package; |
673 | sub_package-> | 674 | union acpi_operand_object **sub_elements; |
674 | package. | 675 | acpi_status status; |
675 | count, 0, 0, | 676 | u32 expected_count; |
676 | 0); | 677 | u32 i; |
677 | if (ACPI_FAILURE(status)) { | 678 | u32 j; |
678 | return (status); | ||
679 | } | ||
680 | break; | ||
681 | 679 | ||
682 | case ACPI_PTYPE2_COUNT: | 680 | /* Validate each sub-Package in the parent Package */ |
683 | 681 | ||
684 | /* 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; | ||
685 | 685 | ||
686 | status = | 686 | /* Each sub-object must be of type Package */ |
687 | acpi_ns_check_object_type(pathname, | ||
688 | sub_elements, | ||
689 | ACPI_RTYPE_INTEGER, | ||
690 | 0); | ||
691 | if (ACPI_FAILURE(status)) { | ||
692 | return (status); | ||
693 | } | ||
694 | 687 | ||
695 | /* 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 | } | ||
696 | 693 | ||
697 | expected_count = | 694 | /* Examine the different types of expected sub-packages */ |
698 | (u32) (*sub_elements)->integer.value; | 695 | |
699 | if (sub_package->package.count < expected_count) { | 696 | switch (package->ret_info.type) { |
700 | count = sub_package->package.count; | 697 | case ACPI_PTYPE2: |
701 | goto package_too_small; | 698 | case ACPI_PTYPE2_PKG_COUNT: |
702 | } | 699 | case ACPI_PTYPE2_REV_FIXED: |
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; | ||
703 | 723 | ||
704 | /* Check the type of each sub-package element */ | 724 | case ACPI_PTYPE2_FIXED: |
705 | 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++) { | ||
706 | status = | 736 | status = |
707 | acpi_ns_check_package_elements(pathname, | 737 | acpi_ns_check_object_type(data, |
708 | (sub_elements | 738 | &sub_elements[j], |
709 | + 1), | 739 | package-> |
710 | package-> | 740 | ret_info2. |
711 | ret_info. | 741 | object_type[j], |
712 | object_type1, | 742 | j); |
713 | (expected_count | ||
714 | - 1), 0, 0, | ||
715 | 1); | ||
716 | if (ACPI_FAILURE(status)) { | 743 | if (ACPI_FAILURE(status)) { |
717 | return (status); | 744 | return (status); |
718 | } | 745 | } |
719 | break; | 746 | } |
747 | break; | ||
748 | |||
749 | case ACPI_PTYPE2_MIN: | ||
720 | 750 | ||
721 | default: | 751 | /* Each sub-package has a variable but minimum length */ |
722 | break; | 752 | |
753 | expected_count = package->ret_info.count1; | ||
754 | if (sub_package->package.count < expected_count) { | ||
755 | goto package_too_small; | ||
723 | } | 756 | } |
724 | 757 | ||
725 | elements++; | 758 | /* Check the type of each sub-package element */ |
726 | } | ||
727 | break; | ||
728 | 759 | ||
729 | 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; | ||
730 | 770 | ||
731 | /* Should not get here if predefined info table is correct */ | 771 | case ACPI_PTYPE2_COUNT: |
772 | |||
773 | /* | ||
774 | * First element is the (Integer) count of elements, including | ||
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 | } | ||
732 | 783 | ||
733 | ACPI_WARNING((AE_INFO, | 784 | /* |
734 | "%s: Invalid internal return type in table entry: %X", | 785 | * Make sure package is large enough for the Count and is |
735 | pathname, package->ret_info.type)); | 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 | } | ||
736 | 797 | ||
737 | return (AE_AML_INTERNAL); | 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++; | ||
738 | } | 818 | } |
739 | 819 | ||
740 | return (AE_OK); | 820 | return (AE_OK); |
741 | 821 | ||
742 | package_too_small: | 822 | package_too_small: |
743 | 823 | ||
744 | /* Error exit for the case with an incorrect package count */ | 824 | /* The sub-package count was smaller than required */ |
745 | 825 | ||
746 | ACPI_WARNING((AE_INFO, "%s: Return Package is too small - " | 826 | ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags, |
747 | "found %u, expected %u", pathname, count, | 827 | "Return Sub-Package[%u] is too small - found %u elements, expected %u", |
748 | expected_count)); | 828 | i, sub_package->package.count, expected_count)); |
749 | 829 | ||
750 | return (AE_AML_OPERAND_VALUE); | 830 | return (AE_AML_OPERAND_VALUE); |
751 | } | 831 | } |
@@ -754,7 +834,7 @@ acpi_ns_check_package(char *pathname, | |||
754 | * | 834 | * |
755 | * FUNCTION: acpi_ns_check_package_elements | 835 | * FUNCTION: acpi_ns_check_package_elements |
756 | * | 836 | * |
757 | * PARAMETERS: Pathname - Full pathname to the node (for error msgs) | 837 | * PARAMETERS: Data - Pointer to validation data structure |
758 | * Elements - Pointer to the package elements array | 838 | * Elements - Pointer to the package elements array |
759 | * Type1 - Object type for first group | 839 | * Type1 - Object type for first group |
760 | * Count1 - Count for first group | 840 | * Count1 - Count for first group |
@@ -770,7 +850,7 @@ acpi_ns_check_package(char *pathname, | |||
770 | ******************************************************************************/ | 850 | ******************************************************************************/ |
771 | 851 | ||
772 | static acpi_status | 852 | static acpi_status |
773 | acpi_ns_check_package_elements(char *pathname, | 853 | acpi_ns_check_package_elements(struct acpi_predefined_data *data, |
774 | union acpi_operand_object **elements, | 854 | union acpi_operand_object **elements, |
775 | u8 type1, | 855 | u8 type1, |
776 | u32 count1, | 856 | u32 count1, |
@@ -786,7 +866,7 @@ acpi_ns_check_package_elements(char *pathname, | |||
786 | * The second group can have a count of zero. | 866 | * The second group can have a count of zero. |
787 | */ | 867 | */ |
788 | for (i = 0; i < count1; i++) { | 868 | for (i = 0; i < count1; i++) { |
789 | status = acpi_ns_check_object_type(pathname, this_element, | 869 | status = acpi_ns_check_object_type(data, this_element, |
790 | type1, i + start_index); | 870 | type1, i + start_index); |
791 | if (ACPI_FAILURE(status)) { | 871 | if (ACPI_FAILURE(status)) { |
792 | return (status); | 872 | return (status); |
@@ -795,7 +875,7 @@ acpi_ns_check_package_elements(char *pathname, | |||
795 | } | 875 | } |
796 | 876 | ||
797 | for (i = 0; i < count2; i++) { | 877 | for (i = 0; i < count2; i++) { |
798 | status = acpi_ns_check_object_type(pathname, this_element, | 878 | status = acpi_ns_check_object_type(data, this_element, |
799 | type2, | 879 | type2, |
800 | (i + count1 + start_index)); | 880 | (i + count1 + start_index)); |
801 | if (ACPI_FAILURE(status)) { | 881 | if (ACPI_FAILURE(status)) { |
@@ -811,12 +891,13 @@ acpi_ns_check_package_elements(char *pathname, | |||
811 | * | 891 | * |
812 | * FUNCTION: acpi_ns_check_object_type | 892 | * FUNCTION: acpi_ns_check_object_type |
813 | * | 893 | * |
814 | * PARAMETERS: Pathname - Full pathname to the node (for error msgs) | 894 | * PARAMETERS: Data - Pointer to validation data structure |
815 | * return_object_ptr - Pointer to the object returned from the | 895 | * return_object_ptr - Pointer to the object returned from the |
816 | * evaluation of a method or object | 896 | * evaluation of a method or object |
817 | * expected_btypes - Bitmap of expected return type(s) | 897 | * expected_btypes - Bitmap of expected return type(s) |
818 | * package_index - Index of object within parent package (if | 898 | * package_index - Index of object within parent package (if |
819 | * applicable - ACPI_NOT_PACKAGE otherwise) | 899 | * applicable - ACPI_NOT_PACKAGE_ELEMENT |
900 | * otherwise) | ||
820 | * | 901 | * |
821 | * RETURN: Status | 902 | * RETURN: Status |
822 | * | 903 | * |
@@ -826,7 +907,7 @@ acpi_ns_check_package_elements(char *pathname, | |||
826 | ******************************************************************************/ | 907 | ******************************************************************************/ |
827 | 908 | ||
828 | static acpi_status | 909 | static acpi_status |
829 | acpi_ns_check_object_type(char *pathname, | 910 | acpi_ns_check_object_type(struct acpi_predefined_data *data, |
830 | union acpi_operand_object **return_object_ptr, | 911 | union acpi_operand_object **return_object_ptr, |
831 | u32 expected_btypes, u32 package_index) | 912 | u32 expected_btypes, u32 package_index) |
832 | { | 913 | { |
@@ -834,9 +915,6 @@ acpi_ns_check_object_type(char *pathname, | |||
834 | acpi_status status = AE_OK; | 915 | acpi_status status = AE_OK; |
835 | u32 return_btype; | 916 | u32 return_btype; |
836 | char type_buffer[48]; /* Room for 5 types */ | 917 | char type_buffer[48]; /* Room for 5 types */ |
837 | u32 this_rtype; | ||
838 | u32 i; | ||
839 | u32 j; | ||
840 | 918 | ||
841 | /* | 919 | /* |
842 | * 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, |
@@ -849,10 +927,11 @@ acpi_ns_check_object_type(char *pathname, | |||
849 | /* A Namespace node should not get here, but make sure */ | 927 | /* A Namespace node should not get here, but make sure */ |
850 | 928 | ||
851 | if (ACPI_GET_DESCRIPTOR_TYPE(return_object) == ACPI_DESC_TYPE_NAMED) { | 929 | if (ACPI_GET_DESCRIPTOR_TYPE(return_object) == ACPI_DESC_TYPE_NAMED) { |
852 | ACPI_WARNING((AE_INFO, | 930 | ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags, |
853 | "%s: Invalid return type - Found a Namespace node [%4.4s] type %s", | 931 | "Invalid return type - Found a Namespace node [%4.4s] type %s", |
854 | pathname, return_object->node.name.ascii, | 932 | return_object->node.name.ascii, |
855 | acpi_ut_get_type_name(return_object->node.type))); | 933 | acpi_ut_get_type_name(return_object->node. |
934 | type))); | ||
856 | return (AE_AML_OPERAND_TYPE); | 935 | return (AE_AML_OPERAND_TYPE); |
857 | } | 936 | } |
858 | 937 | ||
@@ -897,10 +976,11 @@ acpi_ns_check_object_type(char *pathname, | |||
897 | 976 | ||
898 | /* Type mismatch -- attempt repair of the returned object */ | 977 | /* Type mismatch -- attempt repair of the returned object */ |
899 | 978 | ||
900 | status = acpi_ns_repair_object(expected_btypes, package_index, | 979 | status = acpi_ns_repair_object(data, expected_btypes, |
980 | package_index, | ||
901 | return_object_ptr); | 981 | return_object_ptr); |
902 | if (ACPI_SUCCESS(status)) { | 982 | if (ACPI_SUCCESS(status)) { |
903 | return (status); | 983 | return (AE_OK); /* Repair was successful */ |
904 | } | 984 | } |
905 | goto type_error_exit; | 985 | goto type_error_exit; |
906 | } | 986 | } |
@@ -908,7 +988,7 @@ acpi_ns_check_object_type(char *pathname, | |||
908 | /* For reference objects, check that the reference type is correct */ | 988 | /* For reference objects, check that the reference type is correct */ |
909 | 989 | ||
910 | if (return_object->common.type == ACPI_TYPE_LOCAL_REFERENCE) { | 990 | if (return_object->common.type == ACPI_TYPE_LOCAL_REFERENCE) { |
911 | status = acpi_ns_check_reference(pathname, return_object); | 991 | status = acpi_ns_check_reference(data, return_object); |
912 | } | 992 | } |
913 | 993 | ||
914 | return (status); | 994 | return (status); |
@@ -917,33 +997,19 @@ acpi_ns_check_object_type(char *pathname, | |||
917 | 997 | ||
918 | /* Create a string with all expected types for this predefined object */ | 998 | /* Create a string with all expected types for this predefined object */ |
919 | 999 | ||
920 | j = 1; | 1000 | acpi_ns_get_expected_types(type_buffer, expected_btypes); |
921 | type_buffer[0] = 0; | ||
922 | this_rtype = ACPI_RTYPE_INTEGER; | ||
923 | |||
924 | for (i = 0; i < ACPI_NUM_RTYPES; i++) { | ||
925 | |||
926 | /* If one of the expected types, concatenate the name of this type */ | ||
927 | |||
928 | if (expected_btypes & this_rtype) { | ||
929 | ACPI_STRCAT(type_buffer, &acpi_rtype_names[i][j]); | ||
930 | j = 0; /* Use name separator from now on */ | ||
931 | } | ||
932 | this_rtype <<= 1; /* Next Rtype */ | ||
933 | } | ||
934 | 1001 | ||
935 | if (package_index == ACPI_NOT_PACKAGE) { | 1002 | if (package_index == ACPI_NOT_PACKAGE_ELEMENT) { |
936 | ACPI_WARNING((AE_INFO, | 1003 | ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags, |
937 | "%s: Return type mismatch - found %s, expected %s", | 1004 | "Return type mismatch - found %s, expected %s", |
938 | pathname, | 1005 | acpi_ut_get_object_type_name |
939 | acpi_ut_get_object_type_name(return_object), | 1006 | (return_object), type_buffer)); |
940 | type_buffer)); | ||
941 | } else { | 1007 | } else { |
942 | ACPI_WARNING((AE_INFO, | 1008 | ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags, |
943 | "%s: Return Package type mismatch at index %u - " | 1009 | "Return Package type mismatch at index %u - " |
944 | "found %s, expected %s", pathname, package_index, | 1010 | "found %s, expected %s", package_index, |
945 | acpi_ut_get_object_type_name(return_object), | 1011 | acpi_ut_get_object_type_name |
946 | type_buffer)); | 1012 | (return_object), type_buffer)); |
947 | } | 1013 | } |
948 | 1014 | ||
949 | return (AE_AML_OPERAND_TYPE); | 1015 | return (AE_AML_OPERAND_TYPE); |
@@ -953,7 +1019,7 @@ acpi_ns_check_object_type(char *pathname, | |||
953 | * | 1019 | * |
954 | * FUNCTION: acpi_ns_check_reference | 1020 | * FUNCTION: acpi_ns_check_reference |
955 | * | 1021 | * |
956 | * PARAMETERS: Pathname - Full pathname to the node (for error msgs) | 1022 | * PARAMETERS: Data - Pointer to validation data structure |
957 | * return_object - Object returned from the evaluation of a | 1023 | * return_object - Object returned from the evaluation of a |
958 | * method or object | 1024 | * method or object |
959 | * | 1025 | * |
@@ -966,7 +1032,7 @@ acpi_ns_check_object_type(char *pathname, | |||
966 | ******************************************************************************/ | 1032 | ******************************************************************************/ |
967 | 1033 | ||
968 | static acpi_status | 1034 | static acpi_status |
969 | acpi_ns_check_reference(char *pathname, | 1035 | acpi_ns_check_reference(struct acpi_predefined_data *data, |
970 | union acpi_operand_object *return_object) | 1036 | union acpi_operand_object *return_object) |
971 | { | 1037 | { |
972 | 1038 | ||
@@ -979,94 +1045,46 @@ acpi_ns_check_reference(char *pathname, | |||
979 | return (AE_OK); | 1045 | return (AE_OK); |
980 | } | 1046 | } |
981 | 1047 | ||
982 | ACPI_WARNING((AE_INFO, | 1048 | ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags, |
983 | "%s: Return type mismatch - " | 1049 | "Return type mismatch - unexpected reference object type [%s] %2.2X", |
984 | "unexpected reference object type [%s] %2.2X", | 1050 | acpi_ut_get_reference_name(return_object), |
985 | pathname, acpi_ut_get_reference_name(return_object), | 1051 | return_object->reference.class)); |
986 | return_object->reference.class)); | ||
987 | 1052 | ||
988 | return (AE_AML_OPERAND_TYPE); | 1053 | return (AE_AML_OPERAND_TYPE); |
989 | } | 1054 | } |
990 | 1055 | ||
991 | /******************************************************************************* | 1056 | /******************************************************************************* |
992 | * | 1057 | * |
993 | * FUNCTION: acpi_ns_repair_object | 1058 | * FUNCTION: acpi_ns_get_expected_types |
994 | * | 1059 | * |
995 | * PARAMETERS: Pathname - Full pathname to the node (for error msgs) | 1060 | * PARAMETERS: Buffer - Pointer to where the string is returned |
996 | * package_index - Used to determine if target is in a package | 1061 | * expected_btypes - Bitmap of expected return type(s) |
997 | * return_object_ptr - Pointer to the object returned from the | ||
998 | * evaluation of a method or object | ||
999 | * | 1062 | * |
1000 | * RETURN: Status. AE_OK if repair was successful. | 1063 | * RETURN: Buffer is populated with type names. |
1001 | * | 1064 | * |
1002 | * 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 |
1003 | * not expected. | 1066 | * names of expected types, for use in warning messages. |
1004 | * | 1067 | * |
1005 | ******************************************************************************/ | 1068 | ******************************************************************************/ |
1006 | 1069 | ||
1007 | static acpi_status | 1070 | static void acpi_ns_get_expected_types(char *buffer, u32 expected_btypes) |
1008 | acpi_ns_repair_object(u32 expected_btypes, | ||
1009 | u32 package_index, | ||
1010 | union acpi_operand_object **return_object_ptr) | ||
1011 | { | 1071 | { |
1012 | union acpi_operand_object *return_object = *return_object_ptr; | 1072 | u32 this_rtype; |
1013 | union acpi_operand_object *new_object; | 1073 | u32 i; |
1014 | acpi_size length; | 1074 | u32 j; |
1015 | |||
1016 | switch (return_object->common.type) { | ||
1017 | case ACPI_TYPE_BUFFER: | ||
1018 | |||
1019 | if (!(expected_btypes & ACPI_RTYPE_STRING)) { | ||
1020 | return (AE_AML_OPERAND_TYPE); | ||
1021 | } | ||
1022 | |||
1023 | /* | ||
1024 | * Have a Buffer, expected a String, convert. Use a to_string | ||
1025 | * conversion, no transform performed on the buffer data. The best | ||
1026 | * example of this is the _BIF method, where the string data from | ||
1027 | * the battery is often (incorrectly) returned as buffer object(s). | ||
1028 | */ | ||
1029 | length = 0; | ||
1030 | while ((length < return_object->buffer.length) && | ||
1031 | (return_object->buffer.pointer[length])) { | ||
1032 | length++; | ||
1033 | } | ||
1034 | |||
1035 | /* Allocate a new string object */ | ||
1036 | |||
1037 | new_object = acpi_ut_create_string_object(length); | ||
1038 | if (!new_object) { | ||
1039 | return (AE_NO_MEMORY); | ||
1040 | } | ||
1041 | 1075 | ||
1042 | /* | 1076 | j = 1; |
1043 | * Copy the raw buffer data with no transform. String is already NULL | 1077 | buffer[0] = 0; |
1044 | * terminated at Length+1. | 1078 | this_rtype = ACPI_RTYPE_INTEGER; |
1045 | */ | ||
1046 | ACPI_MEMCPY(new_object->string.pointer, | ||
1047 | return_object->buffer.pointer, length); | ||
1048 | 1079 | ||
1049 | /* Install the new return object */ | 1080 | for (i = 0; i < ACPI_NUM_RTYPES; i++) { |
1050 | 1081 | ||
1051 | acpi_ut_remove_reference(return_object); | 1082 | /* If one of the expected types, concatenate the name of this type */ |
1052 | *return_object_ptr = new_object; | ||
1053 | 1083 | ||
1054 | /* | 1084 | if (expected_btypes & this_rtype) { |
1055 | * If the object is a package element, we need to: | 1085 | ACPI_STRCAT(buffer, &acpi_rtype_names[i][j]); |
1056 | * 1. Decrement the reference count of the orignal object, it was | 1086 | j = 0; /* Use name separator from now on */ |
1057 | * incremented when building the package | ||
1058 | * 2. Increment the reference count of the new object, it will be | ||
1059 | * decremented when releasing the package | ||
1060 | */ | ||
1061 | if (package_index != ACPI_NOT_PACKAGE) { | ||
1062 | acpi_ut_remove_reference(return_object); | ||
1063 | acpi_ut_add_reference(new_object); | ||
1064 | } | 1087 | } |
1065 | return (AE_OK); | 1088 | this_rtype <<= 1; /* Next Rtype */ |
1066 | |||
1067 | default: | ||
1068 | break; | ||
1069 | } | 1089 | } |
1070 | |||
1071 | return (AE_AML_OPERAND_TYPE); | ||
1072 | } | 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/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/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 f23593d6add4..ddc84af6336e 100644 --- a/drivers/acpi/acpica/nsxfname.c +++ b/drivers/acpi/acpica/nsxfname.c | |||
@@ -51,6 +51,11 @@ | |||
51 | #define _COMPONENT ACPI_NAMESPACE | 51 | #define _COMPONENT ACPI_NAMESPACE |
52 | ACPI_MODULE_NAME("nsxfname") | 52 | ACPI_MODULE_NAME("nsxfname") |
53 | 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 | |||
54 | /****************************************************************************** | 59 | /****************************************************************************** |
55 | * | 60 | * |
56 | * FUNCTION: acpi_get_handle | 61 | * FUNCTION: acpi_get_handle |
@@ -68,6 +73,7 @@ ACPI_MODULE_NAME("nsxfname") | |||
68 | * namespace handle. | 73 | * namespace handle. |
69 | * | 74 | * |
70 | ******************************************************************************/ | 75 | ******************************************************************************/ |
76 | |||
71 | acpi_status | 77 | acpi_status |
72 | acpi_get_handle(acpi_handle parent, | 78 | acpi_get_handle(acpi_handle parent, |
73 | acpi_string pathname, acpi_handle * ret_handle) | 79 | acpi_string pathname, acpi_handle * ret_handle) |
@@ -210,10 +216,38 @@ ACPI_EXPORT_SYMBOL(acpi_get_name) | |||
210 | 216 | ||
211 | /****************************************************************************** | 217 | /****************************************************************************** |
212 | * | 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 | * | ||
213 | * FUNCTION: acpi_get_object_info | 247 | * FUNCTION: acpi_get_object_info |
214 | * | 248 | * |
215 | * PARAMETERS: Handle - Object Handle | 249 | * PARAMETERS: Handle - Object Handle |
216 | * Buffer - Where the info is returned | 250 | * return_buffer - Where the info is returned |
217 | * | 251 | * |
218 | * RETURN: Status | 252 | * RETURN: Status |
219 | * | 253 | * |
@@ -221,33 +255,37 @@ ACPI_EXPORT_SYMBOL(acpi_get_name) | |||
221 | * namespace node and possibly by running several standard | 255 | * namespace node and possibly by running several standard |
222 | * control methods (Such as in the case of a device.) | 256 | * control methods (Such as in the case of a device.) |
223 | * | 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 | * | ||
224 | ******************************************************************************/ | 263 | ******************************************************************************/ |
264 | |||
225 | acpi_status | 265 | acpi_status |
226 | 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) | ||
227 | { | 268 | { |
228 | acpi_status status; | ||
229 | struct acpi_namespace_node *node; | 269 | struct acpi_namespace_node *node; |
230 | struct acpi_device_info *info; | 270 | struct acpi_device_info *info; |
231 | struct acpi_device_info *return_info; | 271 | struct acpica_device_id_list *cid_list = NULL; |
232 | struct acpi_compatible_id_list *cid_list = NULL; | 272 | struct acpica_device_id *hid = NULL; |
233 | 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; | ||
234 | 282 | ||
235 | /* Parameter validation */ | 283 | /* Parameter validation */ |
236 | 284 | ||
237 | if (!handle || !buffer) { | 285 | if (!handle || !return_buffer) { |
238 | return (AE_BAD_PARAMETER); | 286 | return (AE_BAD_PARAMETER); |
239 | } | 287 | } |
240 | 288 | ||
241 | status = acpi_ut_validate_buffer(buffer); | ||
242 | if (ACPI_FAILURE(status)) { | ||
243 | return (status); | ||
244 | } | ||
245 | |||
246 | info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_device_info)); | ||
247 | if (!info) { | ||
248 | return (AE_NO_MEMORY); | ||
249 | } | ||
250 | |||
251 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | 289 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); |
252 | if (ACPI_FAILURE(status)) { | 290 | if (ACPI_FAILURE(status)) { |
253 | goto cleanup; | 291 | goto cleanup; |
@@ -256,66 +294,91 @@ acpi_get_object_info(acpi_handle handle, struct acpi_buffer * buffer) | |||
256 | node = acpi_ns_map_handle_to_node(handle); | 294 | node = acpi_ns_map_handle_to_node(handle); |
257 | if (!node) { | 295 | if (!node) { |
258 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | 296 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); |
259 | status = AE_BAD_PARAMETER; | 297 | return (AE_BAD_PARAMETER); |
260 | goto cleanup; | ||
261 | } | 298 | } |
262 | 299 | ||
263 | /* Init return structure */ | 300 | /* Get the namespace node data while the namespace is locked */ |
264 | |||
265 | size = sizeof(struct acpi_device_info); | ||
266 | 301 | ||
267 | info->type = node->type; | 302 | info_size = sizeof(struct acpi_device_info); |
268 | info->name = node->name.integer; | 303 | type = node->type; |
269 | info->valid = 0; | 304 | name = node->name.integer; |
270 | 305 | ||
271 | if (node->type == ACPI_TYPE_METHOD) { | 306 | if (node->type == ACPI_TYPE_METHOD) { |
272 | info->param_count = node->object->method.param_count; | 307 | param_count = node->object->method.param_count; |
273 | } | 308 | } |
274 | 309 | ||
275 | status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | 310 | status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); |
276 | if (ACPI_FAILURE(status)) { | 311 | if (ACPI_FAILURE(status)) { |
277 | goto cleanup; | 312 | return (status); |
278 | } | 313 | } |
279 | 314 | ||
280 | /* If not a device, we are all done */ | 315 | if ((type == ACPI_TYPE_DEVICE) || (type == ACPI_TYPE_PROCESSOR)) { |
281 | |||
282 | if (info->type == ACPI_TYPE_DEVICE) { | ||
283 | /* | 316 | /* |
284 | * Get extra info for ACPI Devices objects only: | 317 | * Get extra info for ACPI Device/Processor objects only: |
285 | * Run the Device _HID, _UID, _CID, _STA, _ADR and _sx_d methods. | 318 | * Run the Device _HID, _UID, and _CID methods. |
286 | * | 319 | * |
287 | * 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 |
288 | * 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 |
289 | * to indicate which methods were found and ran successfully. | 322 | * to indicate which methods were found and run successfully. |
290 | */ | 323 | */ |
291 | 324 | ||
292 | /* Execute the Device._HID method */ | 325 | /* Execute the Device._HID method */ |
293 | 326 | ||
294 | status = acpi_ut_execute_HID(node, &info->hardware_id); | 327 | status = acpi_ut_execute_HID(node, &hid); |
295 | if (ACPI_SUCCESS(status)) { | 328 | if (ACPI_SUCCESS(status)) { |
296 | info->valid |= ACPI_VALID_HID; | 329 | info_size += hid->length; |
330 | valid |= ACPI_VALID_HID; | ||
297 | } | 331 | } |
298 | 332 | ||
299 | /* Execute the Device._UID method */ | 333 | /* Execute the Device._UID method */ |
300 | 334 | ||
301 | status = acpi_ut_execute_UID(node, &info->unique_id); | 335 | status = acpi_ut_execute_UID(node, &uid); |
302 | if (ACPI_SUCCESS(status)) { | 336 | if (ACPI_SUCCESS(status)) { |
303 | info->valid |= ACPI_VALID_UID; | 337 | info_size += uid->length; |
338 | valid |= ACPI_VALID_UID; | ||
304 | } | 339 | } |
305 | 340 | ||
306 | /* Execute the Device._CID method */ | 341 | /* Execute the Device._CID method */ |
307 | 342 | ||
308 | status = acpi_ut_execute_CID(node, &cid_list); | 343 | status = acpi_ut_execute_CID(node, &cid_list); |
309 | if (ACPI_SUCCESS(status)) { | 344 | if (ACPI_SUCCESS(status)) { |
310 | size += cid_list->size; | 345 | |
311 | 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; | ||
312 | } | 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 | */ | ||
313 | 376 | ||
314 | /* Execute the Device._STA method */ | 377 | /* Execute the Device._STA method */ |
315 | 378 | ||
316 | status = acpi_ut_execute_STA(node, &info->current_status); | 379 | status = acpi_ut_execute_STA(node, &info->current_status); |
317 | if (ACPI_SUCCESS(status)) { | 380 | if (ACPI_SUCCESS(status)) { |
318 | info->valid |= ACPI_VALID_STA; | 381 | valid |= ACPI_VALID_STA; |
319 | } | 382 | } |
320 | 383 | ||
321 | /* Execute the Device._ADR method */ | 384 | /* Execute the Device._ADR method */ |
@@ -323,36 +386,100 @@ acpi_get_object_info(acpi_handle handle, struct acpi_buffer * buffer) | |||
323 | status = acpi_ut_evaluate_numeric_object(METHOD_NAME__ADR, node, | 386 | status = acpi_ut_evaluate_numeric_object(METHOD_NAME__ADR, node, |
324 | &info->address); | 387 | &info->address); |
325 | if (ACPI_SUCCESS(status)) { | 388 | if (ACPI_SUCCESS(status)) { |
326 | 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; | ||
327 | } | 400 | } |
328 | 401 | ||
329 | /* Execute the Device._sx_d methods */ | 402 | /* Execute the Device._sx_d methods */ |
330 | 403 | ||
331 | 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); | ||
332 | if (ACPI_SUCCESS(status)) { | 408 | if (ACPI_SUCCESS(status)) { |
333 | info->valid |= ACPI_VALID_SXDS; | 409 | valid |= ACPI_VALID_SXDS; |
334 | } | 410 | } |
335 | } | 411 | } |
336 | 412 | ||
337 | /* 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) { | ||
338 | 419 | ||
339 | status = acpi_ut_initialize_buffer(buffer, size); | 420 | /* Point past the CID DEVICE_ID array */ |
340 | if (ACPI_FAILURE(status)) { | 421 | |
341 | goto cleanup; | 422 | next_id_string += |
423 | ((acpi_size) cid_list->count * | ||
424 | sizeof(struct acpica_device_id)); | ||
342 | } | 425 | } |
343 | 426 | ||
344 | /* 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 | } | ||
345 | 441 | ||
346 | return_info = buffer->pointer; | 442 | if (uid) { |
347 | 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 | } | ||
348 | 446 | ||
349 | if (cid_list) { | 447 | if (cid_list) { |
350 | ACPI_MEMCPY(&return_info->compatibility_id, cid_list, | 448 | info->compatible_id_list.count = cid_list->count; |
351 | 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 | } | ||
352 | } | 463 | } |
353 | 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 | |||
354 | cleanup: | 476 | cleanup: |
355 | ACPI_FREE(info); | 477 | if (hid) { |
478 | ACPI_FREE(hid); | ||
479 | } | ||
480 | if (uid) { | ||
481 | ACPI_FREE(uid); | ||
482 | } | ||
356 | if (cid_list) { | 483 | if (cid_list) { |
357 | ACPI_FREE(cid_list); | 484 | ACPI_FREE(cid_list); |
358 | } | 485 | } |
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/tbfadt.c b/drivers/acpi/acpica/tbfadt.c index 82b02dcb942e..c016335fb759 100644 --- a/drivers/acpi/acpica/tbfadt.c +++ b/drivers/acpi/acpica/tbfadt.c | |||
@@ -275,7 +275,6 @@ void acpi_tb_parse_fadt(u32 table_index) | |||
275 | 275 | ||
276 | void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length) | 276 | void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length) |
277 | { | 277 | { |
278 | |||
279 | /* | 278 | /* |
280 | * Check if the FADT is larger than the largest table that we expect | 279 | * Check if the FADT is larger than the largest table that we expect |
281 | * (the ACPI 2.0/3.0 version). If so, truncate the table, and issue | 280 | * (the ACPI 2.0/3.0 version). If so, truncate the table, and issue |
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/utdelete.c b/drivers/acpi/acpica/utdelete.c index bc1710315088..96e26e70c63d 100644 --- a/drivers/acpi/acpica/utdelete.c +++ b/drivers/acpi/acpica/utdelete.c | |||
@@ -215,6 +215,12 @@ static void acpi_ut_delete_internal_obj(union acpi_operand_object *object) | |||
215 | ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, | 215 | ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, |
216 | "***** Region %p\n", object)); | 216 | "***** Region %p\n", object)); |
217 | 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 | |||
218 | second_desc = acpi_ns_get_secondary_object(object); | 224 | second_desc = acpi_ns_get_secondary_object(object); |
219 | if (second_desc) { | 225 | if (second_desc) { |
220 | /* | 226 | /* |
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 fbe782348b0b..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 |
@@ -1037,8 +1070,7 @@ acpi_error(const char *module_name, u32 line_number, const char *format, ...) | |||
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(" %8.8X %s-%u\n", ACPI_CA_VERSION, module_name, | 1073 | ACPI_COMMON_MSG_SUFFIX; |
1041 | line_number); | ||
1042 | va_end(args); | 1074 | va_end(args); |
1043 | } | 1075 | } |
1044 | 1076 | ||
@@ -1052,8 +1084,7 @@ acpi_exception(const char *module_name, | |||
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(" %8.8X %s-%u\n", ACPI_CA_VERSION, module_name, | 1087 | ACPI_COMMON_MSG_SUFFIX; |
1056 | line_number); | ||
1057 | va_end(args); | 1088 | va_end(args); |
1058 | } | 1089 | } |
1059 | 1090 | ||
@@ -1066,8 +1097,7 @@ acpi_warning(const char *module_name, u32 line_number, const char *format, ...) | |||
1066 | 1097 | ||
1067 | va_start(args, format); | 1098 | va_start(args, format); |
1068 | acpi_os_vprintf(format, args); | 1099 | acpi_os_vprintf(format, args); |
1069 | acpi_os_printf(" %8.8X %s-%u\n", ACPI_CA_VERSION, module_name, | 1100 | ACPI_COMMON_MSG_SUFFIX; |
1070 | line_number); | ||
1071 | va_end(args); | 1101 | va_end(args); |
1072 | } | 1102 | } |
1073 | 1103 | ||
@@ -1088,3 +1118,46 @@ ACPI_EXPORT_SYMBOL(acpi_error) | |||
1088 | ACPI_EXPORT_SYMBOL(acpi_exception) | 1118 | ACPI_EXPORT_SYMBOL(acpi_exception) |
1089 | ACPI_EXPORT_SYMBOL(acpi_warning) | 1119 | ACPI_EXPORT_SYMBOL(acpi_warning) |
1090 | 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/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 58b4517ce712..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 |
diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c index f6baa77deefb..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; |
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index 2876fc70c3a9..135fbfe1825c 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include <linux/pci.h> | 38 | #include <linux/pci.h> |
39 | #include <acpi/acpi_bus.h> | 39 | #include <acpi/acpi_bus.h> |
40 | #include <acpi/acpi_drivers.h> | 40 | #include <acpi/acpi_drivers.h> |
41 | #include <linux/dmi.h> | ||
41 | 42 | ||
42 | #include "internal.h" | 43 | #include "internal.h" |
43 | 44 | ||
@@ -141,7 +142,7 @@ int acpi_bus_get_status(struct acpi_device *device) | |||
141 | EXPORT_SYMBOL(acpi_bus_get_status); | 142 | EXPORT_SYMBOL(acpi_bus_get_status); |
142 | 143 | ||
143 | void acpi_bus_private_data_handler(acpi_handle handle, | 144 | void acpi_bus_private_data_handler(acpi_handle handle, |
144 | u32 function, void *context) | 145 | void *context) |
145 | { | 146 | { |
146 | return; | 147 | return; |
147 | } | 148 | } |
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c index ebb593e9c380..9335b87c5174 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/debug.c b/drivers/acpi/debug.c index a8287be0870e..8a690c3b8e23 100644 --- a/drivers/acpi/debug.c +++ b/drivers/acpi/debug.c | |||
@@ -3,6 +3,7 @@ | |||
3 | */ | 3 | */ |
4 | 4 | ||
5 | #include <linux/proc_fs.h> | 5 | #include <linux/proc_fs.h> |
6 | #include <linux/seq_file.h> | ||
6 | #include <linux/init.h> | 7 | #include <linux/init.h> |
7 | #include <linux/module.h> | 8 | #include <linux/module.h> |
8 | #include <linux/kernel.h> | 9 | #include <linux/kernel.h> |
@@ -201,72 +202,54 @@ module_param_call(trace_state, param_set_trace_state, param_get_trace_state, | |||
201 | #define ACPI_SYSTEM_FILE_DEBUG_LAYER "debug_layer" | 202 | #define ACPI_SYSTEM_FILE_DEBUG_LAYER "debug_layer" |
202 | #define ACPI_SYSTEM_FILE_DEBUG_LEVEL "debug_level" | 203 | #define ACPI_SYSTEM_FILE_DEBUG_LEVEL "debug_level" |
203 | 204 | ||
204 | static int | 205 | static int acpi_system_debug_proc_show(struct seq_file *m, void *v) |
205 | acpi_system_read_debug(char *page, | ||
206 | char **start, off_t off, int count, int *eof, void *data) | ||
207 | { | 206 | { |
208 | char *p = page; | ||
209 | int size = 0; | ||
210 | unsigned int i; | 207 | unsigned int i; |
211 | 208 | ||
212 | if (off != 0) | 209 | seq_printf(m, "%-25s\tHex SET\n", "Description"); |
213 | goto end; | ||
214 | 210 | ||
215 | p += sprintf(p, "%-25s\tHex SET\n", "Description"); | 211 | switch ((unsigned long)m->private) { |
216 | |||
217 | switch ((unsigned long)data) { | ||
218 | case 0: | 212 | case 0: |
219 | for (i = 0; i < ARRAY_SIZE(acpi_debug_layers); i++) { | 213 | for (i = 0; i < ARRAY_SIZE(acpi_debug_layers); i++) { |
220 | p += sprintf(p, "%-25s\t0x%08lX [%c]\n", | 214 | seq_printf(m, "%-25s\t0x%08lX [%c]\n", |
221 | acpi_debug_layers[i].name, | 215 | acpi_debug_layers[i].name, |
222 | acpi_debug_layers[i].value, | 216 | acpi_debug_layers[i].value, |
223 | (acpi_dbg_layer & acpi_debug_layers[i]. | 217 | (acpi_dbg_layer & acpi_debug_layers[i]. |
224 | value) ? '*' : ' '); | 218 | value) ? '*' : ' '); |
225 | } | 219 | } |
226 | p += sprintf(p, "%-25s\t0x%08X [%c]\n", "ACPI_ALL_DRIVERS", | 220 | seq_printf(m, "%-25s\t0x%08X [%c]\n", "ACPI_ALL_DRIVERS", |
227 | ACPI_ALL_DRIVERS, | 221 | ACPI_ALL_DRIVERS, |
228 | (acpi_dbg_layer & ACPI_ALL_DRIVERS) == | 222 | (acpi_dbg_layer & ACPI_ALL_DRIVERS) == |
229 | ACPI_ALL_DRIVERS ? '*' : (acpi_dbg_layer & | 223 | ACPI_ALL_DRIVERS ? '*' : (acpi_dbg_layer & |
230 | ACPI_ALL_DRIVERS) == | 224 | ACPI_ALL_DRIVERS) == |
231 | 0 ? ' ' : '-'); | 225 | 0 ? ' ' : '-'); |
232 | p += sprintf(p, | 226 | seq_printf(m, |
233 | "--\ndebug_layer = 0x%08X (* = enabled, - = partial)\n", | 227 | "--\ndebug_layer = 0x%08X (* = enabled, - = partial)\n", |
234 | acpi_dbg_layer); | 228 | acpi_dbg_layer); |
235 | break; | 229 | break; |
236 | case 1: | 230 | case 1: |
237 | for (i = 0; i < ARRAY_SIZE(acpi_debug_levels); i++) { | 231 | for (i = 0; i < ARRAY_SIZE(acpi_debug_levels); i++) { |
238 | p += sprintf(p, "%-25s\t0x%08lX [%c]\n", | 232 | seq_printf(m, "%-25s\t0x%08lX [%c]\n", |
239 | acpi_debug_levels[i].name, | 233 | acpi_debug_levels[i].name, |
240 | acpi_debug_levels[i].value, | 234 | acpi_debug_levels[i].value, |
241 | (acpi_dbg_level & acpi_debug_levels[i]. | 235 | (acpi_dbg_level & acpi_debug_levels[i]. |
242 | value) ? '*' : ' '); | 236 | value) ? '*' : ' '); |
243 | } | 237 | } |
244 | p += sprintf(p, "--\ndebug_level = 0x%08X (* = enabled)\n", | 238 | seq_printf(m, "--\ndebug_level = 0x%08X (* = enabled)\n", |
245 | acpi_dbg_level); | 239 | acpi_dbg_level); |
246 | break; | 240 | break; |
247 | default: | ||
248 | p += sprintf(p, "Invalid debug option\n"); | ||
249 | break; | ||
250 | } | 241 | } |
242 | return 0; | ||
243 | } | ||
251 | 244 | ||
252 | end: | 245 | static int acpi_system_debug_proc_open(struct inode *inode, struct file *file) |
253 | size = (p - page); | 246 | { |
254 | if (size <= off + count) | 247 | return single_open(file, acpi_system_debug_proc_show, PDE(inode)->data); |
255 | *eof = 1; | ||
256 | *start = page + off; | ||
257 | size -= off; | ||
258 | if (size > count) | ||
259 | size = count; | ||
260 | if (size < 0) | ||
261 | size = 0; | ||
262 | |||
263 | return size; | ||
264 | } | 248 | } |
265 | 249 | ||
266 | static int | 250 | static ssize_t acpi_system_debug_proc_write(struct file *file, |
267 | acpi_system_write_debug(struct file *file, | ||
268 | const char __user * buffer, | 251 | const char __user * buffer, |
269 | unsigned long count, void *data) | 252 | size_t count, loff_t *pos) |
270 | { | 253 | { |
271 | char debug_string[12] = { '\0' }; | 254 | char debug_string[12] = { '\0' }; |
272 | 255 | ||
@@ -279,7 +262,7 @@ acpi_system_write_debug(struct file *file, | |||
279 | 262 | ||
280 | debug_string[count] = '\0'; | 263 | debug_string[count] = '\0'; |
281 | 264 | ||
282 | switch ((unsigned long)data) { | 265 | switch ((unsigned long)PDE(file->f_path.dentry->d_inode)->data) { |
283 | case 0: | 266 | case 0: |
284 | acpi_dbg_layer = simple_strtoul(debug_string, NULL, 0); | 267 | acpi_dbg_layer = simple_strtoul(debug_string, NULL, 0); |
285 | break; | 268 | break; |
@@ -292,6 +275,15 @@ acpi_system_write_debug(struct file *file, | |||
292 | 275 | ||
293 | return count; | 276 | return count; |
294 | } | 277 | } |
278 | |||
279 | static const struct file_operations acpi_system_debug_proc_fops = { | ||
280 | .owner = THIS_MODULE, | ||
281 | .open = acpi_system_debug_proc_open, | ||
282 | .read = seq_read, | ||
283 | .llseek = seq_lseek, | ||
284 | .release = single_release, | ||
285 | .write = acpi_system_debug_proc_write, | ||
286 | }; | ||
295 | #endif | 287 | #endif |
296 | 288 | ||
297 | int __init acpi_debug_init(void) | 289 | int __init acpi_debug_init(void) |
@@ -303,24 +295,18 @@ int __init acpi_debug_init(void) | |||
303 | 295 | ||
304 | /* 'debug_layer' [R/W] */ | 296 | /* 'debug_layer' [R/W] */ |
305 | name = ACPI_SYSTEM_FILE_DEBUG_LAYER; | 297 | name = ACPI_SYSTEM_FILE_DEBUG_LAYER; |
306 | entry = | 298 | entry = proc_create_data(name, S_IFREG | S_IRUGO | S_IWUSR, |
307 | create_proc_read_entry(name, S_IFREG | S_IRUGO | S_IWUSR, | 299 | acpi_root_dir, &acpi_system_debug_proc_fops, |
308 | acpi_root_dir, acpi_system_read_debug, | 300 | (void *)0); |
309 | (void *)0); | 301 | if (!entry) |
310 | if (entry) | ||
311 | entry->write_proc = acpi_system_write_debug; | ||
312 | else | ||
313 | goto Error; | 302 | goto Error; |
314 | 303 | ||
315 | /* 'debug_level' [R/W] */ | 304 | /* 'debug_level' [R/W] */ |
316 | name = ACPI_SYSTEM_FILE_DEBUG_LEVEL; | 305 | name = ACPI_SYSTEM_FILE_DEBUG_LEVEL; |
317 | entry = | 306 | entry = proc_create_data(name, S_IFREG | S_IRUGO | S_IWUSR, |
318 | create_proc_read_entry(name, S_IFREG | S_IRUGO | S_IWUSR, | 307 | acpi_root_dir, &acpi_system_debug_proc_fops, |
319 | acpi_root_dir, acpi_system_read_debug, | 308 | (void *)1); |
320 | (void *)1); | 309 | if (!entry) |
321 | if (entry) | ||
322 | entry->write_proc = acpi_system_write_debug; | ||
323 | else | ||
324 | goto Error; | 310 | goto Error; |
325 | 311 | ||
326 | Done: | 312 | Done: |
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..f70796081c4c 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
@@ -42,12 +42,12 @@ | |||
42 | #include <asm/io.h> | 42 | #include <asm/io.h> |
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 | #include <linux/dmi.h> | ||
45 | 46 | ||
46 | #define ACPI_EC_CLASS "embedded_controller" | 47 | #define ACPI_EC_CLASS "embedded_controller" |
47 | #define ACPI_EC_DEVICE_NAME "Embedded Controller" | 48 | #define ACPI_EC_DEVICE_NAME "Embedded Controller" |
48 | #define ACPI_EC_FILE_INFO "info" | 49 | #define ACPI_EC_FILE_INFO "info" |
49 | 50 | ||
50 | #undef PREFIX | ||
51 | #define PREFIX "ACPI: EC: " | 51 | #define PREFIX "ACPI: EC: " |
52 | 52 | ||
53 | /* EC status register */ | 53 | /* EC status register */ |
@@ -68,15 +68,13 @@ enum ec_command { | |||
68 | #define ACPI_EC_DELAY 500 /* Wait 500ms max. during EC ops */ | 68 | #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 */ | 69 | #define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */ |
70 | #define ACPI_EC_CDELAY 10 /* Wait 10us before polling EC */ | 70 | #define ACPI_EC_CDELAY 10 /* Wait 10us before polling EC */ |
71 | #define ACPI_EC_MSI_UDELAY 550 /* Wait 550us for MSI EC */ | ||
71 | 72 | ||
72 | #define ACPI_EC_STORM_THRESHOLD 8 /* number of false interrupts | 73 | #define ACPI_EC_STORM_THRESHOLD 8 /* number of false interrupts |
73 | per one transaction */ | 74 | per one transaction */ |
74 | 75 | ||
75 | enum { | 76 | enum { |
76 | EC_FLAGS_QUERY_PENDING, /* Query is pending */ | 77 | 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 */ | 78 | EC_FLAGS_GPE_STORM, /* GPE storm detected */ |
81 | EC_FLAGS_HANDLERS_INSTALLED /* Handlers for GPE and | 79 | EC_FLAGS_HANDLERS_INSTALLED /* Handlers for GPE and |
82 | * OpReg are installed */ | 80 | * OpReg are installed */ |
@@ -170,7 +168,7 @@ static void start_transaction(struct acpi_ec *ec) | |||
170 | acpi_ec_write_cmd(ec, ec->curr->command); | 168 | acpi_ec_write_cmd(ec, ec->curr->command); |
171 | } | 169 | } |
172 | 170 | ||
173 | static void gpe_transaction(struct acpi_ec *ec, u8 status) | 171 | static void advance_transaction(struct acpi_ec *ec, u8 status) |
174 | { | 172 | { |
175 | unsigned long flags; | 173 | unsigned long flags; |
176 | spin_lock_irqsave(&ec->curr_lock, flags); | 174 | spin_lock_irqsave(&ec->curr_lock, flags); |
@@ -201,29 +199,6 @@ unlock: | |||
201 | spin_unlock_irqrestore(&ec->curr_lock, flags); | 199 | spin_unlock_irqrestore(&ec->curr_lock, flags); |
202 | } | 200 | } |
203 | 201 | ||
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); | 202 | static void acpi_ec_gpe_query(void *ec_cxt); |
228 | 203 | ||
229 | static int ec_check_sci(struct acpi_ec *ec, u8 state) | 204 | static int ec_check_sci(struct acpi_ec *ec, u8 state) |
@@ -236,43 +211,51 @@ static int ec_check_sci(struct acpi_ec *ec, u8 state) | |||
236 | return 0; | 211 | return 0; |
237 | } | 212 | } |
238 | 213 | ||
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) | 214 | static int ec_poll(struct acpi_ec *ec) |
250 | { | 215 | { |
251 | unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY); | 216 | unsigned long flags; |
252 | udelay(ACPI_EC_CDELAY); | 217 | int repeat = 2; /* number of command restarts */ |
253 | while (time_before(jiffies, delay)) { | 218 | while (repeat--) { |
254 | gpe_transaction(ec, acpi_ec_read_status(ec)); | 219 | unsigned long delay = jiffies + |
255 | ec_delay(); | 220 | msecs_to_jiffies(ACPI_EC_DELAY); |
256 | if (ec_transaction_done(ec)) | 221 | do { |
257 | return 0; | 222 | /* don't sleep with disabled interrupts */ |
223 | if (EC_FLAGS_MSI || irqs_disabled()) { | ||
224 | udelay(ACPI_EC_MSI_UDELAY); | ||
225 | if (ec_transaction_done(ec)) | ||
226 | return 0; | ||
227 | } else { | ||
228 | if (wait_event_timeout(ec->wait, | ||
229 | ec_transaction_done(ec), | ||
230 | msecs_to_jiffies(1))) | ||
231 | return 0; | ||
232 | } | ||
233 | advance_transaction(ec, acpi_ec_read_status(ec)); | ||
234 | } while (time_before(jiffies, delay)); | ||
235 | if (!ec->curr->irq_count || | ||
236 | (acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF)) | ||
237 | break; | ||
238 | /* try restart command if we get any false interrupts */ | ||
239 | pr_debug(PREFIX "controller reset, restart transaction\n"); | ||
240 | spin_lock_irqsave(&ec->curr_lock, flags); | ||
241 | start_transaction(ec); | ||
242 | spin_unlock_irqrestore(&ec->curr_lock, flags); | ||
258 | } | 243 | } |
259 | return -ETIME; | 244 | return -ETIME; |
260 | } | 245 | } |
261 | 246 | ||
262 | static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, | 247 | static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, |
263 | struct transaction *t, | 248 | struct transaction *t) |
264 | int force_poll) | ||
265 | { | 249 | { |
266 | unsigned long tmp; | 250 | unsigned long tmp; |
267 | int ret = 0; | 251 | int ret = 0; |
268 | pr_debug(PREFIX "transaction start\n"); | 252 | pr_debug(PREFIX "transaction start\n"); |
269 | /* disable GPE during transaction if storm is detected */ | 253 | /* disable GPE during transaction if storm is detected */ |
270 | if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) { | 254 | 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); | 255 | acpi_disable_gpe(NULL, ec->gpe); |
273 | } | 256 | } |
274 | if (EC_FLAGS_MSI) | 257 | if (EC_FLAGS_MSI) |
275 | udelay(ACPI_EC_DELAY); | 258 | udelay(ACPI_EC_MSI_UDELAY); |
276 | /* start transaction */ | 259 | /* start transaction */ |
277 | spin_lock_irqsave(&ec->curr_lock, tmp); | 260 | spin_lock_irqsave(&ec->curr_lock, tmp); |
278 | /* following two actions should be kept atomic */ | 261 | /* following two actions should be kept atomic */ |
@@ -281,11 +264,7 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, | |||
281 | if (ec->curr->command == ACPI_EC_COMMAND_QUERY) | 264 | if (ec->curr->command == ACPI_EC_COMMAND_QUERY) |
282 | clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); | 265 | clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); |
283 | spin_unlock_irqrestore(&ec->curr_lock, tmp); | 266 | spin_unlock_irqrestore(&ec->curr_lock, tmp); |
284 | /* if we selected poll mode or failed in GPE-mode do a poll loop */ | 267 | 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"); | 268 | pr_debug(PREFIX "transaction end\n"); |
290 | spin_lock_irqsave(&ec->curr_lock, tmp); | 269 | spin_lock_irqsave(&ec->curr_lock, tmp); |
291 | ec->curr = NULL; | 270 | ec->curr = NULL; |
@@ -295,8 +274,7 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, | |||
295 | ec_check_sci(ec, acpi_ec_read_status(ec)); | 274 | ec_check_sci(ec, acpi_ec_read_status(ec)); |
296 | /* it is safe to enable GPE outside of transaction */ | 275 | /* it is safe to enable GPE outside of transaction */ |
297 | acpi_enable_gpe(NULL, ec->gpe); | 276 | acpi_enable_gpe(NULL, ec->gpe); |
298 | } else if (test_bit(EC_FLAGS_GPE_MODE, &ec->flags) && | 277 | } else if (t->irq_count > ACPI_EC_STORM_THRESHOLD) { |
299 | t->irq_count > ACPI_EC_STORM_THRESHOLD) { | ||
300 | pr_info(PREFIX "GPE storm detected, " | 278 | pr_info(PREFIX "GPE storm detected, " |
301 | "transactions will use polling mode\n"); | 279 | "transactions will use polling mode\n"); |
302 | set_bit(EC_FLAGS_GPE_STORM, &ec->flags); | 280 | set_bit(EC_FLAGS_GPE_STORM, &ec->flags); |
@@ -314,16 +292,14 @@ static int ec_wait_ibf0(struct acpi_ec *ec) | |||
314 | { | 292 | { |
315 | unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY); | 293 | unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY); |
316 | /* interrupt wait manually if GPE mode is not active */ | 294 | /* 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)) | 295 | while (time_before(jiffies, delay)) |
320 | if (wait_event_timeout(ec->wait, ec_check_ibf0(ec), timeout)) | 296 | if (wait_event_timeout(ec->wait, ec_check_ibf0(ec), |
297 | msecs_to_jiffies(1))) | ||
321 | return 0; | 298 | return 0; |
322 | return -ETIME; | 299 | return -ETIME; |
323 | } | 300 | } |
324 | 301 | ||
325 | static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t, | 302 | static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t) |
326 | int force_poll) | ||
327 | { | 303 | { |
328 | int status; | 304 | int status; |
329 | u32 glk; | 305 | u32 glk; |
@@ -345,7 +321,7 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t, | |||
345 | status = -ETIME; | 321 | status = -ETIME; |
346 | goto end; | 322 | goto end; |
347 | } | 323 | } |
348 | status = acpi_ec_transaction_unlocked(ec, t, force_poll); | 324 | status = acpi_ec_transaction_unlocked(ec, t); |
349 | end: | 325 | end: |
350 | if (ec->global_lock) | 326 | if (ec->global_lock) |
351 | acpi_release_global_lock(glk); | 327 | acpi_release_global_lock(glk); |
@@ -354,10 +330,6 @@ unlock: | |||
354 | return status; | 330 | return status; |
355 | } | 331 | } |
356 | 332 | ||
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) | 333 | static int acpi_ec_burst_enable(struct acpi_ec *ec) |
362 | { | 334 | { |
363 | u8 d; | 335 | u8 d; |
@@ -365,7 +337,7 @@ static int acpi_ec_burst_enable(struct acpi_ec *ec) | |||
365 | .wdata = NULL, .rdata = &d, | 337 | .wdata = NULL, .rdata = &d, |
366 | .wlen = 0, .rlen = 1}; | 338 | .wlen = 0, .rlen = 1}; |
367 | 339 | ||
368 | return acpi_ec_transaction(ec, &t, 0); | 340 | return acpi_ec_transaction(ec, &t); |
369 | } | 341 | } |
370 | 342 | ||
371 | static int acpi_ec_burst_disable(struct acpi_ec *ec) | 343 | static int acpi_ec_burst_disable(struct acpi_ec *ec) |
@@ -375,7 +347,7 @@ static int acpi_ec_burst_disable(struct acpi_ec *ec) | |||
375 | .wlen = 0, .rlen = 0}; | 347 | .wlen = 0, .rlen = 0}; |
376 | 348 | ||
377 | return (acpi_ec_read_status(ec) & ACPI_EC_FLAG_BURST) ? | 349 | return (acpi_ec_read_status(ec) & ACPI_EC_FLAG_BURST) ? |
378 | acpi_ec_transaction(ec, &t, 0) : 0; | 350 | acpi_ec_transaction(ec, &t) : 0; |
379 | } | 351 | } |
380 | 352 | ||
381 | static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 * data) | 353 | static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 * data) |
@@ -386,7 +358,7 @@ static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 * data) | |||
386 | .wdata = &address, .rdata = &d, | 358 | .wdata = &address, .rdata = &d, |
387 | .wlen = 1, .rlen = 1}; | 359 | .wlen = 1, .rlen = 1}; |
388 | 360 | ||
389 | result = acpi_ec_transaction(ec, &t, 0); | 361 | result = acpi_ec_transaction(ec, &t); |
390 | *data = d; | 362 | *data = d; |
391 | return result; | 363 | return result; |
392 | } | 364 | } |
@@ -398,7 +370,7 @@ static int acpi_ec_write(struct acpi_ec *ec, u8 address, u8 data) | |||
398 | .wdata = wdata, .rdata = NULL, | 370 | .wdata = wdata, .rdata = NULL, |
399 | .wlen = 2, .rlen = 0}; | 371 | .wlen = 2, .rlen = 0}; |
400 | 372 | ||
401 | return acpi_ec_transaction(ec, &t, 0); | 373 | return acpi_ec_transaction(ec, &t); |
402 | } | 374 | } |
403 | 375 | ||
404 | /* | 376 | /* |
@@ -466,7 +438,7 @@ int ec_transaction(u8 command, | |||
466 | if (!first_ec) | 438 | if (!first_ec) |
467 | return -ENODEV; | 439 | return -ENODEV; |
468 | 440 | ||
469 | return acpi_ec_transaction(first_ec, &t, force_poll); | 441 | return acpi_ec_transaction(first_ec, &t); |
470 | } | 442 | } |
471 | 443 | ||
472 | EXPORT_SYMBOL(ec_transaction); | 444 | EXPORT_SYMBOL(ec_transaction); |
@@ -487,7 +459,7 @@ static int acpi_ec_query(struct acpi_ec *ec, u8 * data) | |||
487 | * bit to be cleared (and thus clearing the interrupt source). | 459 | * bit to be cleared (and thus clearing the interrupt source). |
488 | */ | 460 | */ |
489 | 461 | ||
490 | result = acpi_ec_transaction(ec, &t, 0); | 462 | result = acpi_ec_transaction(ec, &t); |
491 | if (result) | 463 | if (result) |
492 | return result; | 464 | return result; |
493 | 465 | ||
@@ -570,28 +542,10 @@ static u32 acpi_ec_gpe_handler(void *data) | |||
570 | pr_debug(PREFIX "~~~> interrupt\n"); | 542 | pr_debug(PREFIX "~~~> interrupt\n"); |
571 | status = acpi_ec_read_status(ec); | 543 | status = acpi_ec_read_status(ec); |
572 | 544 | ||
573 | if (test_bit(EC_FLAGS_GPE_MODE, &ec->flags)) { | 545 | advance_transaction(ec, status); |
574 | gpe_transaction(ec, status); | 546 | if (ec_transaction_done(ec) && (status & ACPI_EC_FLAG_IBF) == 0) |
575 | if (ec_transaction_done(ec) && | 547 | wake_up(&ec->wait); |
576 | (status & ACPI_EC_FLAG_IBF) == 0) | ||
577 | wake_up(&ec->wait); | ||
578 | } | ||
579 | |||
580 | ec_check_sci(ec, status); | 548 | 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; | 549 | return ACPI_INTERRUPT_HANDLED; |
596 | } | 550 | } |
597 | 551 | ||
@@ -617,7 +571,8 @@ acpi_ec_space_handler(u32 function, acpi_physical_address address, | |||
617 | if (bits != 8 && acpi_strict) | 571 | if (bits != 8 && acpi_strict) |
618 | return AE_BAD_PARAMETER; | 572 | return AE_BAD_PARAMETER; |
619 | 573 | ||
620 | acpi_ec_burst_enable(ec); | 574 | if (EC_FLAGS_MSI) |
575 | acpi_ec_burst_enable(ec); | ||
621 | 576 | ||
622 | if (function == ACPI_READ) { | 577 | if (function == ACPI_READ) { |
623 | result = acpi_ec_read(ec, address, &temp); | 578 | result = acpi_ec_read(ec, address, &temp); |
@@ -638,7 +593,8 @@ acpi_ec_space_handler(u32 function, acpi_physical_address address, | |||
638 | } | 593 | } |
639 | } | 594 | } |
640 | 595 | ||
641 | acpi_ec_burst_disable(ec); | 596 | if (EC_FLAGS_MSI) |
597 | acpi_ec_burst_disable(ec); | ||
642 | 598 | ||
643 | switch (result) { | 599 | switch (result) { |
644 | case -EINVAL: | 600 | case -EINVAL: |
@@ -788,6 +744,42 @@ ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval) | |||
788 | return AE_CTRL_TERMINATE; | 744 | return AE_CTRL_TERMINATE; |
789 | } | 745 | } |
790 | 746 | ||
747 | static int ec_install_handlers(struct acpi_ec *ec) | ||
748 | { | ||
749 | acpi_status status; | ||
750 | if (test_bit(EC_FLAGS_HANDLERS_INSTALLED, &ec->flags)) | ||
751 | return 0; | ||
752 | status = acpi_install_gpe_handler(NULL, ec->gpe, | ||
753 | ACPI_GPE_EDGE_TRIGGERED, | ||
754 | &acpi_ec_gpe_handler, ec); | ||
755 | if (ACPI_FAILURE(status)) | ||
756 | return -ENODEV; | ||
757 | acpi_set_gpe_type(NULL, ec->gpe, ACPI_GPE_TYPE_RUNTIME); | ||
758 | acpi_enable_gpe(NULL, ec->gpe); | ||
759 | status = acpi_install_address_space_handler(ec->handle, | ||
760 | ACPI_ADR_SPACE_EC, | ||
761 | &acpi_ec_space_handler, | ||
762 | NULL, ec); | ||
763 | if (ACPI_FAILURE(status)) { | ||
764 | if (status == AE_NOT_FOUND) { | ||
765 | /* | ||
766 | * Maybe OS fails in evaluating the _REG object. | ||
767 | * The AE_NOT_FOUND error will be ignored and OS | ||
768 | * continue to initialize EC. | ||
769 | */ | ||
770 | printk(KERN_ERR "Fail in evaluating the _REG object" | ||
771 | " of EC device. Broken bios is suspected.\n"); | ||
772 | } else { | ||
773 | acpi_remove_gpe_handler(NULL, ec->gpe, | ||
774 | &acpi_ec_gpe_handler); | ||
775 | return -ENODEV; | ||
776 | } | ||
777 | } | ||
778 | |||
779 | set_bit(EC_FLAGS_HANDLERS_INSTALLED, &ec->flags); | ||
780 | return 0; | ||
781 | } | ||
782 | |||
791 | static void ec_remove_handlers(struct acpi_ec *ec) | 783 | static void ec_remove_handlers(struct acpi_ec *ec) |
792 | { | 784 | { |
793 | if (ACPI_FAILURE(acpi_remove_address_space_handler(ec->handle, | 785 | if (ACPI_FAILURE(acpi_remove_address_space_handler(ec->handle, |
@@ -802,9 +794,8 @@ static void ec_remove_handlers(struct acpi_ec *ec) | |||
802 | static int acpi_ec_add(struct acpi_device *device) | 794 | static int acpi_ec_add(struct acpi_device *device) |
803 | { | 795 | { |
804 | struct acpi_ec *ec = NULL; | 796 | struct acpi_ec *ec = NULL; |
797 | int ret; | ||
805 | 798 | ||
806 | if (!device) | ||
807 | return -EINVAL; | ||
808 | strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME); | 799 | strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME); |
809 | strcpy(acpi_device_class(device), ACPI_EC_CLASS); | 800 | strcpy(acpi_device_class(device), ACPI_EC_CLASS); |
810 | 801 | ||
@@ -837,9 +828,12 @@ static int acpi_ec_add(struct acpi_device *device) | |||
837 | acpi_ec_add_fs(device); | 828 | acpi_ec_add_fs(device); |
838 | pr_info(PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n", | 829 | 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); | 830 | ec->gpe, ec->command_addr, ec->data_addr); |
840 | pr_info(PREFIX "driver started in %s mode\n", | 831 | |
841 | (test_bit(EC_FLAGS_GPE_MODE, &ec->flags))?"interrupt":"poll"); | 832 | ret = ec_install_handlers(ec); |
842 | return 0; | 833 | |
834 | /* EC is fully operational, allow queries */ | ||
835 | clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); | ||
836 | return ret; | ||
843 | } | 837 | } |
844 | 838 | ||
845 | static int acpi_ec_remove(struct acpi_device *device, int type) | 839 | static int acpi_ec_remove(struct acpi_device *device, int type) |
@@ -851,6 +845,7 @@ static int acpi_ec_remove(struct acpi_device *device, int type) | |||
851 | return -EINVAL; | 845 | return -EINVAL; |
852 | 846 | ||
853 | ec = acpi_driver_data(device); | 847 | ec = acpi_driver_data(device); |
848 | ec_remove_handlers(ec); | ||
854 | mutex_lock(&ec->lock); | 849 | mutex_lock(&ec->lock); |
855 | list_for_each_entry_safe(handler, tmp, &ec->list, node) { | 850 | list_for_each_entry_safe(handler, tmp, &ec->list, node) { |
856 | list_del(&handler->node); | 851 | list_del(&handler->node); |
@@ -888,75 +883,6 @@ ec_parse_io_ports(struct acpi_resource *resource, void *context) | |||
888 | return AE_OK; | 883 | return AE_OK; |
889 | } | 884 | } |
890 | 885 | ||
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) | 886 | int __init acpi_boot_ec_enable(void) |
961 | { | 887 | { |
962 | if (!boot_ec || test_bit(EC_FLAGS_HANDLERS_INSTALLED, &boot_ec->flags)) | 888 | if (!boot_ec || test_bit(EC_FLAGS_HANDLERS_INSTALLED, &boot_ec->flags)) |
@@ -1054,8 +980,6 @@ static int acpi_ec_suspend(struct acpi_device *device, pm_message_t state) | |||
1054 | { | 980 | { |
1055 | struct acpi_ec *ec = acpi_driver_data(device); | 981 | struct acpi_ec *ec = acpi_driver_data(device); |
1056 | /* Stop using GPE */ | 982 | /* 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); | 983 | acpi_disable_gpe(NULL, ec->gpe); |
1060 | return 0; | 984 | return 0; |
1061 | } | 985 | } |
@@ -1064,8 +988,6 @@ static int acpi_ec_resume(struct acpi_device *device) | |||
1064 | { | 988 | { |
1065 | struct acpi_ec *ec = acpi_driver_data(device); | 989 | struct acpi_ec *ec = acpi_driver_data(device); |
1066 | /* Enable use of GPE back */ | 990 | /* 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); | 991 | acpi_enable_gpe(NULL, ec->gpe); |
1070 | return 0; | 992 | return 0; |
1071 | } | 993 | } |
@@ -1077,8 +999,6 @@ static struct acpi_driver acpi_ec_driver = { | |||
1077 | .ops = { | 999 | .ops = { |
1078 | .add = acpi_ec_add, | 1000 | .add = acpi_ec_add, |
1079 | .remove = acpi_ec_remove, | 1001 | .remove = acpi_ec_remove, |
1080 | .start = acpi_ec_start, | ||
1081 | .stop = acpi_ec_stop, | ||
1082 | .suspend = acpi_ec_suspend, | 1002 | .suspend = acpi_ec_suspend, |
1083 | .resume = acpi_ec_resume, | 1003 | .resume = acpi_ec_resume, |
1084 | }, | 1004 | }, |
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 a8a5c29958c8..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 | } |
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 5691f165a952..5633b86e3ed1 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c | |||
@@ -58,6 +58,7 @@ struct acpi_os_dpc { | |||
58 | acpi_osd_exec_callback function; | 58 | acpi_osd_exec_callback function; |
59 | void *context; | 59 | void *context; |
60 | struct work_struct work; | 60 | struct work_struct work; |
61 | int wait; | ||
61 | }; | 62 | }; |
62 | 63 | ||
63 | #ifdef CONFIG_ACPI_CUSTOM_DSDT | 64 | #ifdef CONFIG_ACPI_CUSTOM_DSDT |
@@ -88,6 +89,7 @@ struct acpi_res_list { | |||
88 | char name[5]; /* only can have a length of 4 chars, make use of this | 89 | char name[5]; /* only can have a length of 4 chars, make use of this |
89 | one instead of res->name, no need to kalloc then */ | 90 | one instead of res->name, no need to kalloc then */ |
90 | struct list_head resource_list; | 91 | struct list_head resource_list; |
92 | int count; | ||
91 | }; | 93 | }; |
92 | 94 | ||
93 | static LIST_HEAD(resource_list_head); | 95 | static LIST_HEAD(resource_list_head); |
@@ -191,7 +193,7 @@ acpi_status __init acpi_os_initialize(void) | |||
191 | 193 | ||
192 | static void bind_to_cpu0(struct work_struct *work) | 194 | static void bind_to_cpu0(struct work_struct *work) |
193 | { | 195 | { |
194 | set_cpus_allowed(current, cpumask_of_cpu(0)); | 196 | set_cpus_allowed_ptr(current, cpumask_of(0)); |
195 | kfree(work); | 197 | kfree(work); |
196 | } | 198 | } |
197 | 199 | ||
@@ -697,31 +699,12 @@ void acpi_os_derive_pci_id(acpi_handle rhandle, /* upper bound */ | |||
697 | static void acpi_os_execute_deferred(struct work_struct *work) | 699 | static void acpi_os_execute_deferred(struct work_struct *work) |
698 | { | 700 | { |
699 | struct acpi_os_dpc *dpc = container_of(work, struct acpi_os_dpc, work); | 701 | struct acpi_os_dpc *dpc = container_of(work, struct acpi_os_dpc, work); |
700 | if (!dpc) { | ||
701 | printk(KERN_ERR PREFIX "Invalid (NULL) context\n"); | ||
702 | return; | ||
703 | } | ||
704 | |||
705 | dpc->function(dpc->context); | ||
706 | kfree(dpc); | ||
707 | |||
708 | return; | ||
709 | } | ||
710 | |||
711 | static void acpi_os_execute_hp_deferred(struct work_struct *work) | ||
712 | { | ||
713 | struct acpi_os_dpc *dpc = container_of(work, struct acpi_os_dpc, work); | ||
714 | if (!dpc) { | ||
715 | printk(KERN_ERR PREFIX "Invalid (NULL) context\n"); | ||
716 | return; | ||
717 | } | ||
718 | 702 | ||
719 | acpi_os_wait_events_complete(NULL); | 703 | if (dpc->wait) |
704 | acpi_os_wait_events_complete(NULL); | ||
720 | 705 | ||
721 | dpc->function(dpc->context); | 706 | dpc->function(dpc->context); |
722 | kfree(dpc); | 707 | kfree(dpc); |
723 | |||
724 | return; | ||
725 | } | 708 | } |
726 | 709 | ||
727 | /******************************************************************************* | 710 | /******************************************************************************* |
@@ -745,15 +728,11 @@ static acpi_status __acpi_os_execute(acpi_execute_type type, | |||
745 | acpi_status status = AE_OK; | 728 | acpi_status status = AE_OK; |
746 | struct acpi_os_dpc *dpc; | 729 | struct acpi_os_dpc *dpc; |
747 | struct workqueue_struct *queue; | 730 | struct workqueue_struct *queue; |
748 | work_func_t func; | ||
749 | int ret; | 731 | int ret; |
750 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | 732 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, |
751 | "Scheduling function [%p(%p)] for deferred execution.\n", | 733 | "Scheduling function [%p(%p)] for deferred execution.\n", |
752 | function, context)); | 734 | function, context)); |
753 | 735 | ||
754 | if (!function) | ||
755 | return AE_BAD_PARAMETER; | ||
756 | |||
757 | /* | 736 | /* |
758 | * Allocate/initialize DPC structure. Note that this memory will be | 737 | * Allocate/initialize DPC structure. Note that this memory will be |
759 | * freed by the callee. The kernel handles the work_struct list in a | 738 | * freed by the callee. The kernel handles the work_struct list in a |
@@ -778,8 +757,8 @@ static acpi_status __acpi_os_execute(acpi_execute_type type, | |||
778 | */ | 757 | */ |
779 | queue = hp ? kacpi_hotplug_wq : | 758 | queue = hp ? kacpi_hotplug_wq : |
780 | (type == OSL_NOTIFY_HANDLER ? kacpi_notify_wq : kacpid_wq); | 759 | (type == OSL_NOTIFY_HANDLER ? kacpi_notify_wq : kacpid_wq); |
781 | func = hp ? acpi_os_execute_hp_deferred : acpi_os_execute_deferred; | 760 | dpc->wait = hp ? 1 : 0; |
782 | INIT_WORK(&dpc->work, func); | 761 | INIT_WORK(&dpc->work, acpi_os_execute_deferred); |
783 | ret = queue_work(queue, &dpc->work); | 762 | ret = queue_work(queue, &dpc->work); |
784 | 763 | ||
785 | if (!ret) { | 764 | if (!ret) { |
@@ -1358,6 +1337,89 @@ acpi_os_validate_interface (char *interface) | |||
1358 | return AE_SUPPORT; | 1337 | return AE_SUPPORT; |
1359 | } | 1338 | } |
1360 | 1339 | ||
1340 | static inline int acpi_res_list_add(struct acpi_res_list *res) | ||
1341 | { | ||
1342 | struct acpi_res_list *res_list_elem; | ||
1343 | |||
1344 | list_for_each_entry(res_list_elem, &resource_list_head, | ||
1345 | resource_list) { | ||
1346 | |||
1347 | if (res->resource_type == res_list_elem->resource_type && | ||
1348 | res->start == res_list_elem->start && | ||
1349 | res->end == res_list_elem->end) { | ||
1350 | |||
1351 | /* | ||
1352 | * The Region(addr,len) already exist in the list, | ||
1353 | * just increase the count | ||
1354 | */ | ||
1355 | |||
1356 | res_list_elem->count++; | ||
1357 | return 0; | ||
1358 | } | ||
1359 | } | ||
1360 | |||
1361 | res->count = 1; | ||
1362 | list_add(&res->resource_list, &resource_list_head); | ||
1363 | return 1; | ||
1364 | } | ||
1365 | |||
1366 | static inline void acpi_res_list_del(struct acpi_res_list *res) | ||
1367 | { | ||
1368 | struct acpi_res_list *res_list_elem; | ||
1369 | |||
1370 | list_for_each_entry(res_list_elem, &resource_list_head, | ||
1371 | resource_list) { | ||
1372 | |||
1373 | if (res->resource_type == res_list_elem->resource_type && | ||
1374 | res->start == res_list_elem->start && | ||
1375 | res->end == res_list_elem->end) { | ||
1376 | |||
1377 | /* | ||
1378 | * If the res count is decreased to 0, | ||
1379 | * remove and free it | ||
1380 | */ | ||
1381 | |||
1382 | if (--res_list_elem->count == 0) { | ||
1383 | list_del(&res_list_elem->resource_list); | ||
1384 | kfree(res_list_elem); | ||
1385 | } | ||
1386 | return; | ||
1387 | } | ||
1388 | } | ||
1389 | } | ||
1390 | |||
1391 | acpi_status | ||
1392 | acpi_os_invalidate_address( | ||
1393 | u8 space_id, | ||
1394 | acpi_physical_address address, | ||
1395 | acpi_size length) | ||
1396 | { | ||
1397 | struct acpi_res_list res; | ||
1398 | |||
1399 | switch (space_id) { | ||
1400 | case ACPI_ADR_SPACE_SYSTEM_IO: | ||
1401 | case ACPI_ADR_SPACE_SYSTEM_MEMORY: | ||
1402 | /* Only interference checks against SystemIO and SytemMemory | ||
1403 | are needed */ | ||
1404 | res.start = address; | ||
1405 | res.end = address + length - 1; | ||
1406 | res.resource_type = space_id; | ||
1407 | spin_lock(&acpi_res_lock); | ||
1408 | acpi_res_list_del(&res); | ||
1409 | spin_unlock(&acpi_res_lock); | ||
1410 | break; | ||
1411 | case ACPI_ADR_SPACE_PCI_CONFIG: | ||
1412 | case ACPI_ADR_SPACE_EC: | ||
1413 | case ACPI_ADR_SPACE_SMBUS: | ||
1414 | case ACPI_ADR_SPACE_CMOS: | ||
1415 | case ACPI_ADR_SPACE_PCI_BAR_TARGET: | ||
1416 | case ACPI_ADR_SPACE_DATA_TABLE: | ||
1417 | case ACPI_ADR_SPACE_FIXED_HARDWARE: | ||
1418 | break; | ||
1419 | } | ||
1420 | return AE_OK; | ||
1421 | } | ||
1422 | |||
1361 | /****************************************************************************** | 1423 | /****************************************************************************** |
1362 | * | 1424 | * |
1363 | * FUNCTION: acpi_os_validate_address | 1425 | * FUNCTION: acpi_os_validate_address |
@@ -1382,6 +1444,7 @@ acpi_os_validate_address ( | |||
1382 | char *name) | 1444 | char *name) |
1383 | { | 1445 | { |
1384 | struct acpi_res_list *res; | 1446 | struct acpi_res_list *res; |
1447 | int added; | ||
1385 | if (acpi_enforce_resources == ENFORCE_RESOURCES_NO) | 1448 | if (acpi_enforce_resources == ENFORCE_RESOURCES_NO) |
1386 | return AE_OK; | 1449 | return AE_OK; |
1387 | 1450 | ||
@@ -1399,14 +1462,17 @@ acpi_os_validate_address ( | |||
1399 | res->end = address + length - 1; | 1462 | res->end = address + length - 1; |
1400 | res->resource_type = space_id; | 1463 | res->resource_type = space_id; |
1401 | spin_lock(&acpi_res_lock); | 1464 | spin_lock(&acpi_res_lock); |
1402 | list_add(&res->resource_list, &resource_list_head); | 1465 | added = acpi_res_list_add(res); |
1403 | spin_unlock(&acpi_res_lock); | 1466 | spin_unlock(&acpi_res_lock); |
1404 | pr_debug("Added %s resource: start: 0x%llx, end: 0x%llx, " | 1467 | pr_debug("%s %s resource: start: 0x%llx, end: 0x%llx, " |
1405 | "name: %s\n", (space_id == ACPI_ADR_SPACE_SYSTEM_IO) | 1468 | "name: %s\n", added ? "Added" : "Already exist", |
1469 | (space_id == ACPI_ADR_SPACE_SYSTEM_IO) | ||
1406 | ? "SystemIO" : "System Memory", | 1470 | ? "SystemIO" : "System Memory", |
1407 | (unsigned long long)res->start, | 1471 | (unsigned long long)res->start, |
1408 | (unsigned long long)res->end, | 1472 | (unsigned long long)res->end, |
1409 | res->name); | 1473 | res->name); |
1474 | if (!added) | ||
1475 | kfree(res); | ||
1410 | break; | 1476 | break; |
1411 | case ACPI_ADR_SPACE_PCI_CONFIG: | 1477 | case ACPI_ADR_SPACE_PCI_CONFIG: |
1412 | case ACPI_ADR_SPACE_EC: | 1478 | case ACPI_ADR_SPACE_EC: |
diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c index b794eb88ab90..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 | ||
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 55b5b90c2a44..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,20 +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 pci_bus *bus; | ||
68 | u16 segment; | ||
69 | u8 bus_nr; | ||
70 | |||
71 | u32 osc_support_set; /* _OSC state of support bits */ | ||
72 | u32 osc_control_set; /* _OSC state of control bits */ | ||
73 | u32 osc_control_qry; /* the latest _OSC query result */ | ||
74 | |||
75 | u32 osc_queried:1; /* has _OSC control been queried? */ | ||
76 | }; | ||
77 | |||
78 | static LIST_HEAD(acpi_pci_roots); | 66 | static LIST_HEAD(acpi_pci_roots); |
79 | 67 | ||
80 | static struct acpi_pci_driver *sub_driver; | 68 | static struct acpi_pci_driver *sub_driver; |
@@ -317,7 +305,7 @@ static acpi_status acpi_pci_osc_support(struct acpi_pci_root *root, u32 flags) | |||
317 | return status; | 305 | return status; |
318 | } | 306 | } |
319 | 307 | ||
320 | static struct acpi_pci_root *acpi_pci_find_root(acpi_handle handle) | 308 | struct acpi_pci_root *acpi_pci_find_root(acpi_handle handle) |
321 | { | 309 | { |
322 | struct acpi_pci_root *root; | 310 | struct acpi_pci_root *root; |
323 | 311 | ||
@@ -327,6 +315,7 @@ static struct acpi_pci_root *acpi_pci_find_root(acpi_handle handle) | |||
327 | } | 315 | } |
328 | return NULL; | 316 | return NULL; |
329 | } | 317 | } |
318 | EXPORT_SYMBOL_GPL(acpi_pci_find_root); | ||
330 | 319 | ||
331 | struct acpi_handle_node { | 320 | struct acpi_handle_node { |
332 | struct list_head node; | 321 | struct list_head node; |
diff --git a/drivers/acpi/pci_slot.c b/drivers/acpi/pci_slot.c index 12158e0d009b..45da2bae36c8 100644 --- a/drivers/acpi/pci_slot.c +++ b/drivers/acpi/pci_slot.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/acpi.h> | 31 | #include <linux/acpi.h> |
32 | #include <acpi/acpi_bus.h> | 32 | #include <acpi/acpi_bus.h> |
33 | #include <acpi/acpi_drivers.h> | 33 | #include <acpi/acpi_drivers.h> |
34 | #include <linux/dmi.h> | ||
34 | 35 | ||
35 | static int debug; | 36 | static int debug; |
36 | static int check_sta_before_sun; | 37 | static int check_sta_before_sun; |
@@ -57,7 +58,7 @@ ACPI_MODULE_NAME("pci_slot"); | |||
57 | MY_NAME , ## arg); \ | 58 | MY_NAME , ## arg); \ |
58 | } while (0) | 59 | } while (0) |
59 | 60 | ||
60 | #define SLOT_NAME_SIZE 20 /* Inspired by #define in acpiphp.h */ | 61 | #define SLOT_NAME_SIZE 21 /* Inspired by #define in acpiphp.h */ |
61 | 62 | ||
62 | struct acpi_pci_slot { | 63 | struct acpi_pci_slot { |
63 | acpi_handle root_handle; /* handle of the root bridge */ | 64 | acpi_handle root_handle; /* handle of the root bridge */ |
@@ -149,7 +150,7 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
149 | return AE_OK; | 150 | return AE_OK; |
150 | } | 151 | } |
151 | 152 | ||
152 | snprintf(name, sizeof(name), "%u", (u32)sun); | 153 | snprintf(name, sizeof(name), "%llu", sun); |
153 | pci_slot = pci_create_slot(pci_bus, device, name, NULL); | 154 | pci_slot = pci_create_slot(pci_bus, device, name, NULL); |
154 | if (IS_ERR(pci_slot)) { | 155 | if (IS_ERR(pci_slot)) { |
155 | err("pci_create_slot returned %ld\n", PTR_ERR(pci_slot)); | 156 | err("pci_create_slot returned %ld\n", PTR_ERR(pci_slot)); |
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index d74365d4a6e7..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"); |
@@ -361,17 +364,15 @@ int acpi_device_sleep_wake(struct acpi_device *dev, | |||
361 | */ | 364 | */ |
362 | 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) |
363 | { | 366 | { |
364 | int i, err; | 367 | int i, err = 0; |
365 | 368 | ||
366 | if (!dev || !dev->wakeup.flags.valid) | 369 | if (!dev || !dev->wakeup.flags.valid) |
367 | return -EINVAL; | 370 | return -EINVAL; |
368 | 371 | ||
369 | /* | 372 | mutex_lock(&acpi_device_lock); |
370 | * Do not execute the code below twice in a row without calling | 373 | |
371 | * acpi_disable_wakeup_device_power() in between for the same device | 374 | if (dev->wakeup.prepare_count++) |
372 | */ | 375 | goto out; |
373 | if (dev->wakeup.flags.prepared) | ||
374 | return 0; | ||
375 | 376 | ||
376 | /* Open power resource */ | 377 | /* Open power resource */ |
377 | for (i = 0; i < dev->wakeup.resources.count; i++) { | 378 | for (i = 0; i < dev->wakeup.resources.count; i++) { |
@@ -379,7 +380,8 @@ int acpi_enable_wakeup_device_power(struct acpi_device *dev, int sleep_state) | |||
379 | if (ret) { | 380 | if (ret) { |
380 | printk(KERN_ERR PREFIX "Transition power state\n"); | 381 | printk(KERN_ERR PREFIX "Transition power state\n"); |
381 | dev->wakeup.flags.valid = 0; | 382 | dev->wakeup.flags.valid = 0; |
382 | return -ENODEV; | 383 | err = -ENODEV; |
384 | goto err_out; | ||
383 | } | 385 | } |
384 | } | 386 | } |
385 | 387 | ||
@@ -388,9 +390,13 @@ int acpi_enable_wakeup_device_power(struct acpi_device *dev, int sleep_state) | |||
388 | * in arbitrary power state afterwards. | 390 | * in arbitrary power state afterwards. |
389 | */ | 391 | */ |
390 | err = acpi_device_sleep_wake(dev, 1, sleep_state, 3); | 392 | err = acpi_device_sleep_wake(dev, 1, sleep_state, 3); |
391 | if (!err) | ||
392 | dev->wakeup.flags.prepared = 1; | ||
393 | 393 | ||
394 | err_out: | ||
395 | if (err) | ||
396 | dev->wakeup.prepare_count = 0; | ||
397 | |||
398 | out: | ||
399 | mutex_unlock(&acpi_device_lock); | ||
394 | return err; | 400 | return err; |
395 | } | 401 | } |
396 | 402 | ||
@@ -402,35 +408,42 @@ int acpi_enable_wakeup_device_power(struct acpi_device *dev, int sleep_state) | |||
402 | */ | 408 | */ |
403 | int acpi_disable_wakeup_device_power(struct acpi_device *dev) | 409 | int acpi_disable_wakeup_device_power(struct acpi_device *dev) |
404 | { | 410 | { |
405 | int i, ret; | 411 | int i, err = 0; |
406 | 412 | ||
407 | if (!dev || !dev->wakeup.flags.valid) | 413 | if (!dev || !dev->wakeup.flags.valid) |
408 | return -EINVAL; | 414 | return -EINVAL; |
409 | 415 | ||
416 | mutex_lock(&acpi_device_lock); | ||
417 | |||
418 | if (--dev->wakeup.prepare_count > 0) | ||
419 | goto out; | ||
420 | |||
410 | /* | 421 | /* |
411 | * 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 |
412 | * acpi_enable_wakeup_device_power() in between for the same device | 423 | * the function is called may be useful, for example for initialisation. |
413 | */ | 424 | */ |
414 | if (!dev->wakeup.flags.prepared) | 425 | if (dev->wakeup.prepare_count < 0) |
415 | return 0; | 426 | dev->wakeup.prepare_count = 0; |
416 | 427 | ||
417 | dev->wakeup.flags.prepared = 0; | 428 | err = acpi_device_sleep_wake(dev, 0, 0, 0); |
418 | 429 | if (err) | |
419 | ret = acpi_device_sleep_wake(dev, 0, 0, 0); | 430 | goto out; |
420 | if (ret) | ||
421 | return ret; | ||
422 | 431 | ||
423 | /* Close power resource */ | 432 | /* Close power resource */ |
424 | for (i = 0; i < dev->wakeup.resources.count; i++) { | 433 | for (i = 0; i < dev->wakeup.resources.count; i++) { |
425 | 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); | ||
426 | if (ret) { | 436 | if (ret) { |
427 | printk(KERN_ERR PREFIX "Transition power state\n"); | 437 | printk(KERN_ERR PREFIX "Transition power state\n"); |
428 | dev->wakeup.flags.valid = 0; | 438 | dev->wakeup.flags.valid = 0; |
429 | return -ENODEV; | 439 | err = -ENODEV; |
440 | goto out; | ||
430 | } | 441 | } |
431 | } | 442 | } |
432 | 443 | ||
433 | return ret; | 444 | out: |
445 | mutex_unlock(&acpi_device_lock); | ||
446 | return err; | ||
434 | } | 447 | } |
435 | 448 | ||
436 | /* -------------------------------------------------------------------------- | 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 2cc4b3033872..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,9 +81,10 @@ 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); |
85 | #ifdef CONFIG_ACPI_PROCFS | ||
84 | 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); |
87 | #endif | ||
85 | static void acpi_processor_notify(struct acpi_device *device, u32 event); | 88 | static void acpi_processor_notify(struct acpi_device *device, u32 event); |
86 | static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu); | 89 | static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu); |
87 | static int acpi_processor_handle_eject(struct acpi_processor *pr); | 90 | static int acpi_processor_handle_eject(struct acpi_processor *pr); |
@@ -101,7 +104,6 @@ static struct acpi_driver acpi_processor_driver = { | |||
101 | .ops = { | 104 | .ops = { |
102 | .add = acpi_processor_add, | 105 | .add = acpi_processor_add, |
103 | .remove = acpi_processor_remove, | 106 | .remove = acpi_processor_remove, |
104 | .start = acpi_processor_start, | ||
105 | .suspend = acpi_processor_suspend, | 107 | .suspend = acpi_processor_suspend, |
106 | .resume = acpi_processor_resume, | 108 | .resume = acpi_processor_resume, |
107 | .notify = acpi_processor_notify, | 109 | .notify = acpi_processor_notify, |
@@ -110,7 +112,7 @@ static struct acpi_driver acpi_processor_driver = { | |||
110 | 112 | ||
111 | #define INSTALL_NOTIFY_HANDLER 1 | 113 | #define INSTALL_NOTIFY_HANDLER 1 |
112 | #define UNINSTALL_NOTIFY_HANDLER 2 | 114 | #define UNINSTALL_NOTIFY_HANDLER 2 |
113 | 115 | #ifdef CONFIG_ACPI_PROCFS | |
114 | static const struct file_operations acpi_processor_info_fops = { | 116 | static const struct file_operations acpi_processor_info_fops = { |
115 | .owner = THIS_MODULE, | 117 | .owner = THIS_MODULE, |
116 | .open = acpi_processor_info_open_fs, | 118 | .open = acpi_processor_info_open_fs, |
@@ -118,6 +120,7 @@ static const struct file_operations acpi_processor_info_fops = { | |||
118 | .llseek = seq_lseek, | 120 | .llseek = seq_lseek, |
119 | .release = single_release, | 121 | .release = single_release, |
120 | }; | 122 | }; |
123 | #endif | ||
121 | 124 | ||
122 | DEFINE_PER_CPU(struct acpi_processor *, processors); | 125 | DEFINE_PER_CPU(struct acpi_processor *, processors); |
123 | struct acpi_processor_errata errata __read_mostly; | 126 | struct acpi_processor_errata errata __read_mostly; |
@@ -316,6 +319,7 @@ static int acpi_processor_set_pdc(struct acpi_processor *pr) | |||
316 | FS Interface (/proc) | 319 | FS Interface (/proc) |
317 | -------------------------------------------------------------------------- */ | 320 | -------------------------------------------------------------------------- */ |
318 | 321 | ||
322 | #ifdef CONFIG_ACPI_PROCFS | ||
319 | static struct proc_dir_entry *acpi_processor_dir = NULL; | 323 | static struct proc_dir_entry *acpi_processor_dir = NULL; |
320 | 324 | ||
321 | static int acpi_processor_info_seq_show(struct seq_file *seq, void *offset) | 325 | static int acpi_processor_info_seq_show(struct seq_file *seq, void *offset) |
@@ -388,7 +392,6 @@ static int acpi_processor_add_fs(struct acpi_device *device) | |||
388 | return -EIO; | 392 | return -EIO; |
389 | return 0; | 393 | return 0; |
390 | } | 394 | } |
391 | |||
392 | static int acpi_processor_remove_fs(struct acpi_device *device) | 395 | static int acpi_processor_remove_fs(struct acpi_device *device) |
393 | { | 396 | { |
394 | 397 | ||
@@ -405,6 +408,16 @@ static int acpi_processor_remove_fs(struct acpi_device *device) | |||
405 | 408 | ||
406 | return 0; | 409 | return 0; |
407 | } | 410 | } |
411 | #else | ||
412 | static inline int acpi_processor_add_fs(struct acpi_device *device) | ||
413 | { | ||
414 | return 0; | ||
415 | } | ||
416 | static inline int acpi_processor_remove_fs(struct acpi_device *device) | ||
417 | { | ||
418 | return 0; | ||
419 | } | ||
420 | #endif | ||
408 | 421 | ||
409 | /* Use the acpiid in MADT to map cpus in case of SMP */ | 422 | /* Use the acpiid in MADT to map cpus in case of SMP */ |
410 | 423 | ||
@@ -698,92 +711,6 @@ static int acpi_processor_get_info(struct acpi_device *device) | |||
698 | 711 | ||
699 | static DEFINE_PER_CPU(void *, processor_device_array); | 712 | static DEFINE_PER_CPU(void *, processor_device_array); |
700 | 713 | ||
701 | static int __cpuinit acpi_processor_start(struct acpi_device *device) | ||
702 | { | ||
703 | int result = 0; | ||
704 | struct acpi_processor *pr; | ||
705 | struct sys_device *sysdev; | ||
706 | |||
707 | pr = acpi_driver_data(device); | ||
708 | |||
709 | result = acpi_processor_get_info(device); | ||
710 | if (result) { | ||
711 | /* Processor is physically not present */ | ||
712 | return 0; | ||
713 | } | ||
714 | |||
715 | BUG_ON((pr->id >= nr_cpu_ids) || (pr->id < 0)); | ||
716 | |||
717 | /* | ||
718 | * Buggy BIOS check | ||
719 | * ACPI id of processors can be reported wrongly by the BIOS. | ||
720 | * Don't trust it blindly | ||
721 | */ | ||
722 | if (per_cpu(processor_device_array, pr->id) != NULL && | ||
723 | per_cpu(processor_device_array, pr->id) != device) { | ||
724 | printk(KERN_WARNING "BIOS reported wrong ACPI id " | ||
725 | "for the processor\n"); | ||
726 | return -ENODEV; | ||
727 | } | ||
728 | per_cpu(processor_device_array, pr->id) = device; | ||
729 | |||
730 | per_cpu(processors, pr->id) = pr; | ||
731 | |||
732 | result = acpi_processor_add_fs(device); | ||
733 | if (result) | ||
734 | goto end; | ||
735 | |||
736 | sysdev = get_cpu_sysdev(pr->id); | ||
737 | if (sysfs_create_link(&device->dev.kobj, &sysdev->kobj, "sysdev")) | ||
738 | return -EFAULT; | ||
739 | |||
740 | /* _PDC call should be done before doing anything else (if reqd.). */ | ||
741 | arch_acpi_processor_init_pdc(pr); | ||
742 | acpi_processor_set_pdc(pr); | ||
743 | arch_acpi_processor_cleanup_pdc(pr); | ||
744 | |||
745 | #ifdef CONFIG_CPU_FREQ | ||
746 | acpi_processor_ppc_has_changed(pr); | ||
747 | #endif | ||
748 | acpi_processor_get_throttling_info(pr); | ||
749 | acpi_processor_get_limit_info(pr); | ||
750 | |||
751 | |||
752 | acpi_processor_power_init(pr, device); | ||
753 | |||
754 | pr->cdev = thermal_cooling_device_register("Processor", device, | ||
755 | &processor_cooling_ops); | ||
756 | if (IS_ERR(pr->cdev)) { | ||
757 | result = PTR_ERR(pr->cdev); | ||
758 | goto end; | ||
759 | } | ||
760 | |||
761 | dev_info(&device->dev, "registered as cooling_device%d\n", | ||
762 | pr->cdev->id); | ||
763 | |||
764 | result = sysfs_create_link(&device->dev.kobj, | ||
765 | &pr->cdev->device.kobj, | ||
766 | "thermal_cooling"); | ||
767 | if (result) | ||
768 | printk(KERN_ERR PREFIX "Create sysfs link\n"); | ||
769 | result = sysfs_create_link(&pr->cdev->device.kobj, | ||
770 | &device->dev.kobj, | ||
771 | "device"); | ||
772 | if (result) | ||
773 | printk(KERN_ERR PREFIX "Create sysfs link\n"); | ||
774 | |||
775 | if (pr->flags.throttling) { | ||
776 | printk(KERN_INFO PREFIX "%s [%s] (supports", | ||
777 | acpi_device_name(device), acpi_device_bid(device)); | ||
778 | printk(" %d throttling states", pr->throttling.state_count); | ||
779 | printk(")\n"); | ||
780 | } | ||
781 | |||
782 | end: | ||
783 | |||
784 | return result; | ||
785 | } | ||
786 | |||
787 | static void acpi_processor_notify(struct acpi_device *device, u32 event) | 714 | static void acpi_processor_notify(struct acpi_device *device, u32 event) |
788 | { | 715 | { |
789 | struct acpi_processor *pr = acpi_driver_data(device); | 716 | struct acpi_processor *pr = acpi_driver_data(device); |
@@ -846,10 +773,8 @@ static struct notifier_block acpi_cpu_notifier = | |||
846 | static int acpi_processor_add(struct acpi_device *device) | 773 | static int acpi_processor_add(struct acpi_device *device) |
847 | { | 774 | { |
848 | struct acpi_processor *pr = NULL; | 775 | struct acpi_processor *pr = NULL; |
849 | 776 | int result = 0; | |
850 | 777 | struct sys_device *sysdev; | |
851 | if (!device) | ||
852 | return -EINVAL; | ||
853 | 778 | ||
854 | pr = kzalloc(sizeof(struct acpi_processor), GFP_KERNEL); | 779 | pr = kzalloc(sizeof(struct acpi_processor), GFP_KERNEL); |
855 | if (!pr) | 780 | if (!pr) |
@@ -865,7 +790,100 @@ static int acpi_processor_add(struct acpi_device *device) | |||
865 | strcpy(acpi_device_class(device), ACPI_PROCESSOR_CLASS); | 790 | strcpy(acpi_device_class(device), ACPI_PROCESSOR_CLASS); |
866 | device->driver_data = pr; | 791 | device->driver_data = pr; |
867 | 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 | |||
868 | 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; | ||
869 | } | 887 | } |
870 | 888 | ||
871 | static int acpi_processor_remove(struct acpi_device *device, int type) | 889 | static int acpi_processor_remove(struct acpi_device *device, int type) |
@@ -942,7 +960,6 @@ int acpi_processor_device_add(acpi_handle handle, struct acpi_device **device) | |||
942 | { | 960 | { |
943 | acpi_handle phandle; | 961 | acpi_handle phandle; |
944 | struct acpi_device *pdev; | 962 | struct acpi_device *pdev; |
945 | struct acpi_processor *pr; | ||
946 | 963 | ||
947 | 964 | ||
948 | if (acpi_get_parent(handle, &phandle)) { | 965 | if (acpi_get_parent(handle, &phandle)) { |
@@ -957,15 +974,6 @@ int acpi_processor_device_add(acpi_handle handle, struct acpi_device **device) | |||
957 | return -ENODEV; | 974 | return -ENODEV; |
958 | } | 975 | } |
959 | 976 | ||
960 | acpi_bus_start(*device); | ||
961 | |||
962 | pr = acpi_driver_data(*device); | ||
963 | if (!pr) | ||
964 | return -ENODEV; | ||
965 | |||
966 | if ((pr->id >= 0) && (pr->id < nr_cpu_ids)) { | ||
967 | kobject_uevent(&(*device)->dev.kobj, KOBJ_ONLINE); | ||
968 | } | ||
969 | return 0; | 977 | return 0; |
970 | } | 978 | } |
971 | 979 | ||
@@ -995,25 +1003,6 @@ static void __ref acpi_processor_hotplug_notify(acpi_handle handle, | |||
995 | "Unable to add the device\n"); | 1003 | "Unable to add the device\n"); |
996 | break; | 1004 | break; |
997 | } | 1005 | } |
998 | |||
999 | pr = acpi_driver_data(device); | ||
1000 | if (!pr) { | ||
1001 | printk(KERN_ERR PREFIX "Driver data is NULL\n"); | ||
1002 | break; | ||
1003 | } | ||
1004 | |||
1005 | if (pr->id >= 0 && (pr->id < nr_cpu_ids)) { | ||
1006 | kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE); | ||
1007 | break; | ||
1008 | } | ||
1009 | |||
1010 | result = acpi_processor_start(device); | ||
1011 | if ((!result) && ((pr->id >= 0) && (pr->id < nr_cpu_ids))) { | ||
1012 | kobject_uevent(&device->dev.kobj, KOBJ_ONLINE); | ||
1013 | } else { | ||
1014 | printk(KERN_ERR PREFIX "Device [%s] failed to start\n", | ||
1015 | acpi_device_bid(device)); | ||
1016 | } | ||
1017 | break; | 1006 | break; |
1018 | case ACPI_NOTIFY_EJECT_REQUEST: | 1007 | case ACPI_NOTIFY_EJECT_REQUEST: |
1019 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 1008 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
@@ -1030,9 +1019,6 @@ static void __ref acpi_processor_hotplug_notify(acpi_handle handle, | |||
1030 | "Driver data is NULL, dropping EJECT\n"); | 1019 | "Driver data is NULL, dropping EJECT\n"); |
1031 | return; | 1020 | return; |
1032 | } | 1021 | } |
1033 | |||
1034 | if ((pr->id < nr_cpu_ids) && (cpu_present(pr->id))) | ||
1035 | kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE); | ||
1036 | break; | 1022 | break; |
1037 | default: | 1023 | default: |
1038 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 1024 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
@@ -1161,11 +1147,11 @@ static int __init acpi_processor_init(void) | |||
1161 | (struct acpi_table_header **)&madt))) | 1147 | (struct acpi_table_header **)&madt))) |
1162 | madt = NULL; | 1148 | madt = NULL; |
1163 | #endif | 1149 | #endif |
1164 | 1150 | #ifdef CONFIG_ACPI_PROCFS | |
1165 | acpi_processor_dir = proc_mkdir(ACPI_PROCESSOR_CLASS, acpi_root_dir); | 1151 | acpi_processor_dir = proc_mkdir(ACPI_PROCESSOR_CLASS, acpi_root_dir); |
1166 | if (!acpi_processor_dir) | 1152 | if (!acpi_processor_dir) |
1167 | return -ENOMEM; | 1153 | return -ENOMEM; |
1168 | 1154 | #endif | |
1169 | /* | 1155 | /* |
1170 | * Check whether the system is DMI table. If yes, OSPM | 1156 | * Check whether the system is DMI table. If yes, OSPM |
1171 | * should not use mwait for CPU-states. | 1157 | * should not use mwait for CPU-states. |
@@ -1193,7 +1179,9 @@ out_cpuidle: | |||
1193 | cpuidle_unregister_driver(&acpi_idle_driver); | 1179 | cpuidle_unregister_driver(&acpi_idle_driver); |
1194 | 1180 | ||
1195 | out_proc: | 1181 | out_proc: |
1182 | #ifdef CONFIG_ACPI_PROCFS | ||
1196 | remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir); | 1183 | remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir); |
1184 | #endif | ||
1197 | 1185 | ||
1198 | return result; | 1186 | return result; |
1199 | } | 1187 | } |
@@ -1213,7 +1201,9 @@ static void __exit acpi_processor_exit(void) | |||
1213 | 1201 | ||
1214 | cpuidle_unregister_driver(&acpi_idle_driver); | 1202 | cpuidle_unregister_driver(&acpi_idle_driver); |
1215 | 1203 | ||
1204 | #ifdef CONFIG_ACPI_PROCFS | ||
1216 | remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir); | 1205 | remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir); |
1206 | #endif | ||
1217 | 1207 | ||
1218 | return; | 1208 | return; |
1219 | } | 1209 | } |
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 66393d5c4c7c..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"); |
@@ -680,6 +682,7 @@ static int acpi_processor_get_power_info(struct acpi_processor *pr) | |||
680 | return 0; | 682 | return 0; |
681 | } | 683 | } |
682 | 684 | ||
685 | #ifdef CONFIG_ACPI_PROCFS | ||
683 | static int acpi_processor_power_seq_show(struct seq_file *seq, void *offset) | 686 | static int acpi_processor_power_seq_show(struct seq_file *seq, void *offset) |
684 | { | 687 | { |
685 | struct acpi_processor *pr = seq->private; | 688 | struct acpi_processor *pr = seq->private; |
@@ -759,7 +762,7 @@ static const struct file_operations acpi_processor_power_fops = { | |||
759 | .llseek = seq_lseek, | 762 | .llseek = seq_lseek, |
760 | .release = single_release, | 763 | .release = single_release, |
761 | }; | 764 | }; |
762 | 765 | #endif | |
763 | 766 | ||
764 | /** | 767 | /** |
765 | * acpi_idle_bm_check - checks if bus master activity was detected | 768 | * acpi_idle_bm_check - checks if bus master activity was detected |
@@ -1160,7 +1163,9 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr, | |||
1160 | { | 1163 | { |
1161 | acpi_status status = 0; | 1164 | acpi_status status = 0; |
1162 | static int first_run; | 1165 | static int first_run; |
1166 | #ifdef CONFIG_ACPI_PROCFS | ||
1163 | struct proc_dir_entry *entry = NULL; | 1167 | struct proc_dir_entry *entry = NULL; |
1168 | #endif | ||
1164 | unsigned int i; | 1169 | unsigned int i; |
1165 | 1170 | ||
1166 | if (boot_option_idle_override) | 1171 | if (boot_option_idle_override) |
@@ -1217,7 +1222,7 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr, | |||
1217 | pr->power.states[i].type); | 1222 | pr->power.states[i].type); |
1218 | printk(")\n"); | 1223 | printk(")\n"); |
1219 | } | 1224 | } |
1220 | 1225 | #ifdef CONFIG_ACPI_PROCFS | |
1221 | /* 'power' [R] */ | 1226 | /* 'power' [R] */ |
1222 | entry = proc_create_data(ACPI_PROCESSOR_FILE_POWER, | 1227 | entry = proc_create_data(ACPI_PROCESSOR_FILE_POWER, |
1223 | S_IRUGO, acpi_device_dir(device), | 1228 | S_IRUGO, acpi_device_dir(device), |
@@ -1225,6 +1230,7 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr, | |||
1225 | acpi_driver_data(device)); | 1230 | acpi_driver_data(device)); |
1226 | if (!entry) | 1231 | if (!entry) |
1227 | return -EIO; | 1232 | return -EIO; |
1233 | #endif | ||
1228 | return 0; | 1234 | return 0; |
1229 | } | 1235 | } |
1230 | 1236 | ||
@@ -1237,9 +1243,11 @@ int acpi_processor_power_exit(struct acpi_processor *pr, | |||
1237 | cpuidle_unregister_device(&pr->power.dev); | 1243 | cpuidle_unregister_device(&pr->power.dev); |
1238 | pr->flags.power_setup_done = 0; | 1244 | pr->flags.power_setup_done = 0; |
1239 | 1245 | ||
1246 | #ifdef CONFIG_ACPI_PROCFS | ||
1240 | if (acpi_device_dir(device)) | 1247 | if (acpi_device_dir(device)) |
1241 | remove_proc_entry(ACPI_PROCESSOR_FILE_POWER, | 1248 | remove_proc_entry(ACPI_PROCESSOR_FILE_POWER, |
1242 | acpi_device_dir(device)); | 1249 | acpi_device_dir(device)); |
1250 | #endif | ||
1243 | 1251 | ||
1244 | return 0; | 1252 | return 0; |
1245 | } | 1253 | } |
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index 60e543d3234e..8ba0ed0b9ddb 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 |
@@ -509,7 +511,7 @@ int acpi_processor_preregister_performance( | |||
509 | struct acpi_processor *match_pr; | 511 | struct acpi_processor *match_pr; |
510 | struct acpi_psd_package *match_pdomain; | 512 | struct acpi_psd_package *match_pdomain; |
511 | 513 | ||
512 | if (!alloc_cpumask_var(&covered_cpus, GFP_KERNEL)) | 514 | if (!zalloc_cpumask_var(&covered_cpus, GFP_KERNEL)) |
513 | return -ENOMEM; | 515 | return -ENOMEM; |
514 | 516 | ||
515 | mutex_lock(&performance_mutex); | 517 | mutex_lock(&performance_mutex); |
@@ -556,7 +558,6 @@ int acpi_processor_preregister_performance( | |||
556 | * Now that we have _PSD data from all CPUs, lets setup P-state | 558 | * Now that we have _PSD data from all CPUs, lets setup P-state |
557 | * domain info. | 559 | * domain info. |
558 | */ | 560 | */ |
559 | cpumask_clear(covered_cpus); | ||
560 | for_each_possible_cpu(i) { | 561 | for_each_possible_cpu(i) { |
561 | pr = per_cpu(processors, i); | 562 | pr = per_cpu(processors, i); |
562 | if (!pr) | 563 | if (!pr) |
diff --git a/drivers/acpi/processor_thermal.c b/drivers/acpi/processor_thermal.c index 31adda1099e0..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"); |
@@ -438,7 +440,7 @@ struct thermal_cooling_device_ops processor_cooling_ops = { | |||
438 | }; | 440 | }; |
439 | 441 | ||
440 | /* /proc interface */ | 442 | /* /proc interface */ |
441 | 443 | #ifdef CONFIG_ACPI_PROCFS | |
442 | static int acpi_processor_limit_seq_show(struct seq_file *seq, void *offset) | 444 | static int acpi_processor_limit_seq_show(struct seq_file *seq, void *offset) |
443 | { | 445 | { |
444 | struct acpi_processor *pr = (struct acpi_processor *)seq->private; | 446 | struct acpi_processor *pr = (struct acpi_processor *)seq->private; |
@@ -517,3 +519,4 @@ const struct file_operations acpi_processor_limit_fops = { | |||
517 | .llseek = seq_lseek, | 519 | .llseek = seq_lseek, |
518 | .release = single_release, | 520 | .release = single_release, |
519 | }; | 521 | }; |
522 | #endif | ||
diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c index ae39797aab55..4c6c14c1e307 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"); |
@@ -75,7 +77,7 @@ static int acpi_processor_update_tsd_coord(void) | |||
75 | struct acpi_tsd_package *pdomain, *match_pdomain; | 77 | struct acpi_tsd_package *pdomain, *match_pdomain; |
76 | struct acpi_processor_throttling *pthrottling, *match_pthrottling; | 78 | struct acpi_processor_throttling *pthrottling, *match_pthrottling; |
77 | 79 | ||
78 | if (!alloc_cpumask_var(&covered_cpus, GFP_KERNEL)) | 80 | if (!zalloc_cpumask_var(&covered_cpus, GFP_KERNEL)) |
79 | return -ENOMEM; | 81 | return -ENOMEM; |
80 | 82 | ||
81 | /* | 83 | /* |
@@ -103,7 +105,6 @@ static int acpi_processor_update_tsd_coord(void) | |||
103 | if (retval) | 105 | if (retval) |
104 | goto err_ret; | 106 | goto err_ret; |
105 | 107 | ||
106 | cpumask_clear(covered_cpus); | ||
107 | for_each_possible_cpu(i) { | 108 | for_each_possible_cpu(i) { |
108 | pr = per_cpu(processors, i); | 109 | pr = per_cpu(processors, i); |
109 | if (!pr) | 110 | if (!pr) |
@@ -1216,7 +1217,7 @@ int acpi_processor_get_throttling_info(struct acpi_processor *pr) | |||
1216 | } | 1217 | } |
1217 | 1218 | ||
1218 | /* proc interface */ | 1219 | /* proc interface */ |
1219 | 1220 | #ifdef CONFIG_ACPI_PROCFS | |
1220 | static int acpi_processor_throttling_seq_show(struct seq_file *seq, | 1221 | static int acpi_processor_throttling_seq_show(struct seq_file *seq, |
1221 | void *offset) | 1222 | void *offset) |
1222 | { | 1223 | { |
@@ -1324,3 +1325,4 @@ const struct file_operations acpi_processor_throttling_fops = { | |||
1324 | .llseek = seq_lseek, | 1325 | .llseek = seq_lseek, |
1325 | .release = single_release, | 1326 | .release = single_release, |
1326 | }; | 1327 | }; |
1328 | #endif | ||
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 781435d7e369..408ebde18986 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); |
@@ -287,14 +287,14 @@ int acpi_match_device_ids(struct acpi_device *device, | |||
287 | } | 287 | } |
288 | 288 | ||
289 | if (device->flags.compatible_ids) { | 289 | if (device->flags.compatible_ids) { |
290 | struct acpi_compatible_id_list *cid_list = device->pnp.cid_list; | 290 | struct acpica_device_id_list *cid_list = device->pnp.cid_list; |
291 | int i; | 291 | int i; |
292 | 292 | ||
293 | for (id = ids; id->id[0]; id++) { | 293 | for (id = ids; id->id[0]; id++) { |
294 | /* compare multiple _CID entries against driver ids */ | 294 | /* compare multiple _CID entries against driver ids */ |
295 | for (i = 0; i < cid_list->count; i++) { | 295 | for (i = 0; i < cid_list->count; i++) { |
296 | if (!strcmp((char*)id->id, | 296 | if (!strcmp((char*)id->id, |
297 | cid_list->id[i].value)) | 297 | cid_list->ids[i].string)) |
298 | return 0; | 298 | return 0; |
299 | } | 299 | } |
300 | } | 300 | } |
@@ -309,6 +309,10 @@ static void acpi_device_release(struct device *dev) | |||
309 | struct acpi_device *acpi_dev = to_acpi_device(dev); | 309 | struct acpi_device *acpi_dev = to_acpi_device(dev); |
310 | 310 | ||
311 | 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); | ||
312 | kfree(acpi_dev); | 316 | kfree(acpi_dev); |
313 | } | 317 | } |
314 | 318 | ||
@@ -366,7 +370,8 @@ static acpi_status acpi_device_notify_fixed(void *data) | |||
366 | { | 370 | { |
367 | struct acpi_device *device = data; | 371 | struct acpi_device *device = data; |
368 | 372 | ||
369 | acpi_device_notify(device->handle, ACPI_FIXED_HARDWARE_EVENT, device); | 373 | /* Fixed hardware devices have no handles */ |
374 | acpi_device_notify(NULL, ACPI_FIXED_HARDWARE_EVENT, device); | ||
370 | return AE_OK; | 375 | return AE_OK; |
371 | } | 376 | } |
372 | 377 | ||
@@ -426,9 +431,6 @@ static int acpi_device_probe(struct device * dev) | |||
426 | if (acpi_drv->ops.notify) { | 431 | if (acpi_drv->ops.notify) { |
427 | ret = acpi_device_install_notify_handler(acpi_dev); | 432 | ret = acpi_device_install_notify_handler(acpi_dev); |
428 | if (ret) { | 433 | if (ret) { |
429 | if (acpi_drv->ops.stop) | ||
430 | acpi_drv->ops.stop(acpi_dev, | ||
431 | acpi_dev->removal_type); | ||
432 | if (acpi_drv->ops.remove) | 434 | if (acpi_drv->ops.remove) |
433 | acpi_drv->ops.remove(acpi_dev, | 435 | acpi_drv->ops.remove(acpi_dev, |
434 | acpi_dev->removal_type); | 436 | acpi_dev->removal_type); |
@@ -452,8 +454,6 @@ static int acpi_device_remove(struct device * dev) | |||
452 | if (acpi_drv) { | 454 | if (acpi_drv) { |
453 | if (acpi_drv->ops.notify) | 455 | if (acpi_drv->ops.notify) |
454 | acpi_device_remove_notify_handler(acpi_dev); | 456 | acpi_device_remove_notify_handler(acpi_dev); |
455 | if (acpi_drv->ops.stop) | ||
456 | acpi_drv->ops.stop(acpi_dev, acpi_dev->removal_type); | ||
457 | if (acpi_drv->ops.remove) | 457 | if (acpi_drv->ops.remove) |
458 | acpi_drv->ops.remove(acpi_dev, acpi_dev->removal_type); | 458 | acpi_drv->ops.remove(acpi_dev, acpi_dev->removal_type); |
459 | } | 459 | } |
@@ -687,7 +687,7 @@ acpi_bus_get_ejd(acpi_handle handle, acpi_handle *ejd) | |||
687 | } | 687 | } |
688 | EXPORT_SYMBOL_GPL(acpi_bus_get_ejd); | 688 | EXPORT_SYMBOL_GPL(acpi_bus_get_ejd); |
689 | 689 | ||
690 | void acpi_bus_data_handler(acpi_handle handle, u32 function, void *context) | 690 | void acpi_bus_data_handler(acpi_handle handle, void *context) |
691 | { | 691 | { |
692 | 692 | ||
693 | /* TBD */ | 693 | /* TBD */ |
@@ -781,6 +781,7 @@ static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device) | |||
781 | kfree(buffer.pointer); | 781 | kfree(buffer.pointer); |
782 | 782 | ||
783 | device->wakeup.flags.valid = 1; | 783 | device->wakeup.flags.valid = 1; |
784 | device->wakeup.prepare_count = 0; | ||
784 | /* Call _PSW/_DSW object to disable its ability to wake the sleeping | 785 | /* Call _PSW/_DSW object to disable its ability to wake the sleeping |
785 | * system for the ACPI device with the _PRW object. | 786 | * system for the ACPI device with the _PRW object. |
786 | * The _PSW object is depreciated in ACPI 3.0 and is replaced by _DSW. | 787 | * The _PSW object is depreciated in ACPI 3.0 and is replaced by _DSW. |
@@ -999,33 +1000,89 @@ static int acpi_dock_match(struct acpi_device *device) | |||
999 | return acpi_get_handle(device->handle, "_DCK", &tmp); | 1000 | return acpi_get_handle(device->handle, "_DCK", &tmp); |
1000 | } | 1001 | } |
1001 | 1002 | ||
1003 | static struct acpica_device_id_list* | ||
1004 | acpi_add_cid( | ||
1005 | struct acpi_device_info *info, | ||
1006 | struct acpica_device_id *new_cid) | ||
1007 | { | ||
1008 | struct acpica_device_id_list *cid; | ||
1009 | char *next_id_string; | ||
1010 | acpi_size cid_length; | ||
1011 | acpi_size new_cid_length; | ||
1012 | u32 i; | ||
1013 | |||
1014 | |||
1015 | /* Allocate new CID list with room for the new CID */ | ||
1016 | |||
1017 | if (!new_cid) | ||
1018 | new_cid_length = info->compatible_id_list.list_size; | ||
1019 | else if (info->compatible_id_list.list_size) | ||
1020 | new_cid_length = info->compatible_id_list.list_size + | ||
1021 | new_cid->length + sizeof(struct acpica_device_id); | ||
1022 | else | ||
1023 | new_cid_length = sizeof(struct acpica_device_id_list) + new_cid->length; | ||
1024 | |||
1025 | cid = ACPI_ALLOCATE_ZEROED(new_cid_length); | ||
1026 | if (!cid) { | ||
1027 | return NULL; | ||
1028 | } | ||
1029 | |||
1030 | cid->list_size = new_cid_length; | ||
1031 | cid->count = info->compatible_id_list.count; | ||
1032 | if (new_cid) | ||
1033 | cid->count++; | ||
1034 | next_id_string = (char *) cid->ids + (cid->count * sizeof(struct acpica_device_id)); | ||
1035 | |||
1036 | /* Copy all existing CIDs */ | ||
1037 | |||
1038 | for (i = 0; i < info->compatible_id_list.count; i++) { | ||
1039 | cid_length = info->compatible_id_list.ids[i].length; | ||
1040 | cid->ids[i].string = next_id_string; | ||
1041 | cid->ids[i].length = cid_length; | ||
1042 | |||
1043 | ACPI_MEMCPY(next_id_string, info->compatible_id_list.ids[i].string, | ||
1044 | cid_length); | ||
1045 | |||
1046 | next_id_string += cid_length; | ||
1047 | } | ||
1048 | |||
1049 | /* Append the new CID */ | ||
1050 | |||
1051 | if (new_cid) { | ||
1052 | cid->ids[i].string = next_id_string; | ||
1053 | cid->ids[i].length = new_cid->length; | ||
1054 | |||
1055 | ACPI_MEMCPY(next_id_string, new_cid->string, new_cid->length); | ||
1056 | } | ||
1057 | |||
1058 | return cid; | ||
1059 | } | ||
1060 | |||
1002 | static void acpi_device_set_id(struct acpi_device *device, | 1061 | static void acpi_device_set_id(struct acpi_device *device, |
1003 | struct acpi_device *parent, acpi_handle handle, | 1062 | struct acpi_device *parent, acpi_handle handle, |
1004 | int type) | 1063 | int type) |
1005 | { | 1064 | { |
1006 | struct acpi_device_info *info; | 1065 | struct acpi_device_info *info = NULL; |
1007 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
1008 | char *hid = NULL; | 1066 | char *hid = NULL; |
1009 | char *uid = NULL; | 1067 | char *uid = NULL; |
1010 | struct acpi_compatible_id_list *cid_list = NULL; | 1068 | struct acpica_device_id_list *cid_list = NULL; |
1011 | const char *cid_add = NULL; | 1069 | char *cid_add = NULL; |
1012 | acpi_status status; | 1070 | acpi_status status; |
1013 | 1071 | ||
1014 | switch (type) { | 1072 | switch (type) { |
1015 | case ACPI_BUS_TYPE_DEVICE: | 1073 | case ACPI_BUS_TYPE_DEVICE: |
1016 | status = acpi_get_object_info(handle, &buffer); | 1074 | status = acpi_get_object_info(handle, &info); |
1017 | if (ACPI_FAILURE(status)) { | 1075 | if (ACPI_FAILURE(status)) { |
1018 | printk(KERN_ERR PREFIX "%s: Error reading device info\n", __func__); | 1076 | printk(KERN_ERR PREFIX "%s: Error reading device info\n", __func__); |
1019 | return; | 1077 | return; |
1020 | } | 1078 | } |
1021 | 1079 | ||
1022 | info = buffer.pointer; | ||
1023 | if (info->valid & ACPI_VALID_HID) | 1080 | if (info->valid & ACPI_VALID_HID) |
1024 | hid = info->hardware_id.value; | 1081 | hid = info->hardware_id.string; |
1025 | if (info->valid & ACPI_VALID_UID) | 1082 | if (info->valid & ACPI_VALID_UID) |
1026 | uid = info->unique_id.value; | 1083 | uid = info->unique_id.string; |
1027 | if (info->valid & ACPI_VALID_CID) | 1084 | if (info->valid & ACPI_VALID_CID) |
1028 | cid_list = &info->compatibility_id; | 1085 | cid_list = &info->compatible_id_list; |
1029 | if (info->valid & ACPI_VALID_ADR) { | 1086 | if (info->valid & ACPI_VALID_ADR) { |
1030 | device->pnp.bus_address = info->address; | 1087 | device->pnp.bus_address = info->address; |
1031 | device->flags.bus_address = 1; | 1088 | device->flags.bus_address = 1; |
@@ -1076,55 +1133,46 @@ static void acpi_device_set_id(struct acpi_device *device, | |||
1076 | } | 1133 | } |
1077 | 1134 | ||
1078 | if (hid) { | 1135 | if (hid) { |
1079 | strcpy(device->pnp.hardware_id, hid); | 1136 | device->pnp.hardware_id = ACPI_ALLOCATE_ZEROED(strlen (hid) + 1); |
1080 | device->flags.hardware_id = 1; | 1137 | if (device->pnp.hardware_id) { |
1138 | strcpy(device->pnp.hardware_id, hid); | ||
1139 | device->flags.hardware_id = 1; | ||
1140 | } | ||
1081 | } | 1141 | } |
1142 | if (!device->flags.hardware_id) | ||
1143 | device->pnp.hardware_id = ""; | ||
1144 | |||
1082 | if (uid) { | 1145 | if (uid) { |
1083 | strcpy(device->pnp.unique_id, uid); | 1146 | device->pnp.unique_id = ACPI_ALLOCATE_ZEROED(strlen (uid) + 1); |
1084 | device->flags.unique_id = 1; | 1147 | if (device->pnp.unique_id) { |
1148 | strcpy(device->pnp.unique_id, uid); | ||
1149 | device->flags.unique_id = 1; | ||
1150 | } | ||
1085 | } | 1151 | } |
1152 | if (!device->flags.unique_id) | ||
1153 | device->pnp.unique_id = ""; | ||
1154 | |||
1086 | if (cid_list || cid_add) { | 1155 | if (cid_list || cid_add) { |
1087 | struct acpi_compatible_id_list *list; | 1156 | struct acpica_device_id_list *list; |
1088 | int size = 0; | 1157 | |
1089 | int count = 0; | 1158 | if (cid_add) { |
1090 | 1159 | struct acpica_device_id cid; | |
1091 | if (cid_list) { | 1160 | cid.length = strlen (cid_add) + 1; |
1092 | size = cid_list->size; | 1161 | cid.string = cid_add; |
1093 | } else if (cid_add) { | 1162 | |
1094 | size = sizeof(struct acpi_compatible_id_list); | 1163 | list = acpi_add_cid(info, &cid); |
1095 | cid_list = ACPI_ALLOCATE_ZEROED((acpi_size) size); | 1164 | } else { |
1096 | if (!cid_list) { | 1165 | list = acpi_add_cid(info, NULL); |
1097 | printk(KERN_ERR "Memory allocation error\n"); | ||
1098 | kfree(buffer.pointer); | ||
1099 | return; | ||
1100 | } else { | ||
1101 | cid_list->count = 0; | ||
1102 | cid_list->size = size; | ||
1103 | } | ||
1104 | } | 1166 | } |
1105 | if (cid_add) | ||
1106 | size += sizeof(struct acpi_compatible_id); | ||
1107 | list = kmalloc(size, GFP_KERNEL); | ||
1108 | 1167 | ||
1109 | if (list) { | 1168 | if (list) { |
1110 | if (cid_list) { | ||
1111 | memcpy(list, cid_list, cid_list->size); | ||
1112 | count = cid_list->count; | ||
1113 | } | ||
1114 | if (cid_add) { | ||
1115 | strncpy(list->id[count].value, cid_add, | ||
1116 | ACPI_MAX_CID_LENGTH); | ||
1117 | count++; | ||
1118 | device->flags.compatible_ids = 1; | ||
1119 | } | ||
1120 | list->size = size; | ||
1121 | list->count = count; | ||
1122 | device->pnp.cid_list = list; | 1169 | device->pnp.cid_list = list; |
1123 | } else | 1170 | if (cid_add) |
1124 | printk(KERN_ERR PREFIX "Memory allocation error\n"); | 1171 | device->flags.compatible_ids = 1; |
1172 | } | ||
1125 | } | 1173 | } |
1126 | 1174 | ||
1127 | kfree(buffer.pointer); | 1175 | kfree(info); |
1128 | } | 1176 | } |
1129 | 1177 | ||
1130 | static int acpi_device_set_context(struct acpi_device *device, int type) | 1178 | static int acpi_device_set_context(struct acpi_device *device, int type) |
@@ -1264,16 +1312,6 @@ acpi_add_single_object(struct acpi_device **child, | |||
1264 | acpi_device_set_id(device, parent, handle, type); | 1312 | acpi_device_set_id(device, parent, handle, type); |
1265 | 1313 | ||
1266 | /* | 1314 | /* |
1267 | * The ACPI device is attached to acpi handle before getting | ||
1268 | * the power/wakeup/peformance flags. Otherwise OS can't get | ||
1269 | * the corresponding ACPI device by the acpi handle in the course | ||
1270 | * of getting the power/wakeup/performance flags. | ||
1271 | */ | ||
1272 | result = acpi_device_set_context(device, type); | ||
1273 | if (result) | ||
1274 | goto end; | ||
1275 | |||
1276 | /* | ||
1277 | * Power Management | 1315 | * Power Management |
1278 | * ---------------- | 1316 | * ---------------- |
1279 | */ | 1317 | */ |
@@ -1303,6 +1341,8 @@ acpi_add_single_object(struct acpi_device **child, | |||
1303 | goto end; | 1341 | goto end; |
1304 | } | 1342 | } |
1305 | 1343 | ||
1344 | if ((result = acpi_device_set_context(device, type))) | ||
1345 | goto end; | ||
1306 | 1346 | ||
1307 | result = acpi_device_register(device, parent); | 1347 | result = acpi_device_register(device, parent); |
1308 | 1348 | ||
@@ -1317,10 +1357,8 @@ acpi_add_single_object(struct acpi_device **child, | |||
1317 | end: | 1357 | end: |
1318 | if (!result) | 1358 | if (!result) |
1319 | *child = device; | 1359 | *child = device; |
1320 | else { | 1360 | else |
1321 | kfree(device->pnp.cid_list); | 1361 | acpi_device_release(&device->dev); |
1322 | kfree(device); | ||
1323 | } | ||
1324 | 1362 | ||
1325 | return result; | 1363 | return result; |
1326 | } | 1364 | } |
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 42159a28f433..a90afcc723ab 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c | |||
@@ -405,6 +405,14 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = { | |||
405 | }, | 405 | }, |
406 | }, | 406 | }, |
407 | { | 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 | { | ||
408 | .callback = init_old_suspend_ordering, | 416 | .callback = init_old_suspend_ordering, |
409 | .ident = "Panasonic CF51-2L", | 417 | .ident = "Panasonic CF51-2L", |
410 | .matches = { | 418 | .matches = { |
@@ -689,19 +697,25 @@ int acpi_pm_device_sleep_wake(struct device *dev, bool enable) | |||
689 | { | 697 | { |
690 | acpi_handle handle; | 698 | acpi_handle handle; |
691 | struct acpi_device *adev; | 699 | struct acpi_device *adev; |
700 | int error; | ||
692 | 701 | ||
693 | if (!device_may_wakeup(dev)) | 702 | if (!device_can_wakeup(dev)) |
694 | return -EINVAL; | 703 | return -EINVAL; |
695 | 704 | ||
696 | handle = DEVICE_ACPI_HANDLE(dev); | 705 | handle = DEVICE_ACPI_HANDLE(dev); |
697 | if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &adev))) { | 706 | if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &adev))) { |
698 | printk(KERN_DEBUG "ACPI handle has no context!\n"); | 707 | dev_dbg(dev, "ACPI handle has no context in %s!\n", __func__); |
699 | return -ENODEV; | 708 | return -ENODEV; |
700 | } | 709 | } |
701 | 710 | ||
702 | return enable ? | 711 | error = enable ? |
703 | acpi_enable_wakeup_device_power(adev, acpi_target_sleep_state) : | 712 | acpi_enable_wakeup_device_power(adev, acpi_target_sleep_state) : |
704 | 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; | ||
705 | } | 719 | } |
706 | #endif | 720 | #endif |
707 | 721 | ||
diff --git a/drivers/acpi/system.c b/drivers/acpi/system.c index 9c61ab2177cf..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 | ||
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 60ea984c84a0..94b1a4c5abab 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c | |||
@@ -40,10 +40,12 @@ | |||
40 | #include <linux/pci.h> | 40 | #include <linux/pci.h> |
41 | #include <linux/pci_ids.h> | 41 | #include <linux/pci_ids.h> |
42 | #include <asm/uaccess.h> | 42 | #include <asm/uaccess.h> |
43 | 43 | #include <linux/dmi.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 | 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" |
@@ -198,7 +200,7 @@ struct acpi_video_device { | |||
198 | struct acpi_device *dev; | 200 | struct acpi_device *dev; |
199 | struct acpi_video_device_brightness *brightness; | 201 | struct acpi_video_device_brightness *brightness; |
200 | struct backlight_device *backlight; | 202 | struct backlight_device *backlight; |
201 | struct thermal_cooling_device *cdev; | 203 | struct thermal_cooling_device *cooling_dev; |
202 | struct output_device *output_dev; | 204 | struct output_device *output_dev; |
203 | }; | 205 | }; |
204 | 206 | ||
@@ -387,20 +389,20 @@ static struct output_properties acpi_output_properties = { | |||
387 | 389 | ||
388 | 390 | ||
389 | /* thermal cooling device callbacks */ | 391 | /* thermal cooling device callbacks */ |
390 | static int video_get_max_state(struct thermal_cooling_device *cdev, unsigned | 392 | static int video_get_max_state(struct thermal_cooling_device *cooling_dev, unsigned |
391 | long *state) | 393 | long *state) |
392 | { | 394 | { |
393 | struct acpi_device *device = cdev->devdata; | 395 | struct acpi_device *device = cooling_dev->devdata; |
394 | struct acpi_video_device *video = acpi_driver_data(device); | 396 | struct acpi_video_device *video = acpi_driver_data(device); |
395 | 397 | ||
396 | *state = video->brightness->count - 3; | 398 | *state = video->brightness->count - 3; |
397 | return 0; | 399 | return 0; |
398 | } | 400 | } |
399 | 401 | ||
400 | static int video_get_cur_state(struct thermal_cooling_device *cdev, unsigned | 402 | static int video_get_cur_state(struct thermal_cooling_device *cooling_dev, unsigned |
401 | long *state) | 403 | long *state) |
402 | { | 404 | { |
403 | struct acpi_device *device = cdev->devdata; | 405 | struct acpi_device *device = cooling_dev->devdata; |
404 | struct acpi_video_device *video = acpi_driver_data(device); | 406 | struct acpi_video_device *video = acpi_driver_data(device); |
405 | unsigned long long level; | 407 | unsigned long long level; |
406 | int offset; | 408 | int offset; |
@@ -417,9 +419,9 @@ static int video_get_cur_state(struct thermal_cooling_device *cdev, unsigned | |||
417 | } | 419 | } |
418 | 420 | ||
419 | static int | 421 | static int |
420 | video_set_cur_state(struct thermal_cooling_device *cdev, unsigned long state) | 422 | video_set_cur_state(struct thermal_cooling_device *cooling_dev, unsigned long state) |
421 | { | 423 | { |
422 | struct acpi_device *device = cdev->devdata; | 424 | struct acpi_device *device = cooling_dev->devdata; |
423 | struct acpi_video_device *video = acpi_driver_data(device); | 425 | struct acpi_video_device *video = acpi_driver_data(device); |
424 | int level; | 426 | int level; |
425 | 427 | ||
@@ -603,6 +605,7 @@ acpi_video_device_lcd_get_level_current(struct acpi_video_device *device, | |||
603 | unsigned long long *level) | 605 | unsigned long long *level) |
604 | { | 606 | { |
605 | acpi_status status = AE_OK; | 607 | acpi_status status = AE_OK; |
608 | int i; | ||
606 | 609 | ||
607 | if (device->cap._BQC || device->cap._BCQ) { | 610 | if (device->cap._BQC || device->cap._BCQ) { |
608 | char *buf = device->cap._BQC ? "_BQC" : "_BCQ"; | 611 | char *buf = device->cap._BQC ? "_BQC" : "_BCQ"; |
@@ -618,8 +621,15 @@ acpi_video_device_lcd_get_level_current(struct acpi_video_device *device, | |||
618 | 621 | ||
619 | } | 622 | } |
620 | *level += bqc_offset_aml_bug_workaround; | 623 | *level += bqc_offset_aml_bug_workaround; |
621 | device->brightness->curr = *level; | 624 | for (i = 2; i < device->brightness->count; i++) |
622 | return 0; | 625 | if (device->brightness->levels[i] == *level) { |
626 | device->brightness->curr = *level; | ||
627 | return 0; | ||
628 | } | ||
629 | /* BQC returned an invalid level. Stop using it. */ | ||
630 | ACPI_WARNING((AE_INFO, "%s returned an invalid level", | ||
631 | buf)); | ||
632 | device->cap._BQC = device->cap._BCQ = 0; | ||
623 | } else { | 633 | } else { |
624 | /* Fixme: | 634 | /* Fixme: |
625 | * should we return an error or ignore this failure? | 635 | * should we return an error or ignore this failure? |
@@ -870,7 +880,7 @@ acpi_video_init_brightness(struct acpi_video_device *device) | |||
870 | br->flags._BCM_use_index = br->flags._BCL_use_index; | 880 | br->flags._BCM_use_index = br->flags._BCL_use_index; |
871 | 881 | ||
872 | /* _BQC uses INDEX while _BCL uses VALUE in some laptops */ | 882 | /* _BQC uses INDEX while _BCL uses VALUE in some laptops */ |
873 | br->curr = level_old = max_level; | 883 | br->curr = level = max_level; |
874 | 884 | ||
875 | if (!device->cap._BQC) | 885 | if (!device->cap._BQC) |
876 | goto set_level; | 886 | goto set_level; |
@@ -892,15 +902,25 @@ acpi_video_init_brightness(struct acpi_video_device *device) | |||
892 | 902 | ||
893 | br->flags._BQC_use_index = (level == max_level ? 0 : 1); | 903 | br->flags._BQC_use_index = (level == max_level ? 0 : 1); |
894 | 904 | ||
895 | if (!br->flags._BQC_use_index) | 905 | if (!br->flags._BQC_use_index) { |
906 | /* | ||
907 | * Set the backlight to the initial state. | ||
908 | * On some buggy laptops, _BQC returns an uninitialized value | ||
909 | * when invoked for the first time, i.e. level_old is invalid. | ||
910 | * set the backlight to max_level in this case | ||
911 | */ | ||
912 | for (i = 2; i < br->count; i++) | ||
913 | if (level_old == br->levels[i]) | ||
914 | level = level_old; | ||
896 | goto set_level; | 915 | goto set_level; |
916 | } | ||
897 | 917 | ||
898 | if (br->flags._BCL_reversed) | 918 | if (br->flags._BCL_reversed) |
899 | level_old = (br->count - 1) - level_old; | 919 | level_old = (br->count - 1) - level_old; |
900 | level_old = br->levels[level_old]; | 920 | level = br->levels[level_old]; |
901 | 921 | ||
902 | set_level: | 922 | set_level: |
903 | result = acpi_video_device_lcd_set_level(device, level_old); | 923 | result = acpi_video_device_lcd_set_level(device, level); |
904 | if (result) | 924 | if (result) |
905 | goto out_free_levels; | 925 | goto out_free_levels; |
906 | 926 | ||
@@ -934,9 +954,6 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) | |||
934 | { | 954 | { |
935 | acpi_handle h_dummy1; | 955 | acpi_handle h_dummy1; |
936 | 956 | ||
937 | |||
938 | memset(&device->cap, 0, sizeof(device->cap)); | ||
939 | |||
940 | if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_ADR", &h_dummy1))) { | 957 | if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_ADR", &h_dummy1))) { |
941 | device->cap._ADR = 1; | 958 | device->cap._ADR = 1; |
942 | } | 959 | } |
@@ -990,19 +1007,29 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) | |||
990 | if (result) | 1007 | if (result) |
991 | printk(KERN_ERR PREFIX "Create sysfs link\n"); | 1008 | printk(KERN_ERR PREFIX "Create sysfs link\n"); |
992 | 1009 | ||
993 | device->cdev = thermal_cooling_device_register("LCD", | 1010 | device->cooling_dev = thermal_cooling_device_register("LCD", |
994 | device->dev, &video_cooling_ops); | 1011 | device->dev, &video_cooling_ops); |
995 | if (IS_ERR(device->cdev)) | 1012 | if (IS_ERR(device->cooling_dev)) { |
1013 | /* | ||
1014 | * Set cooling_dev to NULL so we don't crash trying to | ||
1015 | * free it. | ||
1016 | * Also, why the hell we are returning early and | ||
1017 | * not attempt to register video output if cooling | ||
1018 | * device registration failed? | ||
1019 | * -- dtor | ||
1020 | */ | ||
1021 | device->cooling_dev = NULL; | ||
996 | return; | 1022 | return; |
1023 | } | ||
997 | 1024 | ||
998 | dev_info(&device->dev->dev, "registered as cooling_device%d\n", | 1025 | dev_info(&device->dev->dev, "registered as cooling_device%d\n", |
999 | device->cdev->id); | 1026 | device->cooling_dev->id); |
1000 | result = sysfs_create_link(&device->dev->dev.kobj, | 1027 | result = sysfs_create_link(&device->dev->dev.kobj, |
1001 | &device->cdev->device.kobj, | 1028 | &device->cooling_dev->device.kobj, |
1002 | "thermal_cooling"); | 1029 | "thermal_cooling"); |
1003 | if (result) | 1030 | if (result) |
1004 | printk(KERN_ERR PREFIX "Create sysfs link\n"); | 1031 | printk(KERN_ERR PREFIX "Create sysfs link\n"); |
1005 | result = sysfs_create_link(&device->cdev->device.kobj, | 1032 | result = sysfs_create_link(&device->cooling_dev->device.kobj, |
1006 | &device->dev->dev.kobj, "device"); | 1033 | &device->dev->dev.kobj, "device"); |
1007 | if (result) | 1034 | if (result) |
1008 | printk(KERN_ERR PREFIX "Create sysfs link\n"); | 1035 | printk(KERN_ERR PREFIX "Create sysfs link\n"); |
@@ -1039,7 +1066,6 @@ static void acpi_video_bus_find_cap(struct acpi_video_bus *video) | |||
1039 | { | 1066 | { |
1040 | acpi_handle h_dummy1; | 1067 | acpi_handle h_dummy1; |
1041 | 1068 | ||
1042 | memset(&video->cap, 0, sizeof(video->cap)); | ||
1043 | if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_DOS", &h_dummy1))) { | 1069 | if (ACPI_SUCCESS(acpi_get_handle(video->device->handle, "_DOS", &h_dummy1))) { |
1044 | video->cap._DOS = 1; | 1070 | video->cap._DOS = 1; |
1045 | } | 1071 | } |
@@ -2009,13 +2035,13 @@ static int acpi_video_bus_put_one_device(struct acpi_video_device *device) | |||
2009 | backlight_device_unregister(device->backlight); | 2035 | backlight_device_unregister(device->backlight); |
2010 | device->backlight = NULL; | 2036 | device->backlight = NULL; |
2011 | } | 2037 | } |
2012 | if (device->cdev) { | 2038 | if (device->cooling_dev) { |
2013 | sysfs_remove_link(&device->dev->dev.kobj, | 2039 | sysfs_remove_link(&device->dev->dev.kobj, |
2014 | "thermal_cooling"); | 2040 | "thermal_cooling"); |
2015 | sysfs_remove_link(&device->cdev->device.kobj, | 2041 | sysfs_remove_link(&device->cooling_dev->device.kobj, |
2016 | "device"); | 2042 | "device"); |
2017 | thermal_cooling_device_unregister(device->cdev); | 2043 | thermal_cooling_device_unregister(device->cooling_dev); |
2018 | device->cdev = NULL; | 2044 | device->cooling_dev = NULL; |
2019 | } | 2045 | } |
2020 | video_output_unregister(device->output_dev); | 2046 | video_output_unregister(device->output_dev); |
2021 | 2047 | ||
diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c index 7cd2b63435ea..7032f25da9b5 100644 --- a/drivers/acpi/video_detect.c +++ b/drivers/acpi/video_detect.c | |||
@@ -38,6 +38,8 @@ | |||
38 | #include <linux/dmi.h> | 38 | #include <linux/dmi.h> |
39 | #include <linux/pci.h> | 39 | #include <linux/pci.h> |
40 | 40 | ||
41 | #define PREFIX "ACPI: " | ||
42 | |||
41 | ACPI_MODULE_NAME("video"); | 43 | ACPI_MODULE_NAME("video"); |
42 | #define _COMPONENT ACPI_VIDEO_COMPONENT | 44 | #define _COMPONENT ACPI_VIDEO_COMPONENT |
43 | 45 | ||
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, |