diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-07 18:14:06 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-07 18:14:06 -0400 |
commit | d8dc91b753b881c60c766c06aeec87675a07df4a (patch) | |
tree | 9a02f81fc5436b424d88c2340dcd6b0fe6ae6cca | |
parent | 7035cdf36d5c4d913f68ff97e1c2e5603500d946 (diff) | |
parent | 3f44ea0d1c3835872033a6633135e16f87161202 (diff) |
Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux
Pul ACPI & Power Management updates from Len Brown:
- acpidump utility added
- intel_idle driver now supports IVB Xeon
- turbostat utility can now count SMIs
- ACPI can now bind to USB3 hubs
- misc fixes
* 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux: (49 commits)
ACPI: Add new sysfs interface to export device description
ACPI: Harden acpi_table_parse_entries() against BIOS bug
tools/power/turbostat: add option to count SMIs, re-name some options
tools/power turbostat: add [-d MSR#][-D MSR#] options to print counter deltas
intel_idle: enable IVB Xeon support
tools/power turbostat: add [-m MSR#] option
tools/power turbostat: make -M output pretty
tools/power turbostat: print more turbo-limit information
tools/power turbostat: delete unused line
tools/power turbostat: run on IVB Xeon
tools/power/acpi/acpidump: create acpidump(8), local make install targets
tools/power/acpi/acpidump: version 20101221 - find dynamic tables in sysfs
ACPI: run _OSC after ACPI_FULL_INITIALIZATION
tools/power/acpi/acpidump: create acpidump(8), local make install targets
tools/power/acpi/acpidump: version 20101221 - find dynamic tables in sysfs
tools/power/acpi/acpidump: version 20071116
tools/power/acpi/acpidump: version 20070714
tools/power/acpi/acpidump: version 20060606
tools/power/acpi/acpidump: version 20051111
xo15-ebook: convert to module_acpi_driver()
...
51 files changed, 2073 insertions, 737 deletions
diff --git a/Documentation/ABI/testing/sysfs-devices-firmware_node b/Documentation/ABI/testing/sysfs-devices-firmware_node new file mode 100644 index 000000000000..46badc9ea284 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-devices-firmware_node | |||
@@ -0,0 +1,17 @@ | |||
1 | What: /sys/devices/.../firmware_node/ | ||
2 | Date: September 2012 | ||
3 | Contact: <> | ||
4 | Description: | ||
5 | The /sys/devices/.../firmware_node directory contains attributes | ||
6 | allowing the user space to check and modify some firmware | ||
7 | related properties of given device. | ||
8 | |||
9 | What: /sys/devices/.../firmware_node/description | ||
10 | Date: September 2012 | ||
11 | Contact: Lance Ortiz <lance.ortiz@hp.com> | ||
12 | Description: | ||
13 | The /sys/devices/.../firmware/description attribute contains a string | ||
14 | that describes the device as provided by the _STR method in the ACPI | ||
15 | namespace. This attribute is read-only. If the device does not have | ||
16 | an _STR method associated with it in the ACPI namespace, this | ||
17 | attribute is not present. | ||
diff --git a/drivers/acpi/acpica/Makefile b/drivers/acpi/acpica/Makefile index 0a1b3435f920..7f1d40797e80 100644 --- a/drivers/acpi/acpica/Makefile +++ b/drivers/acpi/acpica/Makefile | |||
@@ -158,5 +158,6 @@ acpi-y += \ | |||
158 | utresrc.o \ | 158 | utresrc.o \ |
159 | utstate.o \ | 159 | utstate.o \ |
160 | utxface.o \ | 160 | utxface.o \ |
161 | utxfinit.o \ | ||
161 | utxferror.o \ | 162 | utxferror.o \ |
162 | utxfmutex.o | 163 | utxfmutex.o |
diff --git a/drivers/acpi/acpica/achware.h b/drivers/acpi/acpica/achware.h index 5de4ec72766d..d902d31abc6c 100644 --- a/drivers/acpi/acpica/achware.h +++ b/drivers/acpi/acpica/achware.h | |||
@@ -110,8 +110,7 @@ acpi_status acpi_hw_write_port(acpi_io_address address, u32 value, u32 width); | |||
110 | /* | 110 | /* |
111 | * hwgpe - GPE support | 111 | * hwgpe - GPE support |
112 | */ | 112 | */ |
113 | u32 acpi_hw_get_gpe_register_bit(struct acpi_gpe_event_info *gpe_event_info, | 113 | u32 acpi_hw_get_gpe_register_bit(struct acpi_gpe_event_info *gpe_event_info); |
114 | struct acpi_gpe_register_info *gpe_register_info); | ||
115 | 114 | ||
116 | acpi_status | 115 | acpi_status |
117 | acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u32 action); | 116 | acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u32 action); |
diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index cc80fe10e8ea..c816ee675094 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h | |||
@@ -707,15 +707,18 @@ union acpi_parse_value { | |||
707 | u8 disasm_opcode; /* Subtype used for disassembly */\ | 707 | u8 disasm_opcode; /* Subtype used for disassembly */\ |
708 | char aml_op_name[16]) /* Op name (debug only) */ | 708 | char aml_op_name[16]) /* Op name (debug only) */ |
709 | 709 | ||
710 | #define ACPI_DASM_BUFFER 0x00 | 710 | /* Flags for disasm_flags field above */ |
711 | #define ACPI_DASM_RESOURCE 0x01 | 711 | |
712 | #define ACPI_DASM_STRING 0x02 | 712 | #define ACPI_DASM_BUFFER 0x00 /* Buffer is a simple data buffer */ |
713 | #define ACPI_DASM_UNICODE 0x03 | 713 | #define ACPI_DASM_RESOURCE 0x01 /* Buffer is a Resource Descriptor */ |
714 | #define ACPI_DASM_EISAID 0x04 | 714 | #define ACPI_DASM_STRING 0x02 /* Buffer is a ASCII string */ |
715 | #define ACPI_DASM_MATCHOP 0x05 | 715 | #define ACPI_DASM_UNICODE 0x03 /* Buffer is a Unicode string */ |
716 | #define ACPI_DASM_LNOT_PREFIX 0x06 | 716 | #define ACPI_DASM_PLD_METHOD 0x04 /* Buffer is a _PLD method bit-packed buffer */ |
717 | #define ACPI_DASM_LNOT_SUFFIX 0x07 | 717 | #define ACPI_DASM_EISAID 0x05 /* Integer is an EISAID */ |
718 | #define ACPI_DASM_IGNORE 0x08 | 718 | #define ACPI_DASM_MATCHOP 0x06 /* Parent opcode is a Match() operator */ |
719 | #define ACPI_DASM_LNOT_PREFIX 0x07 /* Start of a Lnot_equal (etc.) pair of opcodes */ | ||
720 | #define ACPI_DASM_LNOT_SUFFIX 0x08 /* End of a Lnot_equal (etc.) pair of opcodes */ | ||
721 | #define ACPI_DASM_IGNORE 0x09 /* Not used at this time */ | ||
719 | 722 | ||
720 | /* | 723 | /* |
721 | * Generic operation (for example: If, While, Store) | 724 | * Generic operation (for example: If, While, Store) |
@@ -932,6 +935,7 @@ struct acpi_bit_register_info { | |||
932 | #define ACPI_OSI_WIN_VISTA_SP1 0x09 | 935 | #define ACPI_OSI_WIN_VISTA_SP1 0x09 |
933 | #define ACPI_OSI_WIN_VISTA_SP2 0x0A | 936 | #define ACPI_OSI_WIN_VISTA_SP2 0x0A |
934 | #define ACPI_OSI_WIN_7 0x0B | 937 | #define ACPI_OSI_WIN_7 0x0B |
938 | #define ACPI_OSI_WIN_8 0x0C | ||
935 | 939 | ||
936 | #define ACPI_ALWAYS_ILLEGAL 0x00 | 940 | #define ACPI_ALWAYS_ILLEGAL 0x00 |
937 | 941 | ||
@@ -1024,6 +1028,7 @@ struct acpi_port_info { | |||
1024 | ****************************************************************************/ | 1028 | ****************************************************************************/ |
1025 | 1029 | ||
1026 | struct acpi_db_method_info { | 1030 | struct acpi_db_method_info { |
1031 | acpi_handle method; | ||
1027 | acpi_handle main_thread_gate; | 1032 | acpi_handle main_thread_gate; |
1028 | acpi_handle thread_complete_gate; | 1033 | acpi_handle thread_complete_gate; |
1029 | acpi_thread_id *threads; | 1034 | acpi_thread_id *threads; |
diff --git a/drivers/acpi/acpica/acmacros.h b/drivers/acpi/acpica/acmacros.h index 832b6198652e..a7f68c47f517 100644 --- a/drivers/acpi/acpica/acmacros.h +++ b/drivers/acpi/acpica/acmacros.h | |||
@@ -277,10 +277,33 @@ | |||
277 | 277 | ||
278 | /* Bitfields within ACPI registers */ | 278 | /* Bitfields within ACPI registers */ |
279 | 279 | ||
280 | #define ACPI_REGISTER_PREPARE_BITS(val, pos, mask) ((val << pos) & mask) | 280 | #define ACPI_REGISTER_PREPARE_BITS(val, pos, mask) \ |
281 | #define ACPI_REGISTER_INSERT_VALUE(reg, pos, mask, val) reg = (reg & (~(mask))) | ACPI_REGISTER_PREPARE_BITS(val, pos, mask) | 281 | ((val << pos) & mask) |
282 | 282 | ||
283 | #define ACPI_INSERT_BITS(target, mask, source) target = ((target & (~(mask))) | (source & mask)) | 283 | #define ACPI_REGISTER_INSERT_VALUE(reg, pos, mask, val) \ |
284 | reg = (reg & (~(mask))) | ACPI_REGISTER_PREPARE_BITS(val, pos, mask) | ||
285 | |||
286 | #define ACPI_INSERT_BITS(target, mask, source) \ | ||
287 | target = ((target & (~(mask))) | (source & mask)) | ||
288 | |||
289 | /* Generic bitfield macros and masks */ | ||
290 | |||
291 | #define ACPI_GET_BITS(source_ptr, position, mask) \ | ||
292 | ((*source_ptr >> position) & mask) | ||
293 | |||
294 | #define ACPI_SET_BITS(target_ptr, position, mask, value) \ | ||
295 | (*target_ptr |= ((value & mask) << position)) | ||
296 | |||
297 | #define ACPI_1BIT_MASK 0x00000001 | ||
298 | #define ACPI_2BIT_MASK 0x00000003 | ||
299 | #define ACPI_3BIT_MASK 0x00000007 | ||
300 | #define ACPI_4BIT_MASK 0x0000000F | ||
301 | #define ACPI_5BIT_MASK 0x0000001F | ||
302 | #define ACPI_6BIT_MASK 0x0000003F | ||
303 | #define ACPI_7BIT_MASK 0x0000007F | ||
304 | #define ACPI_8BIT_MASK 0x000000FF | ||
305 | #define ACPI_16BIT_MASK 0x0000FFFF | ||
306 | #define ACPI_24BIT_MASK 0x00FFFFFF | ||
284 | 307 | ||
285 | /* | 308 | /* |
286 | * An object of type struct acpi_namespace_node can appear in some contexts | 309 | * An object of type struct acpi_namespace_node can appear in some contexts |
diff --git a/drivers/acpi/acpica/dswload.c b/drivers/acpi/acpica/dswload.c index 552aa3a50c84..557510084c7a 100644 --- a/drivers/acpi/acpica/dswload.c +++ b/drivers/acpi/acpica/dswload.c | |||
@@ -230,6 +230,20 @@ acpi_ds_load1_begin_op(struct acpi_walk_state * walk_state, | |||
230 | walk_state->scope_info->common.value = ACPI_TYPE_ANY; | 230 | walk_state->scope_info->common.value = ACPI_TYPE_ANY; |
231 | break; | 231 | break; |
232 | 232 | ||
233 | case ACPI_TYPE_METHOD: | ||
234 | |||
235 | /* | ||
236 | * Allow scope change to root during execution of module-level | ||
237 | * code. Root is typed METHOD during this time. | ||
238 | */ | ||
239 | if ((node == acpi_gbl_root_node) && | ||
240 | (walk_state-> | ||
241 | parse_flags & ACPI_PARSE_MODULE_LEVEL)) { | ||
242 | break; | ||
243 | } | ||
244 | |||
245 | /*lint -fallthrough */ | ||
246 | |||
233 | default: | 247 | default: |
234 | 248 | ||
235 | /* All other types are an error */ | 249 | /* All other types are an error */ |
diff --git a/drivers/acpi/acpica/dswload2.c b/drivers/acpi/acpica/dswload2.c index ae7147724763..89c0114210c0 100644 --- a/drivers/acpi/acpica/dswload2.c +++ b/drivers/acpi/acpica/dswload2.c | |||
@@ -230,6 +230,20 @@ acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state, | |||
230 | walk_state->scope_info->common.value = ACPI_TYPE_ANY; | 230 | walk_state->scope_info->common.value = ACPI_TYPE_ANY; |
231 | break; | 231 | break; |
232 | 232 | ||
233 | case ACPI_TYPE_METHOD: | ||
234 | |||
235 | /* | ||
236 | * Allow scope change to root during execution of module-level | ||
237 | * code. Root is typed METHOD during this time. | ||
238 | */ | ||
239 | if ((node == acpi_gbl_root_node) && | ||
240 | (walk_state-> | ||
241 | parse_flags & ACPI_PARSE_MODULE_LEVEL)) { | ||
242 | break; | ||
243 | } | ||
244 | |||
245 | /*lint -fallthrough */ | ||
246 | |||
233 | default: | 247 | default: |
234 | 248 | ||
235 | /* All other types are an error */ | 249 | /* All other types are an error */ |
diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c index afbd5cb391f6..ef0193d74b5d 100644 --- a/drivers/acpi/acpica/evgpe.c +++ b/drivers/acpi/acpica/evgpe.c | |||
@@ -80,8 +80,7 @@ acpi_ev_update_gpe_enable_mask(struct acpi_gpe_event_info *gpe_event_info) | |||
80 | return_ACPI_STATUS(AE_NOT_EXIST); | 80 | return_ACPI_STATUS(AE_NOT_EXIST); |
81 | } | 81 | } |
82 | 82 | ||
83 | register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info, | 83 | register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info); |
84 | gpe_register_info); | ||
85 | 84 | ||
86 | /* Clear the run bit up front */ | 85 | /* Clear the run bit up front */ |
87 | 86 | ||
@@ -379,6 +378,18 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list) | |||
379 | */ | 378 | */ |
380 | if (!(gpe_register_info->enable_for_run | | 379 | if (!(gpe_register_info->enable_for_run | |
381 | gpe_register_info->enable_for_wake)) { | 380 | gpe_register_info->enable_for_wake)) { |
381 | ACPI_DEBUG_PRINT((ACPI_DB_INTERRUPTS, | ||
382 | "Ignore disabled registers for GPE%02X-GPE%02X: " | ||
383 | "RunEnable=%02X, WakeEnable=%02X\n", | ||
384 | gpe_register_info-> | ||
385 | base_gpe_number, | ||
386 | gpe_register_info-> | ||
387 | base_gpe_number + | ||
388 | (ACPI_GPE_REGISTER_WIDTH - 1), | ||
389 | gpe_register_info-> | ||
390 | enable_for_run, | ||
391 | gpe_register_info-> | ||
392 | enable_for_wake)); | ||
382 | continue; | 393 | continue; |
383 | } | 394 | } |
384 | 395 | ||
@@ -401,9 +412,14 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list) | |||
401 | } | 412 | } |
402 | 413 | ||
403 | ACPI_DEBUG_PRINT((ACPI_DB_INTERRUPTS, | 414 | ACPI_DEBUG_PRINT((ACPI_DB_INTERRUPTS, |
404 | "Read GPE Register at GPE%02X: Status=%02X, Enable=%02X\n", | 415 | "Read registers for GPE%02X-GPE%02X: Status=%02X, Enable=%02X, " |
416 | "RunEnable=%02X, WakeEnable=%02X\n", | ||
405 | gpe_register_info->base_gpe_number, | 417 | gpe_register_info->base_gpe_number, |
406 | status_reg, enable_reg)); | 418 | gpe_register_info->base_gpe_number + |
419 | (ACPI_GPE_REGISTER_WIDTH - 1), | ||
420 | status_reg, enable_reg, | ||
421 | gpe_register_info->enable_for_run, | ||
422 | gpe_register_info->enable_for_wake)); | ||
407 | 423 | ||
408 | /* Check if there is anything active at all in this register */ | 424 | /* Check if there is anything active at all in this register */ |
409 | 425 | ||
diff --git a/drivers/acpi/acpica/evxfgpe.c b/drivers/acpi/acpica/evxfgpe.c index 6affbdb4b88c..87c5f2332260 100644 --- a/drivers/acpi/acpica/evxfgpe.c +++ b/drivers/acpi/acpica/evxfgpe.c | |||
@@ -357,8 +357,7 @@ acpi_status acpi_set_gpe_wake_mask(acpi_handle gpe_device, u32 gpe_number, u8 ac | |||
357 | goto unlock_and_exit; | 357 | goto unlock_and_exit; |
358 | } | 358 | } |
359 | 359 | ||
360 | register_bit = | 360 | register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info); |
361 | acpi_hw_get_gpe_register_bit(gpe_event_info, gpe_register_info); | ||
362 | 361 | ||
363 | /* Perform the action */ | 362 | /* Perform the action */ |
364 | 363 | ||
diff --git a/drivers/acpi/acpica/hwgpe.c b/drivers/acpi/acpica/hwgpe.c index 25bd28c4ae8d..db4076580e2b 100644 --- a/drivers/acpi/acpica/hwgpe.c +++ b/drivers/acpi/acpica/hwgpe.c | |||
@@ -60,7 +60,6 @@ acpi_hw_enable_wakeup_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, | |||
60 | * FUNCTION: acpi_hw_get_gpe_register_bit | 60 | * FUNCTION: acpi_hw_get_gpe_register_bit |
61 | * | 61 | * |
62 | * PARAMETERS: gpe_event_info - Info block for the GPE | 62 | * PARAMETERS: gpe_event_info - Info block for the GPE |
63 | * gpe_register_info - Info block for the GPE register | ||
64 | * | 63 | * |
65 | * RETURN: Register mask with a one in the GPE bit position | 64 | * RETURN: Register mask with a one in the GPE bit position |
66 | * | 65 | * |
@@ -69,11 +68,10 @@ acpi_hw_enable_wakeup_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, | |||
69 | * | 68 | * |
70 | ******************************************************************************/ | 69 | ******************************************************************************/ |
71 | 70 | ||
72 | u32 acpi_hw_get_gpe_register_bit(struct acpi_gpe_event_info *gpe_event_info, | 71 | u32 acpi_hw_get_gpe_register_bit(struct acpi_gpe_event_info *gpe_event_info) |
73 | struct acpi_gpe_register_info *gpe_register_info) | ||
74 | { | 72 | { |
75 | return (u32)1 << (gpe_event_info->gpe_number - | 73 | return (u32)1 << (gpe_event_info->gpe_number - |
76 | gpe_register_info->base_gpe_number); | 74 | gpe_event_info->register_info->base_gpe_number); |
77 | } | 75 | } |
78 | 76 | ||
79 | /****************************************************************************** | 77 | /****************************************************************************** |
@@ -115,8 +113,7 @@ acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u32 action) | |||
115 | 113 | ||
116 | /* Set or clear just the bit that corresponds to this GPE */ | 114 | /* Set or clear just the bit that corresponds to this GPE */ |
117 | 115 | ||
118 | register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info, | 116 | register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info); |
119 | gpe_register_info); | ||
120 | switch (action) { | 117 | switch (action) { |
121 | case ACPI_GPE_CONDITIONAL_ENABLE: | 118 | case ACPI_GPE_CONDITIONAL_ENABLE: |
122 | 119 | ||
@@ -178,8 +175,7 @@ acpi_status acpi_hw_clear_gpe(struct acpi_gpe_event_info * gpe_event_info) | |||
178 | * Write a one to the appropriate bit in the status register to | 175 | * Write a one to the appropriate bit in the status register to |
179 | * clear this GPE. | 176 | * clear this GPE. |
180 | */ | 177 | */ |
181 | register_bit = | 178 | register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info); |
182 | acpi_hw_get_gpe_register_bit(gpe_event_info, gpe_register_info); | ||
183 | 179 | ||
184 | status = acpi_hw_write(register_bit, | 180 | status = acpi_hw_write(register_bit, |
185 | &gpe_register_info->status_address); | 181 | &gpe_register_info->status_address); |
@@ -222,8 +218,7 @@ acpi_hw_get_gpe_status(struct acpi_gpe_event_info * gpe_event_info, | |||
222 | 218 | ||
223 | /* Get the register bitmask for this GPE */ | 219 | /* Get the register bitmask for this GPE */ |
224 | 220 | ||
225 | register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info, | 221 | register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info); |
226 | gpe_register_info); | ||
227 | 222 | ||
228 | /* GPE currently enabled? (enabled for runtime?) */ | 223 | /* GPE currently enabled? (enabled for runtime?) */ |
229 | 224 | ||
diff --git a/drivers/acpi/acpica/hwxfsleep.c b/drivers/acpi/acpica/hwxfsleep.c index 1f165a750ae2..0ff1ecea5c3a 100644 --- a/drivers/acpi/acpica/hwxfsleep.c +++ b/drivers/acpi/acpica/hwxfsleep.c | |||
@@ -381,7 +381,6 @@ ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state) | |||
381 | * FUNCTION: acpi_leave_sleep_state_prep | 381 | * FUNCTION: acpi_leave_sleep_state_prep |
382 | * | 382 | * |
383 | * PARAMETERS: sleep_state - Which sleep state we are exiting | 383 | * PARAMETERS: sleep_state - Which sleep state we are exiting |
384 | * flags - ACPI_EXECUTE_BFS to run optional method | ||
385 | * | 384 | * |
386 | * RETURN: Status | 385 | * RETURN: Status |
387 | * | 386 | * |
diff --git a/drivers/acpi/acpica/nsdump.c b/drivers/acpi/acpica/nsdump.c index 7ee4e6aeb0a2..2526aaf945ee 100644 --- a/drivers/acpi/acpica/nsdump.c +++ b/drivers/acpi/acpica/nsdump.c | |||
@@ -264,7 +264,7 @@ acpi_ns_dump_one_object(acpi_handle obj_handle, | |||
264 | switch (type) { | 264 | switch (type) { |
265 | case ACPI_TYPE_PROCESSOR: | 265 | case ACPI_TYPE_PROCESSOR: |
266 | 266 | ||
267 | acpi_os_printf("ID %X Len %.4X Addr %p\n", | 267 | acpi_os_printf("ID %02X Len %02X Addr %p\n", |
268 | obj_desc->processor.proc_id, | 268 | obj_desc->processor.proc_id, |
269 | obj_desc->processor.length, | 269 | obj_desc->processor.length, |
270 | ACPI_CAST_PTR(void, | 270 | ACPI_CAST_PTR(void, |
diff --git a/drivers/acpi/acpica/tbinstal.c b/drivers/acpi/acpica/tbinstal.c index 74f97d74db1c..70f9d787c82c 100644 --- a/drivers/acpi/acpica/tbinstal.c +++ b/drivers/acpi/acpica/tbinstal.c | |||
@@ -350,6 +350,7 @@ struct acpi_table_header *acpi_tb_table_override(struct acpi_table_header | |||
350 | acpi_status acpi_tb_resize_root_table_list(void) | 350 | acpi_status acpi_tb_resize_root_table_list(void) |
351 | { | 351 | { |
352 | struct acpi_table_desc *tables; | 352 | struct acpi_table_desc *tables; |
353 | u32 table_count; | ||
353 | 354 | ||
354 | ACPI_FUNCTION_TRACE(tb_resize_root_table_list); | 355 | ACPI_FUNCTION_TRACE(tb_resize_root_table_list); |
355 | 356 | ||
@@ -363,8 +364,13 @@ acpi_status acpi_tb_resize_root_table_list(void) | |||
363 | 364 | ||
364 | /* Increase the Table Array size */ | 365 | /* Increase the Table Array size */ |
365 | 366 | ||
366 | tables = ACPI_ALLOCATE_ZEROED(((acpi_size) acpi_gbl_root_table_list. | 367 | if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) { |
367 | max_table_count + | 368 | table_count = acpi_gbl_root_table_list.max_table_count; |
369 | } else { | ||
370 | table_count = acpi_gbl_root_table_list.current_table_count; | ||
371 | } | ||
372 | |||
373 | tables = ACPI_ALLOCATE_ZEROED(((acpi_size) table_count + | ||
368 | ACPI_ROOT_TABLE_SIZE_INCREMENT) * | 374 | ACPI_ROOT_TABLE_SIZE_INCREMENT) * |
369 | sizeof(struct acpi_table_desc)); | 375 | sizeof(struct acpi_table_desc)); |
370 | if (!tables) { | 376 | if (!tables) { |
@@ -377,8 +383,8 @@ acpi_status acpi_tb_resize_root_table_list(void) | |||
377 | 383 | ||
378 | if (acpi_gbl_root_table_list.tables) { | 384 | if (acpi_gbl_root_table_list.tables) { |
379 | ACPI_MEMCPY(tables, acpi_gbl_root_table_list.tables, | 385 | ACPI_MEMCPY(tables, acpi_gbl_root_table_list.tables, |
380 | (acpi_size) acpi_gbl_root_table_list. | 386 | (acpi_size) table_count * |
381 | max_table_count * sizeof(struct acpi_table_desc)); | 387 | sizeof(struct acpi_table_desc)); |
382 | 388 | ||
383 | if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) { | 389 | if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) { |
384 | ACPI_FREE(acpi_gbl_root_table_list.tables); | 390 | ACPI_FREE(acpi_gbl_root_table_list.tables); |
@@ -386,9 +392,9 @@ acpi_status acpi_tb_resize_root_table_list(void) | |||
386 | } | 392 | } |
387 | 393 | ||
388 | acpi_gbl_root_table_list.tables = tables; | 394 | acpi_gbl_root_table_list.tables = tables; |
389 | acpi_gbl_root_table_list.max_table_count += | 395 | acpi_gbl_root_table_list.max_table_count = |
390 | ACPI_ROOT_TABLE_SIZE_INCREMENT; | 396 | table_count + ACPI_ROOT_TABLE_SIZE_INCREMENT; |
391 | acpi_gbl_root_table_list.flags |= (u8)ACPI_ROOT_ORIGIN_ALLOCATED; | 397 | acpi_gbl_root_table_list.flags |= ACPI_ROOT_ORIGIN_ALLOCATED; |
392 | 398 | ||
393 | return_ACPI_STATUS(AE_OK); | 399 | return_ACPI_STATUS(AE_OK); |
394 | } | 400 | } |
diff --git a/drivers/acpi/acpica/tbxface.c b/drivers/acpi/acpica/tbxface.c index 29e51bc01383..21101262e47a 100644 --- a/drivers/acpi/acpica/tbxface.c +++ b/drivers/acpi/acpica/tbxface.c | |||
@@ -159,14 +159,12 @@ acpi_initialize_tables(struct acpi_table_desc * initial_table_array, | |||
159 | * DESCRIPTION: Reallocate Root Table List into dynamic memory. Copies the | 159 | * DESCRIPTION: Reallocate Root Table List into dynamic memory. Copies the |
160 | * root list from the previously provided scratch area. Should | 160 | * root list from the previously provided scratch area. Should |
161 | * be called once dynamic memory allocation is available in the | 161 | * be called once dynamic memory allocation is available in the |
162 | * kernel | 162 | * kernel. |
163 | * | 163 | * |
164 | ******************************************************************************/ | 164 | ******************************************************************************/ |
165 | acpi_status acpi_reallocate_root_table(void) | 165 | acpi_status acpi_reallocate_root_table(void) |
166 | { | 166 | { |
167 | struct acpi_table_desc *tables; | 167 | acpi_status status; |
168 | acpi_size new_size; | ||
169 | acpi_size current_size; | ||
170 | 168 | ||
171 | ACPI_FUNCTION_TRACE(acpi_reallocate_root_table); | 169 | ACPI_FUNCTION_TRACE(acpi_reallocate_root_table); |
172 | 170 | ||
@@ -178,39 +176,10 @@ acpi_status acpi_reallocate_root_table(void) | |||
178 | return_ACPI_STATUS(AE_SUPPORT); | 176 | return_ACPI_STATUS(AE_SUPPORT); |
179 | } | 177 | } |
180 | 178 | ||
181 | /* | 179 | acpi_gbl_root_table_list.flags |= ACPI_ROOT_ALLOW_RESIZE; |
182 | * Get the current size of the root table and add the default | ||
183 | * increment to create the new table size. | ||
184 | */ | ||
185 | current_size = (acpi_size) | ||
186 | acpi_gbl_root_table_list.current_table_count * | ||
187 | sizeof(struct acpi_table_desc); | ||
188 | |||
189 | new_size = current_size + | ||
190 | (ACPI_ROOT_TABLE_SIZE_INCREMENT * sizeof(struct acpi_table_desc)); | ||
191 | |||
192 | /* Create new array and copy the old array */ | ||
193 | |||
194 | tables = ACPI_ALLOCATE_ZEROED(new_size); | ||
195 | if (!tables) { | ||
196 | return_ACPI_STATUS(AE_NO_MEMORY); | ||
197 | } | ||
198 | 180 | ||
199 | ACPI_MEMCPY(tables, acpi_gbl_root_table_list.tables, current_size); | 181 | status = acpi_tb_resize_root_table_list(); |
200 | 182 | return_ACPI_STATUS(status); | |
201 | /* | ||
202 | * Update the root table descriptor. The new size will be the current | ||
203 | * number of tables plus the increment, independent of the reserved | ||
204 | * size of the original table list. | ||
205 | */ | ||
206 | acpi_gbl_root_table_list.tables = tables; | ||
207 | acpi_gbl_root_table_list.max_table_count = | ||
208 | acpi_gbl_root_table_list.current_table_count + | ||
209 | ACPI_ROOT_TABLE_SIZE_INCREMENT; | ||
210 | acpi_gbl_root_table_list.flags = | ||
211 | ACPI_ROOT_ORIGIN_ALLOCATED | ACPI_ROOT_ALLOW_RESIZE; | ||
212 | |||
213 | return_ACPI_STATUS(AE_OK); | ||
214 | } | 183 | } |
215 | 184 | ||
216 | /******************************************************************************* | 185 | /******************************************************************************* |
diff --git a/drivers/acpi/acpica/utosi.c b/drivers/acpi/acpica/utosi.c index 34ef0bd7e4b4..676285d6116d 100644 --- a/drivers/acpi/acpica/utosi.c +++ b/drivers/acpi/acpica/utosi.c | |||
@@ -73,6 +73,7 @@ static struct acpi_interface_info acpi_default_supported_interfaces[] = { | |||
73 | {"Windows 2006 SP1", NULL, 0, ACPI_OSI_WIN_VISTA_SP1}, /* Windows Vista SP1 - Added 09/2009 */ | 73 | {"Windows 2006 SP1", NULL, 0, ACPI_OSI_WIN_VISTA_SP1}, /* Windows Vista SP1 - Added 09/2009 */ |
74 | {"Windows 2006 SP2", NULL, 0, ACPI_OSI_WIN_VISTA_SP2}, /* Windows Vista SP2 - Added 09/2010 */ | 74 | {"Windows 2006 SP2", NULL, 0, ACPI_OSI_WIN_VISTA_SP2}, /* Windows Vista SP2 - Added 09/2010 */ |
75 | {"Windows 2009", NULL, 0, ACPI_OSI_WIN_7}, /* Windows 7 and Server 2008 R2 - Added 09/2009 */ | 75 | {"Windows 2009", NULL, 0, ACPI_OSI_WIN_7}, /* Windows 7 and Server 2008 R2 - Added 09/2009 */ |
76 | {"Windows 2012", NULL, 0, ACPI_OSI_WIN_8}, /* Windows 8 and Server 2012 - Added 08/2012 */ | ||
76 | 77 | ||
77 | /* Feature Group Strings */ | 78 | /* Feature Group Strings */ |
78 | 79 | ||
diff --git a/drivers/acpi/acpica/utxface.c b/drivers/acpi/acpica/utxface.c index 534179f1177b..b09632b4f5b3 100644 --- a/drivers/acpi/acpica/utxface.c +++ b/drivers/acpi/acpica/utxface.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Module Name: utxface - External interfaces for "global" ACPI functions | 3 | * Module Name: utxface - External interfaces, miscellaneous utility functions |
4 | * | 4 | * |
5 | *****************************************************************************/ | 5 | *****************************************************************************/ |
6 | 6 | ||
@@ -53,271 +53,6 @@ | |||
53 | #define _COMPONENT ACPI_UTILITIES | 53 | #define _COMPONENT ACPI_UTILITIES |
54 | ACPI_MODULE_NAME("utxface") | 54 | ACPI_MODULE_NAME("utxface") |
55 | 55 | ||
56 | #ifndef ACPI_ASL_COMPILER | ||
57 | /******************************************************************************* | ||
58 | * | ||
59 | * FUNCTION: acpi_initialize_subsystem | ||
60 | * | ||
61 | * PARAMETERS: None | ||
62 | * | ||
63 | * RETURN: Status | ||
64 | * | ||
65 | * DESCRIPTION: Initializes all global variables. This is the first function | ||
66 | * called, so any early initialization belongs here. | ||
67 | * | ||
68 | ******************************************************************************/ | ||
69 | acpi_status __init acpi_initialize_subsystem(void) | ||
70 | { | ||
71 | acpi_status status; | ||
72 | |||
73 | ACPI_FUNCTION_TRACE(acpi_initialize_subsystem); | ||
74 | |||
75 | acpi_gbl_startup_flags = ACPI_SUBSYSTEM_INITIALIZE; | ||
76 | ACPI_DEBUG_EXEC(acpi_ut_init_stack_ptr_trace()); | ||
77 | |||
78 | /* Initialize the OS-Dependent layer */ | ||
79 | |||
80 | status = acpi_os_initialize(); | ||
81 | if (ACPI_FAILURE(status)) { | ||
82 | ACPI_EXCEPTION((AE_INFO, status, "During OSL initialization")); | ||
83 | return_ACPI_STATUS(status); | ||
84 | } | ||
85 | |||
86 | /* Initialize all globals used by the subsystem */ | ||
87 | |||
88 | status = acpi_ut_init_globals(); | ||
89 | if (ACPI_FAILURE(status)) { | ||
90 | ACPI_EXCEPTION((AE_INFO, status, | ||
91 | "During initialization of globals")); | ||
92 | return_ACPI_STATUS(status); | ||
93 | } | ||
94 | |||
95 | /* Create the default mutex objects */ | ||
96 | |||
97 | status = acpi_ut_mutex_initialize(); | ||
98 | if (ACPI_FAILURE(status)) { | ||
99 | ACPI_EXCEPTION((AE_INFO, status, | ||
100 | "During Global Mutex creation")); | ||
101 | return_ACPI_STATUS(status); | ||
102 | } | ||
103 | |||
104 | /* | ||
105 | * Initialize the namespace manager and | ||
106 | * the root of the namespace tree | ||
107 | */ | ||
108 | status = acpi_ns_root_initialize(); | ||
109 | if (ACPI_FAILURE(status)) { | ||
110 | ACPI_EXCEPTION((AE_INFO, status, | ||
111 | "During Namespace initialization")); | ||
112 | return_ACPI_STATUS(status); | ||
113 | } | ||
114 | |||
115 | /* Initialize the global OSI interfaces list with the static names */ | ||
116 | |||
117 | status = acpi_ut_initialize_interfaces(); | ||
118 | if (ACPI_FAILURE(status)) { | ||
119 | ACPI_EXCEPTION((AE_INFO, status, | ||
120 | "During OSI interfaces initialization")); | ||
121 | return_ACPI_STATUS(status); | ||
122 | } | ||
123 | |||
124 | /* If configured, initialize the AML debugger */ | ||
125 | |||
126 | ACPI_DEBUGGER_EXEC(status = acpi_db_initialize()); | ||
127 | return_ACPI_STATUS(status); | ||
128 | } | ||
129 | |||
130 | /******************************************************************************* | ||
131 | * | ||
132 | * FUNCTION: acpi_enable_subsystem | ||
133 | * | ||
134 | * PARAMETERS: flags - Init/enable Options | ||
135 | * | ||
136 | * RETURN: Status | ||
137 | * | ||
138 | * DESCRIPTION: Completes the subsystem initialization including hardware. | ||
139 | * Puts system into ACPI mode if it isn't already. | ||
140 | * | ||
141 | ******************************************************************************/ | ||
142 | acpi_status acpi_enable_subsystem(u32 flags) | ||
143 | { | ||
144 | acpi_status status = AE_OK; | ||
145 | |||
146 | ACPI_FUNCTION_TRACE(acpi_enable_subsystem); | ||
147 | |||
148 | #if (!ACPI_REDUCED_HARDWARE) | ||
149 | |||
150 | /* Enable ACPI mode */ | ||
151 | |||
152 | if (!(flags & ACPI_NO_ACPI_ENABLE)) { | ||
153 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | ||
154 | "[Init] Going into ACPI mode\n")); | ||
155 | |||
156 | acpi_gbl_original_mode = acpi_hw_get_mode(); | ||
157 | |||
158 | status = acpi_enable(); | ||
159 | if (ACPI_FAILURE(status)) { | ||
160 | ACPI_WARNING((AE_INFO, "AcpiEnable failed")); | ||
161 | return_ACPI_STATUS(status); | ||
162 | } | ||
163 | } | ||
164 | |||
165 | /* | ||
166 | * Obtain a permanent mapping for the FACS. This is required for the | ||
167 | * Global Lock and the Firmware Waking Vector | ||
168 | */ | ||
169 | status = acpi_tb_initialize_facs(); | ||
170 | if (ACPI_FAILURE(status)) { | ||
171 | ACPI_WARNING((AE_INFO, "Could not map the FACS table")); | ||
172 | return_ACPI_STATUS(status); | ||
173 | } | ||
174 | #endif /* !ACPI_REDUCED_HARDWARE */ | ||
175 | |||
176 | /* | ||
177 | * Install the default op_region handlers. These are installed unless | ||
178 | * other handlers have already been installed via the | ||
179 | * install_address_space_handler interface. | ||
180 | */ | ||
181 | if (!(flags & ACPI_NO_ADDRESS_SPACE_INIT)) { | ||
182 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | ||
183 | "[Init] Installing default address space handlers\n")); | ||
184 | |||
185 | status = acpi_ev_install_region_handlers(); | ||
186 | if (ACPI_FAILURE(status)) { | ||
187 | return_ACPI_STATUS(status); | ||
188 | } | ||
189 | } | ||
190 | #if (!ACPI_REDUCED_HARDWARE) | ||
191 | /* | ||
192 | * Initialize ACPI Event handling (Fixed and General Purpose) | ||
193 | * | ||
194 | * Note1: We must have the hardware and events initialized before we can | ||
195 | * execute any control methods safely. Any control method can require | ||
196 | * ACPI hardware support, so the hardware must be fully initialized before | ||
197 | * any method execution! | ||
198 | * | ||
199 | * Note2: Fixed events are initialized and enabled here. GPEs are | ||
200 | * initialized, but cannot be enabled until after the hardware is | ||
201 | * completely initialized (SCI and global_lock activated) | ||
202 | */ | ||
203 | if (!(flags & ACPI_NO_EVENT_INIT)) { | ||
204 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | ||
205 | "[Init] Initializing ACPI events\n")); | ||
206 | |||
207 | status = acpi_ev_initialize_events(); | ||
208 | if (ACPI_FAILURE(status)) { | ||
209 | return_ACPI_STATUS(status); | ||
210 | } | ||
211 | } | ||
212 | |||
213 | /* | ||
214 | * Install the SCI handler and Global Lock handler. This completes the | ||
215 | * hardware initialization. | ||
216 | */ | ||
217 | if (!(flags & ACPI_NO_HANDLER_INIT)) { | ||
218 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | ||
219 | "[Init] Installing SCI/GL handlers\n")); | ||
220 | |||
221 | status = acpi_ev_install_xrupt_handlers(); | ||
222 | if (ACPI_FAILURE(status)) { | ||
223 | return_ACPI_STATUS(status); | ||
224 | } | ||
225 | } | ||
226 | #endif /* !ACPI_REDUCED_HARDWARE */ | ||
227 | |||
228 | return_ACPI_STATUS(status); | ||
229 | } | ||
230 | |||
231 | ACPI_EXPORT_SYMBOL(acpi_enable_subsystem) | ||
232 | |||
233 | /******************************************************************************* | ||
234 | * | ||
235 | * FUNCTION: acpi_initialize_objects | ||
236 | * | ||
237 | * PARAMETERS: flags - Init/enable Options | ||
238 | * | ||
239 | * RETURN: Status | ||
240 | * | ||
241 | * DESCRIPTION: Completes namespace initialization by initializing device | ||
242 | * objects and executing AML code for Regions, buffers, etc. | ||
243 | * | ||
244 | ******************************************************************************/ | ||
245 | acpi_status acpi_initialize_objects(u32 flags) | ||
246 | { | ||
247 | acpi_status status = AE_OK; | ||
248 | |||
249 | ACPI_FUNCTION_TRACE(acpi_initialize_objects); | ||
250 | |||
251 | /* | ||
252 | * Run all _REG methods | ||
253 | * | ||
254 | * Note: Any objects accessed by the _REG methods will be automatically | ||
255 | * initialized, even if they contain executable AML (see the call to | ||
256 | * acpi_ns_initialize_objects below). | ||
257 | */ | ||
258 | if (!(flags & ACPI_NO_ADDRESS_SPACE_INIT)) { | ||
259 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | ||
260 | "[Init] Executing _REG OpRegion methods\n")); | ||
261 | |||
262 | status = acpi_ev_initialize_op_regions(); | ||
263 | if (ACPI_FAILURE(status)) { | ||
264 | return_ACPI_STATUS(status); | ||
265 | } | ||
266 | } | ||
267 | |||
268 | /* | ||
269 | * Execute any module-level code that was detected during the table load | ||
270 | * phase. Although illegal since ACPI 2.0, there are many machines that | ||
271 | * contain this type of code. Each block of detected executable AML code | ||
272 | * outside of any control method is wrapped with a temporary control | ||
273 | * method object and placed on a global list. The methods on this list | ||
274 | * are executed below. | ||
275 | */ | ||
276 | acpi_ns_exec_module_code_list(); | ||
277 | |||
278 | /* | ||
279 | * Initialize the objects that remain uninitialized. This runs the | ||
280 | * executable AML that may be part of the declaration of these objects: | ||
281 | * operation_regions, buffer_fields, Buffers, and Packages. | ||
282 | */ | ||
283 | if (!(flags & ACPI_NO_OBJECT_INIT)) { | ||
284 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | ||
285 | "[Init] Completing Initialization of ACPI Objects\n")); | ||
286 | |||
287 | status = acpi_ns_initialize_objects(); | ||
288 | if (ACPI_FAILURE(status)) { | ||
289 | return_ACPI_STATUS(status); | ||
290 | } | ||
291 | } | ||
292 | |||
293 | /* | ||
294 | * Initialize all device objects in the namespace. This runs the device | ||
295 | * _STA and _INI methods. | ||
296 | */ | ||
297 | if (!(flags & ACPI_NO_DEVICE_INIT)) { | ||
298 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | ||
299 | "[Init] Initializing ACPI Devices\n")); | ||
300 | |||
301 | status = acpi_ns_initialize_devices(); | ||
302 | if (ACPI_FAILURE(status)) { | ||
303 | return_ACPI_STATUS(status); | ||
304 | } | ||
305 | } | ||
306 | |||
307 | /* | ||
308 | * Empty the caches (delete the cached objects) on the assumption that | ||
309 | * the table load filled them up more than they will be at runtime -- | ||
310 | * thus wasting non-paged memory. | ||
311 | */ | ||
312 | status = acpi_purge_cached_objects(); | ||
313 | |||
314 | acpi_gbl_startup_flags |= ACPI_INITIALIZED_OK; | ||
315 | return_ACPI_STATUS(status); | ||
316 | } | ||
317 | |||
318 | ACPI_EXPORT_SYMBOL(acpi_initialize_objects) | ||
319 | |||
320 | #endif | ||
321 | /******************************************************************************* | 56 | /******************************************************************************* |
322 | * | 57 | * |
323 | * FUNCTION: acpi_terminate | 58 | * FUNCTION: acpi_terminate |
@@ -683,3 +418,90 @@ acpi_check_address_range(acpi_adr_space_type space_id, | |||
683 | 418 | ||
684 | ACPI_EXPORT_SYMBOL(acpi_check_address_range) | 419 | ACPI_EXPORT_SYMBOL(acpi_check_address_range) |
685 | #endif /* !ACPI_ASL_COMPILER */ | 420 | #endif /* !ACPI_ASL_COMPILER */ |
421 | /******************************************************************************* | ||
422 | * | ||
423 | * FUNCTION: acpi_decode_pld_buffer | ||
424 | * | ||
425 | * PARAMETERS: in_buffer - Buffer returned by _PLD method | ||
426 | * length - Length of the in_buffer | ||
427 | * return_buffer - Where the decode buffer is returned | ||
428 | * | ||
429 | * RETURN: Status and the decoded _PLD buffer. User must deallocate | ||
430 | * the buffer via ACPI_FREE. | ||
431 | * | ||
432 | * DESCRIPTION: Decode the bit-packed buffer returned by the _PLD method into | ||
433 | * a local struct that is much more useful to an ACPI driver. | ||
434 | * | ||
435 | ******************************************************************************/ | ||
436 | acpi_status | ||
437 | acpi_decode_pld_buffer(u8 *in_buffer, | ||
438 | acpi_size length, struct acpi_pld_info ** return_buffer) | ||
439 | { | ||
440 | struct acpi_pld_info *pld_info; | ||
441 | u32 *buffer = ACPI_CAST_PTR(u32, in_buffer); | ||
442 | u32 dword; | ||
443 | |||
444 | /* Parameter validation */ | ||
445 | |||
446 | if (!in_buffer || !return_buffer || (length < 16)) { | ||
447 | return (AE_BAD_PARAMETER); | ||
448 | } | ||
449 | |||
450 | pld_info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_pld_info)); | ||
451 | if (!pld_info) { | ||
452 | return (AE_NO_MEMORY); | ||
453 | } | ||
454 | |||
455 | /* First 32-bit DWord */ | ||
456 | |||
457 | ACPI_MOVE_32_TO_32(&dword, &buffer[0]); | ||
458 | pld_info->revision = ACPI_PLD_GET_REVISION(&dword); | ||
459 | pld_info->ignore_color = ACPI_PLD_GET_IGNORE_COLOR(&dword); | ||
460 | pld_info->color = ACPI_PLD_GET_COLOR(&dword); | ||
461 | |||
462 | /* Second 32-bit DWord */ | ||
463 | |||
464 | ACPI_MOVE_32_TO_32(&dword, &buffer[1]); | ||
465 | pld_info->width = ACPI_PLD_GET_WIDTH(&dword); | ||
466 | pld_info->height = ACPI_PLD_GET_HEIGHT(&dword); | ||
467 | |||
468 | /* Third 32-bit DWord */ | ||
469 | |||
470 | ACPI_MOVE_32_TO_32(&dword, &buffer[2]); | ||
471 | pld_info->user_visible = ACPI_PLD_GET_USER_VISIBLE(&dword); | ||
472 | pld_info->dock = ACPI_PLD_GET_DOCK(&dword); | ||
473 | pld_info->lid = ACPI_PLD_GET_LID(&dword); | ||
474 | pld_info->panel = ACPI_PLD_GET_PANEL(&dword); | ||
475 | pld_info->vertical_position = ACPI_PLD_GET_VERTICAL(&dword); | ||
476 | pld_info->horizontal_position = ACPI_PLD_GET_HORIZONTAL(&dword); | ||
477 | pld_info->shape = ACPI_PLD_GET_SHAPE(&dword); | ||
478 | pld_info->group_orientation = ACPI_PLD_GET_ORIENTATION(&dword); | ||
479 | pld_info->group_token = ACPI_PLD_GET_TOKEN(&dword); | ||
480 | pld_info->group_position = ACPI_PLD_GET_POSITION(&dword); | ||
481 | pld_info->bay = ACPI_PLD_GET_BAY(&dword); | ||
482 | |||
483 | /* Fourth 32-bit DWord */ | ||
484 | |||
485 | ACPI_MOVE_32_TO_32(&dword, &buffer[3]); | ||
486 | pld_info->ejectable = ACPI_PLD_GET_EJECTABLE(&dword); | ||
487 | pld_info->ospm_eject_required = ACPI_PLD_GET_OSPM_EJECT(&dword); | ||
488 | pld_info->cabinet_number = ACPI_PLD_GET_CABINET(&dword); | ||
489 | pld_info->card_cage_number = ACPI_PLD_GET_CARD_CAGE(&dword); | ||
490 | pld_info->reference = ACPI_PLD_GET_REFERENCE(&dword); | ||
491 | pld_info->rotation = ACPI_PLD_GET_ROTATION(&dword); | ||
492 | pld_info->order = ACPI_PLD_GET_ORDER(&dword); | ||
493 | |||
494 | if (length >= ACPI_PLD_BUFFER_SIZE) { | ||
495 | |||
496 | /* Fifth 32-bit DWord (Revision 2 of _PLD) */ | ||
497 | |||
498 | ACPI_MOVE_32_TO_32(&dword, &buffer[4]); | ||
499 | pld_info->vertical_offset = ACPI_PLD_GET_VERT_OFFSET(&dword); | ||
500 | pld_info->horizontal_offset = ACPI_PLD_GET_HORIZ_OFFSET(&dword); | ||
501 | } | ||
502 | |||
503 | *return_buffer = pld_info; | ||
504 | return (AE_OK); | ||
505 | } | ||
506 | |||
507 | ACPI_EXPORT_SYMBOL(acpi_decode_pld_buffer) | ||
diff --git a/drivers/acpi/acpica/utxfinit.c b/drivers/acpi/acpica/utxfinit.c new file mode 100644 index 000000000000..14f523627a5e --- /dev/null +++ b/drivers/acpi/acpica/utxfinit.c | |||
@@ -0,0 +1,317 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Module Name: utxfinit - External interfaces for ACPICA initialization | ||
4 | * | ||
5 | *****************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2012, 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 <linux/export.h> | ||
45 | #include <acpi/acpi.h> | ||
46 | #include "accommon.h" | ||
47 | #include "acevents.h" | ||
48 | #include "acnamesp.h" | ||
49 | #include "acdebug.h" | ||
50 | #include "actables.h" | ||
51 | |||
52 | #define _COMPONENT ACPI_UTILITIES | ||
53 | ACPI_MODULE_NAME("utxfinit") | ||
54 | |||
55 | /******************************************************************************* | ||
56 | * | ||
57 | * FUNCTION: acpi_initialize_subsystem | ||
58 | * | ||
59 | * PARAMETERS: None | ||
60 | * | ||
61 | * RETURN: Status | ||
62 | * | ||
63 | * DESCRIPTION: Initializes all global variables. This is the first function | ||
64 | * called, so any early initialization belongs here. | ||
65 | * | ||
66 | ******************************************************************************/ | ||
67 | acpi_status acpi_initialize_subsystem(void) | ||
68 | { | ||
69 | acpi_status status; | ||
70 | |||
71 | ACPI_FUNCTION_TRACE(acpi_initialize_subsystem); | ||
72 | |||
73 | acpi_gbl_startup_flags = ACPI_SUBSYSTEM_INITIALIZE; | ||
74 | ACPI_DEBUG_EXEC(acpi_ut_init_stack_ptr_trace()); | ||
75 | |||
76 | /* Initialize the OS-Dependent layer */ | ||
77 | |||
78 | status = acpi_os_initialize(); | ||
79 | if (ACPI_FAILURE(status)) { | ||
80 | ACPI_EXCEPTION((AE_INFO, status, "During OSL initialization")); | ||
81 | return_ACPI_STATUS(status); | ||
82 | } | ||
83 | |||
84 | /* Initialize all globals used by the subsystem */ | ||
85 | |||
86 | status = acpi_ut_init_globals(); | ||
87 | if (ACPI_FAILURE(status)) { | ||
88 | ACPI_EXCEPTION((AE_INFO, status, | ||
89 | "During initialization of globals")); | ||
90 | return_ACPI_STATUS(status); | ||
91 | } | ||
92 | |||
93 | /* Create the default mutex objects */ | ||
94 | |||
95 | status = acpi_ut_mutex_initialize(); | ||
96 | if (ACPI_FAILURE(status)) { | ||
97 | ACPI_EXCEPTION((AE_INFO, status, | ||
98 | "During Global Mutex creation")); | ||
99 | return_ACPI_STATUS(status); | ||
100 | } | ||
101 | |||
102 | /* | ||
103 | * Initialize the namespace manager and | ||
104 | * the root of the namespace tree | ||
105 | */ | ||
106 | status = acpi_ns_root_initialize(); | ||
107 | if (ACPI_FAILURE(status)) { | ||
108 | ACPI_EXCEPTION((AE_INFO, status, | ||
109 | "During Namespace initialization")); | ||
110 | return_ACPI_STATUS(status); | ||
111 | } | ||
112 | |||
113 | /* Initialize the global OSI interfaces list with the static names */ | ||
114 | |||
115 | status = acpi_ut_initialize_interfaces(); | ||
116 | if (ACPI_FAILURE(status)) { | ||
117 | ACPI_EXCEPTION((AE_INFO, status, | ||
118 | "During OSI interfaces initialization")); | ||
119 | return_ACPI_STATUS(status); | ||
120 | } | ||
121 | |||
122 | /* If configured, initialize the AML debugger */ | ||
123 | |||
124 | ACPI_DEBUGGER_EXEC(status = acpi_db_initialize()); | ||
125 | return_ACPI_STATUS(status); | ||
126 | } | ||
127 | ACPI_EXPORT_SYMBOL(acpi_initialize_subsystem) | ||
128 | |||
129 | /******************************************************************************* | ||
130 | * | ||
131 | * FUNCTION: acpi_enable_subsystem | ||
132 | * | ||
133 | * PARAMETERS: flags - Init/enable Options | ||
134 | * | ||
135 | * RETURN: Status | ||
136 | * | ||
137 | * DESCRIPTION: Completes the subsystem initialization including hardware. | ||
138 | * Puts system into ACPI mode if it isn't already. | ||
139 | * | ||
140 | ******************************************************************************/ | ||
141 | acpi_status acpi_enable_subsystem(u32 flags) | ||
142 | { | ||
143 | acpi_status status = AE_OK; | ||
144 | |||
145 | ACPI_FUNCTION_TRACE(acpi_enable_subsystem); | ||
146 | |||
147 | #if (!ACPI_REDUCED_HARDWARE) | ||
148 | |||
149 | /* Enable ACPI mode */ | ||
150 | |||
151 | if (!(flags & ACPI_NO_ACPI_ENABLE)) { | ||
152 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | ||
153 | "[Init] Going into ACPI mode\n")); | ||
154 | |||
155 | acpi_gbl_original_mode = acpi_hw_get_mode(); | ||
156 | |||
157 | status = acpi_enable(); | ||
158 | if (ACPI_FAILURE(status)) { | ||
159 | ACPI_WARNING((AE_INFO, "AcpiEnable failed")); | ||
160 | return_ACPI_STATUS(status); | ||
161 | } | ||
162 | } | ||
163 | |||
164 | /* | ||
165 | * Obtain a permanent mapping for the FACS. This is required for the | ||
166 | * Global Lock and the Firmware Waking Vector | ||
167 | */ | ||
168 | status = acpi_tb_initialize_facs(); | ||
169 | if (ACPI_FAILURE(status)) { | ||
170 | ACPI_WARNING((AE_INFO, "Could not map the FACS table")); | ||
171 | return_ACPI_STATUS(status); | ||
172 | } | ||
173 | #endif /* !ACPI_REDUCED_HARDWARE */ | ||
174 | |||
175 | /* | ||
176 | * Install the default op_region handlers. These are installed unless | ||
177 | * other handlers have already been installed via the | ||
178 | * install_address_space_handler interface. | ||
179 | */ | ||
180 | if (!(flags & ACPI_NO_ADDRESS_SPACE_INIT)) { | ||
181 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | ||
182 | "[Init] Installing default address space handlers\n")); | ||
183 | |||
184 | status = acpi_ev_install_region_handlers(); | ||
185 | if (ACPI_FAILURE(status)) { | ||
186 | return_ACPI_STATUS(status); | ||
187 | } | ||
188 | } | ||
189 | #if (!ACPI_REDUCED_HARDWARE) | ||
190 | /* | ||
191 | * Initialize ACPI Event handling (Fixed and General Purpose) | ||
192 | * | ||
193 | * Note1: We must have the hardware and events initialized before we can | ||
194 | * execute any control methods safely. Any control method can require | ||
195 | * ACPI hardware support, so the hardware must be fully initialized before | ||
196 | * any method execution! | ||
197 | * | ||
198 | * Note2: Fixed events are initialized and enabled here. GPEs are | ||
199 | * initialized, but cannot be enabled until after the hardware is | ||
200 | * completely initialized (SCI and global_lock activated) and the various | ||
201 | * initialization control methods are run (_REG, _STA, _INI) on the | ||
202 | * entire namespace. | ||
203 | */ | ||
204 | if (!(flags & ACPI_NO_EVENT_INIT)) { | ||
205 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | ||
206 | "[Init] Initializing ACPI events\n")); | ||
207 | |||
208 | status = acpi_ev_initialize_events(); | ||
209 | if (ACPI_FAILURE(status)) { | ||
210 | return_ACPI_STATUS(status); | ||
211 | } | ||
212 | } | ||
213 | |||
214 | /* | ||
215 | * Install the SCI handler and Global Lock handler. This completes the | ||
216 | * hardware initialization. | ||
217 | */ | ||
218 | if (!(flags & ACPI_NO_HANDLER_INIT)) { | ||
219 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | ||
220 | "[Init] Installing SCI/GL handlers\n")); | ||
221 | |||
222 | status = acpi_ev_install_xrupt_handlers(); | ||
223 | if (ACPI_FAILURE(status)) { | ||
224 | return_ACPI_STATUS(status); | ||
225 | } | ||
226 | } | ||
227 | #endif /* !ACPI_REDUCED_HARDWARE */ | ||
228 | |||
229 | return_ACPI_STATUS(status); | ||
230 | } | ||
231 | ACPI_EXPORT_SYMBOL(acpi_enable_subsystem) | ||
232 | |||
233 | /******************************************************************************* | ||
234 | * | ||
235 | * FUNCTION: acpi_initialize_objects | ||
236 | * | ||
237 | * PARAMETERS: flags - Init/enable Options | ||
238 | * | ||
239 | * RETURN: Status | ||
240 | * | ||
241 | * DESCRIPTION: Completes namespace initialization by initializing device | ||
242 | * objects and executing AML code for Regions, buffers, etc. | ||
243 | * | ||
244 | ******************************************************************************/ | ||
245 | acpi_status acpi_initialize_objects(u32 flags) | ||
246 | { | ||
247 | acpi_status status = AE_OK; | ||
248 | |||
249 | ACPI_FUNCTION_TRACE(acpi_initialize_objects); | ||
250 | |||
251 | /* | ||
252 | * Run all _REG methods | ||
253 | * | ||
254 | * Note: Any objects accessed by the _REG methods will be automatically | ||
255 | * initialized, even if they contain executable AML (see the call to | ||
256 | * acpi_ns_initialize_objects below). | ||
257 | */ | ||
258 | if (!(flags & ACPI_NO_ADDRESS_SPACE_INIT)) { | ||
259 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | ||
260 | "[Init] Executing _REG OpRegion methods\n")); | ||
261 | |||
262 | status = acpi_ev_initialize_op_regions(); | ||
263 | if (ACPI_FAILURE(status)) { | ||
264 | return_ACPI_STATUS(status); | ||
265 | } | ||
266 | } | ||
267 | |||
268 | /* | ||
269 | * Execute any module-level code that was detected during the table load | ||
270 | * phase. Although illegal since ACPI 2.0, there are many machines that | ||
271 | * contain this type of code. Each block of detected executable AML code | ||
272 | * outside of any control method is wrapped with a temporary control | ||
273 | * method object and placed on a global list. The methods on this list | ||
274 | * are executed below. | ||
275 | */ | ||
276 | acpi_ns_exec_module_code_list(); | ||
277 | |||
278 | /* | ||
279 | * Initialize the objects that remain uninitialized. This runs the | ||
280 | * executable AML that may be part of the declaration of these objects: | ||
281 | * operation_regions, buffer_fields, Buffers, and Packages. | ||
282 | */ | ||
283 | if (!(flags & ACPI_NO_OBJECT_INIT)) { | ||
284 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | ||
285 | "[Init] Completing Initialization of ACPI Objects\n")); | ||
286 | |||
287 | status = acpi_ns_initialize_objects(); | ||
288 | if (ACPI_FAILURE(status)) { | ||
289 | return_ACPI_STATUS(status); | ||
290 | } | ||
291 | } | ||
292 | |||
293 | /* | ||
294 | * Initialize all device objects in the namespace. This runs the device | ||
295 | * _STA and _INI methods. | ||
296 | */ | ||
297 | if (!(flags & ACPI_NO_DEVICE_INIT)) { | ||
298 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | ||
299 | "[Init] Initializing ACPI Devices\n")); | ||
300 | |||
301 | status = acpi_ns_initialize_devices(); | ||
302 | if (ACPI_FAILURE(status)) { | ||
303 | return_ACPI_STATUS(status); | ||
304 | } | ||
305 | } | ||
306 | |||
307 | /* | ||
308 | * Empty the caches (delete the cached objects) on the assumption that | ||
309 | * the table load filled them up more than they will be at runtime -- | ||
310 | * thus wasting non-paged memory. | ||
311 | */ | ||
312 | status = acpi_purge_cached_objects(); | ||
313 | |||
314 | acpi_gbl_startup_flags |= ACPI_INITIALIZED_OK; | ||
315 | return_ACPI_STATUS(status); | ||
316 | } | ||
317 | ACPI_EXPORT_SYMBOL(acpi_initialize_objects) | ||
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index e0596954290b..d59175efc428 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c | |||
@@ -994,8 +994,6 @@ static int __init acpi_bus_init(void) | |||
994 | status = acpi_ec_ecdt_probe(); | 994 | status = acpi_ec_ecdt_probe(); |
995 | /* Ignore result. Not having an ECDT is not fatal. */ | 995 | /* Ignore result. Not having an ECDT is not fatal. */ |
996 | 996 | ||
997 | acpi_bus_osc_support(); | ||
998 | |||
999 | status = acpi_initialize_objects(ACPI_FULL_INITIALIZATION); | 997 | status = acpi_initialize_objects(ACPI_FULL_INITIALIZATION); |
1000 | if (ACPI_FAILURE(status)) { | 998 | if (ACPI_FAILURE(status)) { |
1001 | printk(KERN_ERR PREFIX "Unable to initialize ACPI objects\n"); | 999 | printk(KERN_ERR PREFIX "Unable to initialize ACPI objects\n"); |
@@ -1003,6 +1001,12 @@ static int __init acpi_bus_init(void) | |||
1003 | } | 1001 | } |
1004 | 1002 | ||
1005 | /* | 1003 | /* |
1004 | * _OSC method may exist in module level code, | ||
1005 | * so it must be run after ACPI_FULL_INITIALIZATION | ||
1006 | */ | ||
1007 | acpi_bus_osc_support(); | ||
1008 | |||
1009 | /* | ||
1006 | * _PDC control method may load dynamic SSDT tables, | 1010 | * _PDC control method may load dynamic SSDT tables, |
1007 | * and we need to install the table handler before that. | 1011 | * and we need to install the table handler before that. |
1008 | */ | 1012 | */ |
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c index 314a3b84bbc7..f0d936b65e37 100644 --- a/drivers/acpi/button.c +++ b/drivers/acpi/button.c | |||
@@ -450,15 +450,4 @@ static int acpi_button_remove(struct acpi_device *device, int type) | |||
450 | return 0; | 450 | return 0; |
451 | } | 451 | } |
452 | 452 | ||
453 | static int __init acpi_button_init(void) | 453 | module_acpi_driver(acpi_button_driver); |
454 | { | ||
455 | return acpi_bus_register_driver(&acpi_button_driver); | ||
456 | } | ||
457 | |||
458 | static void __exit acpi_button_exit(void) | ||
459 | { | ||
460 | acpi_bus_unregister_driver(&acpi_button_driver); | ||
461 | } | ||
462 | |||
463 | module_init(acpi_button_init); | ||
464 | module_exit(acpi_button_exit); | ||
diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c index bc36a476f1ab..3bd6a54702d6 100644 --- a/drivers/acpi/fan.c +++ b/drivers/acpi/fan.c | |||
@@ -212,24 +212,4 @@ static int acpi_fan_resume(struct device *dev) | |||
212 | } | 212 | } |
213 | #endif | 213 | #endif |
214 | 214 | ||
215 | static int __init acpi_fan_init(void) | 215 | module_acpi_driver(acpi_fan_driver); |
216 | { | ||
217 | int result = 0; | ||
218 | |||
219 | result = acpi_bus_register_driver(&acpi_fan_driver); | ||
220 | if (result < 0) | ||
221 | return -ENODEV; | ||
222 | |||
223 | return 0; | ||
224 | } | ||
225 | |||
226 | static void __exit acpi_fan_exit(void) | ||
227 | { | ||
228 | |||
229 | acpi_bus_unregister_driver(&acpi_fan_driver); | ||
230 | |||
231 | return; | ||
232 | } | ||
233 | |||
234 | module_init(acpi_fan_init); | ||
235 | module_exit(acpi_fan_exit); | ||
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index 243ee85e4d2e..d1a2d74033e9 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c | |||
@@ -25,6 +25,8 @@ | |||
25 | static LIST_HEAD(bus_type_list); | 25 | static LIST_HEAD(bus_type_list); |
26 | static DECLARE_RWSEM(bus_type_sem); | 26 | static DECLARE_RWSEM(bus_type_sem); |
27 | 27 | ||
28 | #define PHYSICAL_NODE_STRING "physical_node" | ||
29 | |||
28 | int register_acpi_bus_type(struct acpi_bus_type *type) | 30 | int register_acpi_bus_type(struct acpi_bus_type *type) |
29 | { | 31 | { |
30 | if (acpi_disabled) | 32 | if (acpi_disabled) |
@@ -124,84 +126,119 @@ acpi_handle acpi_get_child(acpi_handle parent, u64 address) | |||
124 | 126 | ||
125 | EXPORT_SYMBOL(acpi_get_child); | 127 | EXPORT_SYMBOL(acpi_get_child); |
126 | 128 | ||
127 | /* Link ACPI devices with physical devices */ | ||
128 | static void acpi_glue_data_handler(acpi_handle handle, | ||
129 | void *context) | ||
130 | { | ||
131 | /* we provide an empty handler */ | ||
132 | } | ||
133 | |||
134 | /* Note: a success call will increase reference count by one */ | ||
135 | struct device *acpi_get_physical_device(acpi_handle handle) | ||
136 | { | ||
137 | acpi_status status; | ||
138 | struct device *dev; | ||
139 | |||
140 | status = acpi_get_data(handle, acpi_glue_data_handler, (void **)&dev); | ||
141 | if (ACPI_SUCCESS(status)) | ||
142 | return get_device(dev); | ||
143 | return NULL; | ||
144 | } | ||
145 | |||
146 | EXPORT_SYMBOL(acpi_get_physical_device); | ||
147 | |||
148 | static int acpi_bind_one(struct device *dev, acpi_handle handle) | 129 | static int acpi_bind_one(struct device *dev, acpi_handle handle) |
149 | { | 130 | { |
150 | struct acpi_device *acpi_dev; | 131 | struct acpi_device *acpi_dev; |
151 | acpi_status status; | 132 | acpi_status status; |
133 | struct acpi_device_physical_node *physical_node; | ||
134 | char physical_node_name[sizeof(PHYSICAL_NODE_STRING) + 2]; | ||
135 | int retval = -EINVAL; | ||
152 | 136 | ||
153 | if (dev->archdata.acpi_handle) { | 137 | if (dev->archdata.acpi_handle) { |
154 | dev_warn(dev, "Drivers changed 'acpi_handle'\n"); | 138 | dev_warn(dev, "Drivers changed 'acpi_handle'\n"); |
155 | return -EINVAL; | 139 | return -EINVAL; |
156 | } | 140 | } |
141 | |||
157 | get_device(dev); | 142 | get_device(dev); |
158 | status = acpi_attach_data(handle, acpi_glue_data_handler, dev); | 143 | status = acpi_bus_get_device(handle, &acpi_dev); |
159 | if (ACPI_FAILURE(status)) { | 144 | if (ACPI_FAILURE(status)) |
160 | put_device(dev); | 145 | goto err; |
161 | return -EINVAL; | 146 | |
147 | physical_node = kzalloc(sizeof(struct acpi_device_physical_node), | ||
148 | GFP_KERNEL); | ||
149 | if (!physical_node) { | ||
150 | retval = -ENOMEM; | ||
151 | goto err; | ||
162 | } | 152 | } |
163 | dev->archdata.acpi_handle = handle; | ||
164 | 153 | ||
165 | status = acpi_bus_get_device(handle, &acpi_dev); | 154 | mutex_lock(&acpi_dev->physical_node_lock); |
166 | if (!ACPI_FAILURE(status)) { | 155 | /* allocate physical node id according to physical_node_id_bitmap */ |
167 | int ret; | 156 | physical_node->node_id = |
168 | 157 | find_first_zero_bit(acpi_dev->physical_node_id_bitmap, | |
169 | ret = sysfs_create_link(&dev->kobj, &acpi_dev->dev.kobj, | 158 | ACPI_MAX_PHYSICAL_NODE); |
170 | "firmware_node"); | 159 | if (physical_node->node_id >= ACPI_MAX_PHYSICAL_NODE) { |
171 | ret = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj, | 160 | retval = -ENOSPC; |
172 | "physical_node"); | 161 | mutex_unlock(&acpi_dev->physical_node_lock); |
173 | if (acpi_dev->wakeup.flags.valid) | 162 | goto err; |
174 | device_set_wakeup_capable(dev, true); | ||
175 | } | 163 | } |
176 | 164 | ||
165 | set_bit(physical_node->node_id, acpi_dev->physical_node_id_bitmap); | ||
166 | physical_node->dev = dev; | ||
167 | list_add_tail(&physical_node->node, &acpi_dev->physical_node_list); | ||
168 | acpi_dev->physical_node_count++; | ||
169 | mutex_unlock(&acpi_dev->physical_node_lock); | ||
170 | |||
171 | dev->archdata.acpi_handle = handle; | ||
172 | |||
173 | if (!physical_node->node_id) | ||
174 | strcpy(physical_node_name, PHYSICAL_NODE_STRING); | ||
175 | else | ||
176 | sprintf(physical_node_name, | ||
177 | "physical_node%d", physical_node->node_id); | ||
178 | retval = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj, | ||
179 | physical_node_name); | ||
180 | retval = sysfs_create_link(&dev->kobj, &acpi_dev->dev.kobj, | ||
181 | "firmware_node"); | ||
182 | |||
183 | if (acpi_dev->wakeup.flags.valid) | ||
184 | device_set_wakeup_capable(dev, true); | ||
185 | |||
177 | return 0; | 186 | return 0; |
187 | |||
188 | err: | ||
189 | put_device(dev); | ||
190 | return retval; | ||
178 | } | 191 | } |
179 | 192 | ||
180 | static int acpi_unbind_one(struct device *dev) | 193 | static int acpi_unbind_one(struct device *dev) |
181 | { | 194 | { |
195 | struct acpi_device_physical_node *entry; | ||
196 | struct acpi_device *acpi_dev; | ||
197 | acpi_status status; | ||
198 | struct list_head *node, *next; | ||
199 | |||
182 | if (!dev->archdata.acpi_handle) | 200 | if (!dev->archdata.acpi_handle) |
183 | return 0; | 201 | return 0; |
184 | if (dev == acpi_get_physical_device(dev->archdata.acpi_handle)) { | ||
185 | struct acpi_device *acpi_dev; | ||
186 | 202 | ||
187 | /* acpi_get_physical_device increase refcnt by one */ | 203 | status = acpi_bus_get_device(dev->archdata.acpi_handle, |
188 | put_device(dev); | 204 | &acpi_dev); |
205 | if (ACPI_FAILURE(status)) | ||
206 | goto err; | ||
189 | 207 | ||
190 | if (!acpi_bus_get_device(dev->archdata.acpi_handle, | 208 | mutex_lock(&acpi_dev->physical_node_lock); |
191 | &acpi_dev)) { | 209 | list_for_each_safe(node, next, &acpi_dev->physical_node_list) { |
192 | sysfs_remove_link(&dev->kobj, "firmware_node"); | 210 | char physical_node_name[sizeof(PHYSICAL_NODE_STRING) + 2]; |
193 | sysfs_remove_link(&acpi_dev->dev.kobj, "physical_node"); | 211 | |
194 | } | 212 | entry = list_entry(node, struct acpi_device_physical_node, |
213 | node); | ||
214 | if (entry->dev != dev) | ||
215 | continue; | ||
216 | |||
217 | list_del(node); | ||
218 | clear_bit(entry->node_id, acpi_dev->physical_node_id_bitmap); | ||
195 | 219 | ||
196 | acpi_detach_data(dev->archdata.acpi_handle, | 220 | acpi_dev->physical_node_count--; |
197 | acpi_glue_data_handler); | 221 | |
222 | if (!entry->node_id) | ||
223 | strcpy(physical_node_name, PHYSICAL_NODE_STRING); | ||
224 | else | ||
225 | sprintf(physical_node_name, | ||
226 | "physical_node%d", entry->node_id); | ||
227 | |||
228 | sysfs_remove_link(&acpi_dev->dev.kobj, physical_node_name); | ||
229 | sysfs_remove_link(&dev->kobj, "firmware_node"); | ||
198 | dev->archdata.acpi_handle = NULL; | 230 | dev->archdata.acpi_handle = NULL; |
199 | /* acpi_bind_one increase refcnt by one */ | 231 | /* acpi_bind_one increase refcnt by one */ |
200 | put_device(dev); | 232 | put_device(dev); |
201 | } else { | 233 | kfree(entry); |
202 | dev_err(dev, "Oops, 'acpi_handle' corrupt\n"); | ||
203 | } | 234 | } |
235 | mutex_unlock(&acpi_dev->physical_node_lock); | ||
236 | |||
204 | return 0; | 237 | return 0; |
238 | |||
239 | err: | ||
240 | dev_err(dev, "Oops, 'acpi_handle' corrupt\n"); | ||
241 | return -EINVAL; | ||
205 | } | 242 | } |
206 | 243 | ||
207 | static int acpi_platform_notify(struct device *dev) | 244 | static int acpi_platform_notify(struct device *dev) |
diff --git a/drivers/acpi/hed.c b/drivers/acpi/hed.c index d0c1967f7597..20a0f2c3ca3b 100644 --- a/drivers/acpi/hed.c +++ b/drivers/acpi/hed.c | |||
@@ -86,25 +86,7 @@ static struct acpi_driver acpi_hed_driver = { | |||
86 | .notify = acpi_hed_notify, | 86 | .notify = acpi_hed_notify, |
87 | }, | 87 | }, |
88 | }; | 88 | }; |
89 | 89 | module_acpi_driver(acpi_hed_driver); | |
90 | static int __init acpi_hed_init(void) | ||
91 | { | ||
92 | if (acpi_disabled) | ||
93 | return -ENODEV; | ||
94 | |||
95 | if (acpi_bus_register_driver(&acpi_hed_driver) < 0) | ||
96 | return -ENODEV; | ||
97 | |||
98 | return 0; | ||
99 | } | ||
100 | |||
101 | static void __exit acpi_hed_exit(void) | ||
102 | { | ||
103 | acpi_bus_unregister_driver(&acpi_hed_driver); | ||
104 | } | ||
105 | |||
106 | module_init(acpi_hed_init); | ||
107 | module_exit(acpi_hed_exit); | ||
108 | 90 | ||
109 | ACPI_MODULE_NAME("hed"); | 91 | ACPI_MODULE_NAME("hed"); |
110 | MODULE_AUTHOR("Huang Ying"); | 92 | MODULE_AUTHOR("Huang Ying"); |
diff --git a/drivers/acpi/proc.c b/drivers/acpi/proc.c index 251c7b6273a9..27adb090bb30 100644 --- a/drivers/acpi/proc.c +++ b/drivers/acpi/proc.c | |||
@@ -302,26 +302,41 @@ acpi_system_wakeup_device_seq_show(struct seq_file *seq, void *offset) | |||
302 | list_for_each_safe(node, next, &acpi_wakeup_device_list) { | 302 | list_for_each_safe(node, next, &acpi_wakeup_device_list) { |
303 | struct acpi_device *dev = | 303 | struct acpi_device *dev = |
304 | container_of(node, struct acpi_device, wakeup_list); | 304 | container_of(node, struct acpi_device, wakeup_list); |
305 | struct device *ldev; | 305 | struct acpi_device_physical_node *entry; |
306 | 306 | ||
307 | if (!dev->wakeup.flags.valid) | 307 | if (!dev->wakeup.flags.valid) |
308 | continue; | 308 | continue; |
309 | 309 | ||
310 | ldev = acpi_get_physical_device(dev->handle); | 310 | seq_printf(seq, "%s\t S%d\t", |
311 | seq_printf(seq, "%s\t S%d\t%c%-8s ", | ||
312 | dev->pnp.bus_id, | 311 | dev->pnp.bus_id, |
313 | (u32) dev->wakeup.sleep_state, | 312 | (u32) dev->wakeup.sleep_state); |
314 | dev->wakeup.flags.run_wake ? '*' : ' ', | 313 | |
315 | (device_may_wakeup(&dev->dev) | 314 | if (!dev->physical_node_count) |
316 | || (ldev && device_may_wakeup(ldev))) ? | 315 | seq_printf(seq, "%c%-8s\n", |
317 | "enabled" : "disabled"); | 316 | dev->wakeup.flags.run_wake ? |
318 | if (ldev) | 317 | '*' : ' ', "disabled"); |
319 | seq_printf(seq, "%s:%s", | 318 | else { |
320 | ldev->bus ? ldev->bus->name : "no-bus", | 319 | struct device *ldev; |
321 | dev_name(ldev)); | 320 | list_for_each_entry(entry, &dev->physical_node_list, |
322 | seq_printf(seq, "\n"); | 321 | node) { |
323 | put_device(ldev); | 322 | ldev = get_device(entry->dev); |
324 | 323 | if (!ldev) | |
324 | continue; | ||
325 | |||
326 | if (&entry->node != | ||
327 | dev->physical_node_list.next) | ||
328 | seq_printf(seq, "\t\t"); | ||
329 | |||
330 | seq_printf(seq, "%c%-8s %s:%s\n", | ||
331 | dev->wakeup.flags.run_wake ? '*' : ' ', | ||
332 | (device_may_wakeup(&dev->dev) || | ||
333 | (ldev && device_may_wakeup(ldev))) ? | ||
334 | "enabled" : "disabled", | ||
335 | ldev->bus ? ldev->bus->name : | ||
336 | "no-bus", dev_name(ldev)); | ||
337 | put_device(ldev); | ||
338 | } | ||
339 | } | ||
325 | } | 340 | } |
326 | mutex_unlock(&acpi_device_lock); | 341 | mutex_unlock(&acpi_device_lock); |
327 | return 0; | 342 | return 0; |
@@ -329,12 +344,14 @@ acpi_system_wakeup_device_seq_show(struct seq_file *seq, void *offset) | |||
329 | 344 | ||
330 | static void physical_device_enable_wakeup(struct acpi_device *adev) | 345 | static void physical_device_enable_wakeup(struct acpi_device *adev) |
331 | { | 346 | { |
332 | struct device *dev = acpi_get_physical_device(adev->handle); | 347 | struct acpi_device_physical_node *entry; |
333 | 348 | ||
334 | if (dev && device_can_wakeup(dev)) { | 349 | list_for_each_entry(entry, |
335 | bool enable = !device_may_wakeup(dev); | 350 | &adev->physical_node_list, node) |
336 | device_set_wakeup_enable(dev, enable); | 351 | if (entry->dev && device_can_wakeup(entry->dev)) { |
337 | } | 352 | bool enable = !device_may_wakeup(entry->dev); |
353 | device_set_wakeup_enable(entry->dev, enable); | ||
354 | } | ||
338 | } | 355 | } |
339 | 356 | ||
340 | static ssize_t | 357 | static ssize_t |
diff --git a/drivers/acpi/sbshc.c b/drivers/acpi/sbshc.c index f8d2a472795c..cf6129a8af7c 100644 --- a/drivers/acpi/sbshc.c +++ b/drivers/acpi/sbshc.c | |||
@@ -310,23 +310,7 @@ static int acpi_smbus_hc_remove(struct acpi_device *device, int type) | |||
310 | return 0; | 310 | return 0; |
311 | } | 311 | } |
312 | 312 | ||
313 | static int __init acpi_smb_hc_init(void) | 313 | module_acpi_driver(acpi_smb_hc_driver); |
314 | { | ||
315 | int result; | ||
316 | |||
317 | result = acpi_bus_register_driver(&acpi_smb_hc_driver); | ||
318 | if (result < 0) | ||
319 | return -ENODEV; | ||
320 | return 0; | ||
321 | } | ||
322 | |||
323 | static void __exit acpi_smb_hc_exit(void) | ||
324 | { | ||
325 | acpi_bus_unregister_driver(&acpi_smb_hc_driver); | ||
326 | } | ||
327 | |||
328 | module_init(acpi_smb_hc_init); | ||
329 | module_exit(acpi_smb_hc_exit); | ||
330 | 314 | ||
331 | MODULE_LICENSE("GPL"); | 315 | MODULE_LICENSE("GPL"); |
332 | MODULE_AUTHOR("Alexey Starikovskiy"); | 316 | MODULE_AUTHOR("Alexey Starikovskiy"); |
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index d1ecca2b641a..1fcb8678665c 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
@@ -10,6 +10,7 @@ | |||
10 | #include <linux/signal.h> | 10 | #include <linux/signal.h> |
11 | #include <linux/kthread.h> | 11 | #include <linux/kthread.h> |
12 | #include <linux/dmi.h> | 12 | #include <linux/dmi.h> |
13 | #include <linux/nls.h> | ||
13 | 14 | ||
14 | #include <acpi/acpi_drivers.h> | 15 | #include <acpi/acpi_drivers.h> |
15 | 16 | ||
@@ -232,8 +233,35 @@ end: | |||
232 | } | 233 | } |
233 | static DEVICE_ATTR(path, 0444, acpi_device_path_show, NULL); | 234 | static DEVICE_ATTR(path, 0444, acpi_device_path_show, NULL); |
234 | 235 | ||
236 | /* sysfs file that shows description text from the ACPI _STR method */ | ||
237 | static ssize_t description_show(struct device *dev, | ||
238 | struct device_attribute *attr, | ||
239 | char *buf) { | ||
240 | struct acpi_device *acpi_dev = to_acpi_device(dev); | ||
241 | int result; | ||
242 | |||
243 | if (acpi_dev->pnp.str_obj == NULL) | ||
244 | return 0; | ||
245 | |||
246 | /* | ||
247 | * The _STR object contains a Unicode identifier for a device. | ||
248 | * We need to convert to utf-8 so it can be displayed. | ||
249 | */ | ||
250 | result = utf16s_to_utf8s( | ||
251 | (wchar_t *)acpi_dev->pnp.str_obj->buffer.pointer, | ||
252 | acpi_dev->pnp.str_obj->buffer.length, | ||
253 | UTF16_LITTLE_ENDIAN, buf, | ||
254 | PAGE_SIZE); | ||
255 | |||
256 | buf[result++] = '\n'; | ||
257 | |||
258 | return result; | ||
259 | } | ||
260 | static DEVICE_ATTR(description, 0444, description_show, NULL); | ||
261 | |||
235 | static int acpi_device_setup_files(struct acpi_device *dev) | 262 | static int acpi_device_setup_files(struct acpi_device *dev) |
236 | { | 263 | { |
264 | struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; | ||
237 | acpi_status status; | 265 | acpi_status status; |
238 | acpi_handle temp; | 266 | acpi_handle temp; |
239 | int result = 0; | 267 | int result = 0; |
@@ -257,6 +285,21 @@ static int acpi_device_setup_files(struct acpi_device *dev) | |||
257 | goto end; | 285 | goto end; |
258 | } | 286 | } |
259 | 287 | ||
288 | /* | ||
289 | * If device has _STR, 'description' file is created | ||
290 | */ | ||
291 | status = acpi_get_handle(dev->handle, "_STR", &temp); | ||
292 | if (ACPI_SUCCESS(status)) { | ||
293 | status = acpi_evaluate_object(dev->handle, "_STR", | ||
294 | NULL, &buffer); | ||
295 | if (ACPI_FAILURE(status)) | ||
296 | buffer.pointer = NULL; | ||
297 | dev->pnp.str_obj = buffer.pointer; | ||
298 | result = device_create_file(&dev->dev, &dev_attr_description); | ||
299 | if (result) | ||
300 | goto end; | ||
301 | } | ||
302 | |||
260 | /* | 303 | /* |
261 | * If device has _EJ0, 'eject' file is created that is used to trigger | 304 | * If device has _EJ0, 'eject' file is created that is used to trigger |
262 | * hot-removal function from userland. | 305 | * hot-removal function from userland. |
@@ -274,8 +317,15 @@ static void acpi_device_remove_files(struct acpi_device *dev) | |||
274 | acpi_handle temp; | 317 | acpi_handle temp; |
275 | 318 | ||
276 | /* | 319 | /* |
277 | * If device has _EJ0, 'eject' file is created that is used to trigger | 320 | * If device has _STR, remove 'description' file |
278 | * hot-removal function from userland. | 321 | */ |
322 | status = acpi_get_handle(dev->handle, "_STR", &temp); | ||
323 | if (ACPI_SUCCESS(status)) { | ||
324 | kfree(dev->pnp.str_obj); | ||
325 | device_remove_file(&dev->dev, &dev_attr_description); | ||
326 | } | ||
327 | /* | ||
328 | * If device has _EJ0, remove 'eject' file. | ||
279 | */ | 329 | */ |
280 | status = acpi_get_handle(dev->handle, "_EJ0", &temp); | 330 | status = acpi_get_handle(dev->handle, "_EJ0", &temp); |
281 | if (ACPI_SUCCESS(status)) | 331 | if (ACPI_SUCCESS(status)) |
@@ -481,6 +531,8 @@ static int acpi_device_register(struct acpi_device *device) | |||
481 | INIT_LIST_HEAD(&device->children); | 531 | INIT_LIST_HEAD(&device->children); |
482 | INIT_LIST_HEAD(&device->node); | 532 | INIT_LIST_HEAD(&device->node); |
483 | INIT_LIST_HEAD(&device->wakeup_list); | 533 | INIT_LIST_HEAD(&device->wakeup_list); |
534 | INIT_LIST_HEAD(&device->physical_node_list); | ||
535 | mutex_init(&device->physical_node_lock); | ||
484 | 536 | ||
485 | new_bus_id = kzalloc(sizeof(struct acpi_device_bus_id), GFP_KERNEL); | 537 | new_bus_id = kzalloc(sizeof(struct acpi_device_bus_id), GFP_KERNEL); |
486 | if (!new_bus_id) { | 538 | if (!new_bus_id) { |
diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c index f336bca7c450..2572d9715bda 100644 --- a/drivers/acpi/tables.c +++ b/drivers/acpi/tables.c | |||
@@ -240,10 +240,17 @@ acpi_table_parse_entries(char *id, | |||
240 | table_end) { | 240 | table_end) { |
241 | if (entry->type == entry_id | 241 | if (entry->type == entry_id |
242 | && (!max_entries || count++ < max_entries)) | 242 | && (!max_entries || count++ < max_entries)) |
243 | if (handler(entry, table_end)) { | 243 | if (handler(entry, table_end)) |
244 | early_acpi_os_unmap_memory((char *)table_header, tbl_size); | 244 | goto err; |
245 | return -EINVAL; | 245 | |
246 | } | 246 | /* |
247 | * If entry->length is 0, break from this loop to avoid | ||
248 | * infinite loop. | ||
249 | */ | ||
250 | if (entry->length == 0) { | ||
251 | pr_err(PREFIX "[%4.4s:0x%02x] Invalid zero length\n", id, entry_id); | ||
252 | goto err; | ||
253 | } | ||
247 | 254 | ||
248 | entry = (struct acpi_subtable_header *) | 255 | entry = (struct acpi_subtable_header *) |
249 | ((unsigned long)entry + entry->length); | 256 | ((unsigned long)entry + entry->length); |
@@ -255,6 +262,9 @@ acpi_table_parse_entries(char *id, | |||
255 | 262 | ||
256 | early_acpi_os_unmap_memory((char *)table_header, tbl_size); | 263 | early_acpi_os_unmap_memory((char *)table_header, tbl_size); |
257 | return count; | 264 | return count; |
265 | err: | ||
266 | early_acpi_os_unmap_memory((char *)table_header, tbl_size); | ||
267 | return -EINVAL; | ||
258 | } | 268 | } |
259 | 269 | ||
260 | int __init | 270 | int __init |
diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c index 3e87c9c538aa..462f7e300363 100644 --- a/drivers/acpi/utils.c +++ b/drivers/acpi/utils.c | |||
@@ -384,7 +384,7 @@ acpi_evaluate_reference(acpi_handle handle, | |||
384 | EXPORT_SYMBOL(acpi_evaluate_reference); | 384 | EXPORT_SYMBOL(acpi_evaluate_reference); |
385 | 385 | ||
386 | acpi_status | 386 | acpi_status |
387 | acpi_get_physical_device_location(acpi_handle handle, struct acpi_pld *pld) | 387 | acpi_get_physical_device_location(acpi_handle handle, struct acpi_pld_info **pld) |
388 | { | 388 | { |
389 | acpi_status status; | 389 | acpi_status status; |
390 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | 390 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; |
@@ -400,13 +400,16 @@ acpi_get_physical_device_location(acpi_handle handle, struct acpi_pld *pld) | |||
400 | if (!output || output->type != ACPI_TYPE_PACKAGE | 400 | if (!output || output->type != ACPI_TYPE_PACKAGE |
401 | || !output->package.count | 401 | || !output->package.count |
402 | || output->package.elements[0].type != ACPI_TYPE_BUFFER | 402 | || output->package.elements[0].type != ACPI_TYPE_BUFFER |
403 | || output->package.elements[0].buffer.length > sizeof(*pld)) { | 403 | || output->package.elements[0].buffer.length < ACPI_PLD_REV1_BUFFER_SIZE) { |
404 | status = AE_TYPE; | 404 | status = AE_TYPE; |
405 | goto out; | 405 | goto out; |
406 | } | 406 | } |
407 | 407 | ||
408 | memcpy(pld, output->package.elements[0].buffer.pointer, | 408 | status = acpi_decode_pld_buffer( |
409 | output->package.elements[0].buffer.length); | 409 | output->package.elements[0].buffer.pointer, |
410 | output->package.elements[0].buffer.length, | ||
411 | pld); | ||
412 | |||
410 | out: | 413 | out: |
411 | kfree(buffer.pointer); | 414 | kfree(buffer.pointer); |
412 | return status; | 415 | return status; |
diff --git a/drivers/i2c/busses/i2c-scmi.c b/drivers/i2c/busses/i2c-scmi.c index 388cbdc96db7..6aafa3d88ff0 100644 --- a/drivers/i2c/busses/i2c-scmi.c +++ b/drivers/i2c/busses/i2c-scmi.c | |||
@@ -426,19 +426,7 @@ static struct acpi_driver acpi_smbus_cmi_driver = { | |||
426 | .remove = acpi_smbus_cmi_remove, | 426 | .remove = acpi_smbus_cmi_remove, |
427 | }, | 427 | }, |
428 | }; | 428 | }; |
429 | 429 | module_acpi_driver(acpi_smbus_cmi_driver); | |
430 | static int __init acpi_smbus_cmi_init(void) | ||
431 | { | ||
432 | return acpi_bus_register_driver(&acpi_smbus_cmi_driver); | ||
433 | } | ||
434 | |||
435 | static void __exit acpi_smbus_cmi_exit(void) | ||
436 | { | ||
437 | acpi_bus_unregister_driver(&acpi_smbus_cmi_driver); | ||
438 | } | ||
439 | |||
440 | module_init(acpi_smbus_cmi_init); | ||
441 | module_exit(acpi_smbus_cmi_exit); | ||
442 | 430 | ||
443 | MODULE_LICENSE("GPL"); | 431 | MODULE_LICENSE("GPL"); |
444 | MODULE_AUTHOR("Crane Cai <crane.cai@amd.com>"); | 432 | MODULE_AUTHOR("Crane Cai <crane.cai@amd.com>"); |
diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c index e8726177d103..b0f6b4c8ee14 100644 --- a/drivers/idle/intel_idle.c +++ b/drivers/idle/intel_idle.c | |||
@@ -413,6 +413,7 @@ static const struct x86_cpu_id intel_idle_ids[] = { | |||
413 | ICPU(0x2a, idle_cpu_snb), | 413 | ICPU(0x2a, idle_cpu_snb), |
414 | ICPU(0x2d, idle_cpu_snb), | 414 | ICPU(0x2d, idle_cpu_snb), |
415 | ICPU(0x3a, idle_cpu_ivb), | 415 | ICPU(0x3a, idle_cpu_ivb), |
416 | ICPU(0x3e, idle_cpu_ivb), | ||
416 | {} | 417 | {} |
417 | }; | 418 | }; |
418 | MODULE_DEVICE_TABLE(x86cpu, intel_idle_ids); | 419 | MODULE_DEVICE_TABLE(x86cpu, intel_idle_ids); |
diff --git a/drivers/input/misc/atlas_btns.c b/drivers/input/misc/atlas_btns.c index 601f7372f9c4..26f13131639a 100644 --- a/drivers/input/misc/atlas_btns.c +++ b/drivers/input/misc/atlas_btns.c | |||
@@ -151,22 +151,7 @@ static struct acpi_driver atlas_acpi_driver = { | |||
151 | .remove = atlas_acpi_button_remove, | 151 | .remove = atlas_acpi_button_remove, |
152 | }, | 152 | }, |
153 | }; | 153 | }; |
154 | 154 | module_acpi_driver(atlas_acpi_driver); | |
155 | static int __init atlas_acpi_init(void) | ||
156 | { | ||
157 | if (acpi_disabled) | ||
158 | return -ENODEV; | ||
159 | |||
160 | return acpi_bus_register_driver(&atlas_acpi_driver); | ||
161 | } | ||
162 | |||
163 | static void __exit atlas_acpi_exit(void) | ||
164 | { | ||
165 | acpi_bus_unregister_driver(&atlas_acpi_driver); | ||
166 | } | ||
167 | |||
168 | module_init(atlas_acpi_init); | ||
169 | module_exit(atlas_acpi_exit); | ||
170 | 155 | ||
171 | MODULE_AUTHOR("Jaya Kumar"); | 156 | MODULE_AUTHOR("Jaya Kumar"); |
172 | MODULE_LICENSE("GPL"); | 157 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/platform/x86/hp_accel.c b/drivers/platform/x86/hp_accel.c index 6b9af989632b..18d74f29dcb2 100644 --- a/drivers/platform/x86/hp_accel.c +++ b/drivers/platform/x86/hp_accel.c | |||
@@ -382,31 +382,8 @@ static struct acpi_driver lis3lv02d_driver = { | |||
382 | }, | 382 | }, |
383 | .drv.pm = HP_ACCEL_PM, | 383 | .drv.pm = HP_ACCEL_PM, |
384 | }; | 384 | }; |
385 | 385 | module_acpi_driver(lis3lv02d_driver); | |
386 | static int __init lis3lv02d_init_module(void) | ||
387 | { | ||
388 | int ret; | ||
389 | |||
390 | if (acpi_disabled) | ||
391 | return -ENODEV; | ||
392 | |||
393 | ret = acpi_bus_register_driver(&lis3lv02d_driver); | ||
394 | if (ret < 0) | ||
395 | return ret; | ||
396 | |||
397 | pr_info("driver loaded\n"); | ||
398 | |||
399 | return 0; | ||
400 | } | ||
401 | |||
402 | static void __exit lis3lv02d_exit_module(void) | ||
403 | { | ||
404 | acpi_bus_unregister_driver(&lis3lv02d_driver); | ||
405 | } | ||
406 | 386 | ||
407 | MODULE_DESCRIPTION("Glue between LIS3LV02Dx and HP ACPI BIOS and support for disk protection LED."); | 387 | MODULE_DESCRIPTION("Glue between LIS3LV02Dx and HP ACPI BIOS and support for disk protection LED."); |
408 | MODULE_AUTHOR("Yan Burman, Eric Piel, Pavel Machek"); | 388 | MODULE_AUTHOR("Yan Burman, Eric Piel, Pavel Machek"); |
409 | MODULE_LICENSE("GPL"); | 389 | MODULE_LICENSE("GPL"); |
410 | |||
411 | module_init(lis3lv02d_init_module); | ||
412 | module_exit(lis3lv02d_exit_module); | ||
diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c index dae7abe1d711..5ff4f2e314d2 100644 --- a/drivers/platform/x86/ideapad-laptop.c +++ b/drivers/platform/x86/ideapad-laptop.c | |||
@@ -917,20 +917,8 @@ static struct acpi_driver ideapad_acpi_driver = { | |||
917 | .drv.pm = &ideapad_pm, | 917 | .drv.pm = &ideapad_pm, |
918 | .owner = THIS_MODULE, | 918 | .owner = THIS_MODULE, |
919 | }; | 919 | }; |
920 | 920 | module_acpi_driver(ideapad_acpi_driver); | |
921 | static int __init ideapad_acpi_module_init(void) | ||
922 | { | ||
923 | return acpi_bus_register_driver(&ideapad_acpi_driver); | ||
924 | } | ||
925 | |||
926 | static void __exit ideapad_acpi_module_exit(void) | ||
927 | { | ||
928 | acpi_bus_unregister_driver(&ideapad_acpi_driver); | ||
929 | } | ||
930 | 921 | ||
931 | MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>"); | 922 | MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>"); |
932 | MODULE_DESCRIPTION("IdeaPad ACPI Extras"); | 923 | MODULE_DESCRIPTION("IdeaPad ACPI Extras"); |
933 | MODULE_LICENSE("GPL"); | 924 | MODULE_LICENSE("GPL"); |
934 | |||
935 | module_init(ideapad_acpi_module_init); | ||
936 | module_exit(ideapad_acpi_module_exit); | ||
diff --git a/drivers/platform/x86/topstar-laptop.c b/drivers/platform/x86/topstar-laptop.c index d528daa0e81c..d727bfee89a6 100644 --- a/drivers/platform/x86/topstar-laptop.c +++ b/drivers/platform/x86/topstar-laptop.c | |||
@@ -186,27 +186,7 @@ static struct acpi_driver acpi_topstar_driver = { | |||
186 | .notify = acpi_topstar_notify, | 186 | .notify = acpi_topstar_notify, |
187 | }, | 187 | }, |
188 | }; | 188 | }; |
189 | 189 | module_acpi_driver(acpi_topstar_driver); | |
190 | static int __init topstar_laptop_init(void) | ||
191 | { | ||
192 | int ret; | ||
193 | |||
194 | ret = acpi_bus_register_driver(&acpi_topstar_driver); | ||
195 | if (ret < 0) | ||
196 | return ret; | ||
197 | |||
198 | pr_info("ACPI extras driver loaded\n"); | ||
199 | |||
200 | return 0; | ||
201 | } | ||
202 | |||
203 | static void __exit topstar_laptop_exit(void) | ||
204 | { | ||
205 | acpi_bus_unregister_driver(&acpi_topstar_driver); | ||
206 | } | ||
207 | |||
208 | module_init(topstar_laptop_init); | ||
209 | module_exit(topstar_laptop_exit); | ||
210 | 190 | ||
211 | MODULE_AUTHOR("Herton Ronaldo Krzesinski"); | 191 | MODULE_AUTHOR("Herton Ronaldo Krzesinski"); |
212 | MODULE_DESCRIPTION("Topstar Laptop ACPI Extras driver"); | 192 | MODULE_DESCRIPTION("Topstar Laptop ACPI Extras driver"); |
diff --git a/drivers/platform/x86/toshiba_bluetooth.c b/drivers/platform/x86/toshiba_bluetooth.c index 5e5d6317d690..e95be0b74859 100644 --- a/drivers/platform/x86/toshiba_bluetooth.c +++ b/drivers/platform/x86/toshiba_bluetooth.c | |||
@@ -122,30 +122,10 @@ static int toshiba_bt_rfkill_add(struct acpi_device *device) | |||
122 | return result; | 122 | return result; |
123 | } | 123 | } |
124 | 124 | ||
125 | static int __init toshiba_bt_rfkill_init(void) | ||
126 | { | ||
127 | int result; | ||
128 | |||
129 | result = acpi_bus_register_driver(&toshiba_bt_rfkill_driver); | ||
130 | if (result < 0) { | ||
131 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
132 | "Error registering driver\n")); | ||
133 | return result; | ||
134 | } | ||
135 | |||
136 | return 0; | ||
137 | } | ||
138 | |||
139 | static int toshiba_bt_rfkill_remove(struct acpi_device *device, int type) | 125 | static int toshiba_bt_rfkill_remove(struct acpi_device *device, int type) |
140 | { | 126 | { |
141 | /* clean up */ | 127 | /* clean up */ |
142 | return 0; | 128 | return 0; |
143 | } | 129 | } |
144 | 130 | ||
145 | static void __exit toshiba_bt_rfkill_exit(void) | 131 | module_acpi_driver(toshiba_bt_rfkill_driver); |
146 | { | ||
147 | acpi_bus_unregister_driver(&toshiba_bt_rfkill_driver); | ||
148 | } | ||
149 | |||
150 | module_init(toshiba_bt_rfkill_init); | ||
151 | module_exit(toshiba_bt_rfkill_exit); | ||
diff --git a/drivers/platform/x86/xo15-ebook.c b/drivers/platform/x86/xo15-ebook.c index 38ba39d7ca7d..16d340c3b852 100644 --- a/drivers/platform/x86/xo15-ebook.c +++ b/drivers/platform/x86/xo15-ebook.c | |||
@@ -170,16 +170,4 @@ static struct acpi_driver xo15_ebook_driver = { | |||
170 | }, | 170 | }, |
171 | .drv.pm = &ebook_switch_pm, | 171 | .drv.pm = &ebook_switch_pm, |
172 | }; | 172 | }; |
173 | 173 | module_acpi_driver(xo15_ebook_driver); | |
174 | static int __init xo15_ebook_init(void) | ||
175 | { | ||
176 | return acpi_bus_register_driver(&xo15_ebook_driver); | ||
177 | } | ||
178 | |||
179 | static void __exit xo15_ebook_exit(void) | ||
180 | { | ||
181 | acpi_bus_unregister_driver(&xo15_ebook_driver); | ||
182 | } | ||
183 | |||
184 | module_init(xo15_ebook_init); | ||
185 | module_exit(xo15_ebook_exit); | ||
diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c index 507a8e2b9a4c..26b5d4b18dd7 100644 --- a/drivers/pnp/pnpacpi/core.c +++ b/drivers/pnp/pnpacpi/core.c | |||
@@ -321,14 +321,9 @@ static int __init acpi_pnp_match(struct device *dev, void *_pnp) | |||
321 | { | 321 | { |
322 | struct acpi_device *acpi = to_acpi_device(dev); | 322 | struct acpi_device *acpi = to_acpi_device(dev); |
323 | struct pnp_dev *pnp = _pnp; | 323 | struct pnp_dev *pnp = _pnp; |
324 | struct device *physical_device; | ||
325 | |||
326 | physical_device = acpi_get_physical_device(acpi->handle); | ||
327 | if (physical_device) | ||
328 | put_device(physical_device); | ||
329 | 324 | ||
330 | /* true means it matched */ | 325 | /* true means it matched */ |
331 | return !physical_device | 326 | return !acpi->physical_node_count |
332 | && compare_pnp_id(pnp->id, acpi_device_hid(acpi)); | 327 | && compare_pnp_id(pnp->id, acpi_device_hid(acpi)); |
333 | } | 328 | } |
334 | 329 | ||
diff --git a/drivers/usb/core/usb-acpi.c b/drivers/usb/core/usb-acpi.c index 0ef7d42d8abe..cef4252bb31a 100644 --- a/drivers/usb/core/usb-acpi.c +++ b/drivers/usb/core/usb-acpi.c | |||
@@ -87,7 +87,7 @@ static int usb_acpi_check_port_connect_type(struct usb_device *hdev, | |||
87 | acpi_status status; | 87 | acpi_status status; |
88 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | 88 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; |
89 | union acpi_object *upc; | 89 | union acpi_object *upc; |
90 | struct acpi_pld pld; | 90 | struct acpi_pld_info *pld; |
91 | int ret = 0; | 91 | int ret = 0; |
92 | 92 | ||
93 | /* | 93 | /* |
@@ -111,16 +111,17 @@ static int usb_acpi_check_port_connect_type(struct usb_device *hdev, | |||
111 | } | 111 | } |
112 | 112 | ||
113 | if (upc->package.elements[0].integer.value) | 113 | if (upc->package.elements[0].integer.value) |
114 | if (pld.user_visible) | 114 | if (pld->user_visible) |
115 | usb_set_hub_port_connect_type(hdev, port1, | 115 | usb_set_hub_port_connect_type(hdev, port1, |
116 | USB_PORT_CONNECT_TYPE_HOT_PLUG); | 116 | USB_PORT_CONNECT_TYPE_HOT_PLUG); |
117 | else | 117 | else |
118 | usb_set_hub_port_connect_type(hdev, port1, | 118 | usb_set_hub_port_connect_type(hdev, port1, |
119 | USB_PORT_CONNECT_TYPE_HARD_WIRED); | 119 | USB_PORT_CONNECT_TYPE_HARD_WIRED); |
120 | else if (!pld.user_visible) | 120 | else if (!pld->user_visible) |
121 | usb_set_hub_port_connect_type(hdev, port1, USB_PORT_NOT_USED); | 121 | usb_set_hub_port_connect_type(hdev, port1, USB_PORT_NOT_USED); |
122 | 122 | ||
123 | out: | 123 | out: |
124 | ACPI_FREE(pld); | ||
124 | kfree(upc); | 125 | kfree(upc); |
125 | return ret; | 126 | return ret; |
126 | } | 127 | } |
diff --git a/include/acpi/acbuffer.h b/include/acpi/acbuffer.h new file mode 100644 index 000000000000..a1e45cdd729a --- /dev/null +++ b/include/acpi/acbuffer.h | |||
@@ -0,0 +1,235 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Name: acbuffer.h - Support for buffers returned by ACPI predefined names | ||
4 | * | ||
5 | *****************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2012, 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 | #ifndef __ACBUFFER_H__ | ||
45 | #define __ACBUFFER_H__ | ||
46 | |||
47 | /* | ||
48 | * Contains buffer structures for these predefined names: | ||
49 | * _FDE, _GRT, _GTM, _PLD, _SRT | ||
50 | */ | ||
51 | |||
52 | /* | ||
53 | * Note: C bitfields are not used for this reason: | ||
54 | * | ||
55 | * "Bitfields are great and easy to read, but unfortunately the C language | ||
56 | * does not specify the layout of bitfields in memory, which means they are | ||
57 | * essentially useless for dealing with packed data in on-disk formats or | ||
58 | * binary wire protocols." (Or ACPI tables and buffers.) "If you ask me, | ||
59 | * this decision was a design error in C. Ritchie could have picked an order | ||
60 | * and stuck with it." Norman Ramsey. | ||
61 | * See http://stackoverflow.com/a/1053662/41661 | ||
62 | */ | ||
63 | |||
64 | /* _FDE return value */ | ||
65 | |||
66 | struct acpi_fde_info { | ||
67 | u32 floppy0; | ||
68 | u32 floppy1; | ||
69 | u32 floppy2; | ||
70 | u32 floppy3; | ||
71 | u32 tape; | ||
72 | }; | ||
73 | |||
74 | /* | ||
75 | * _GRT return value | ||
76 | * _SRT input value | ||
77 | */ | ||
78 | struct acpi_grt_info { | ||
79 | u16 year; | ||
80 | u8 month; | ||
81 | u8 day; | ||
82 | u8 hour; | ||
83 | u8 minute; | ||
84 | u8 second; | ||
85 | u8 valid; | ||
86 | u16 milliseconds; | ||
87 | u16 timezone; | ||
88 | u8 daylight; | ||
89 | u8 reserved[3]; | ||
90 | }; | ||
91 | |||
92 | /* _GTM return value */ | ||
93 | |||
94 | struct acpi_gtm_info { | ||
95 | u32 pio_speed0; | ||
96 | u32 dma_speed0; | ||
97 | u32 pio_speed1; | ||
98 | u32 dma_speed1; | ||
99 | u32 flags; | ||
100 | }; | ||
101 | |||
102 | /* | ||
103 | * Formatted _PLD return value. The minimum size is a package containing | ||
104 | * one buffer. | ||
105 | * Revision 1: Buffer is 16 bytes (128 bits) | ||
106 | * Revision 2: Buffer is 20 bytes (160 bits) | ||
107 | * | ||
108 | * Note: This structure is returned from the acpi_decode_pld_buffer | ||
109 | * interface. | ||
110 | */ | ||
111 | struct acpi_pld_info { | ||
112 | u8 revision; | ||
113 | u8 ignore_color; | ||
114 | u32 color; | ||
115 | u16 width; | ||
116 | u16 height; | ||
117 | u8 user_visible; | ||
118 | u8 dock; | ||
119 | u8 lid; | ||
120 | u8 panel; | ||
121 | u8 vertical_position; | ||
122 | u8 horizontal_position; | ||
123 | u8 shape; | ||
124 | u8 group_orientation; | ||
125 | u8 group_token; | ||
126 | u8 group_position; | ||
127 | u8 bay; | ||
128 | u8 ejectable; | ||
129 | u8 ospm_eject_required; | ||
130 | u8 cabinet_number; | ||
131 | u8 card_cage_number; | ||
132 | u8 reference; | ||
133 | u8 rotation; | ||
134 | u8 order; | ||
135 | u8 reserved; | ||
136 | u16 vertical_offset; | ||
137 | u16 horizontal_offset; | ||
138 | }; | ||
139 | |||
140 | /* | ||
141 | * Macros to: | ||
142 | * 1) Convert a _PLD buffer to internal struct acpi_pld_info format - ACPI_PLD_GET* | ||
143 | * (Used by acpi_decode_pld_buffer) | ||
144 | * 2) Construct a _PLD buffer - ACPI_PLD_SET* | ||
145 | * (Intended for BIOS use only) | ||
146 | */ | ||
147 | #define ACPI_PLD_REV1_BUFFER_SIZE 16 /* For Revision 1 of the buffer (From ACPI spec) */ | ||
148 | #define ACPI_PLD_BUFFER_SIZE 20 /* For Revision 2 of the buffer (From ACPI spec) */ | ||
149 | |||
150 | /* First 32-bit dword, bits 0:32 */ | ||
151 | |||
152 | #define ACPI_PLD_GET_REVISION(dword) ACPI_GET_BITS (dword, 0, ACPI_7BIT_MASK) | ||
153 | #define ACPI_PLD_SET_REVISION(dword,value) ACPI_SET_BITS (dword, 0, ACPI_7BIT_MASK, value) /* Offset 0, Len 7 */ | ||
154 | |||
155 | #define ACPI_PLD_GET_IGNORE_COLOR(dword) ACPI_GET_BITS (dword, 7, ACPI_1BIT_MASK) | ||
156 | #define ACPI_PLD_SET_IGNORE_COLOR(dword,value) ACPI_SET_BITS (dword, 7, ACPI_1BIT_MASK, value) /* Offset 7, Len 1 */ | ||
157 | |||
158 | #define ACPI_PLD_GET_COLOR(dword) ACPI_GET_BITS (dword, 8, ACPI_24BIT_MASK) | ||
159 | #define ACPI_PLD_SET_COLOR(dword,value) ACPI_SET_BITS (dword, 8, ACPI_24BIT_MASK, value) /* Offset 8, Len 24 */ | ||
160 | |||
161 | /* Second 32-bit dword, bits 33:63 */ | ||
162 | |||
163 | #define ACPI_PLD_GET_WIDTH(dword) ACPI_GET_BITS (dword, 0, ACPI_16BIT_MASK) | ||
164 | #define ACPI_PLD_SET_WIDTH(dword,value) ACPI_SET_BITS (dword, 0, ACPI_16BIT_MASK, value) /* Offset 32+0=32, Len 16 */ | ||
165 | |||
166 | #define ACPI_PLD_GET_HEIGHT(dword) ACPI_GET_BITS (dword, 16, ACPI_16BIT_MASK) | ||
167 | #define ACPI_PLD_SET_HEIGHT(dword,value) ACPI_SET_BITS (dword, 16, ACPI_16BIT_MASK, value) /* Offset 32+16=48, Len 16 */ | ||
168 | |||
169 | /* Third 32-bit dword, bits 64:95 */ | ||
170 | |||
171 | #define ACPI_PLD_GET_USER_VISIBLE(dword) ACPI_GET_BITS (dword, 0, ACPI_1BIT_MASK) | ||
172 | #define ACPI_PLD_SET_USER_VISIBLE(dword,value) ACPI_SET_BITS (dword, 0, ACPI_1BIT_MASK, value) /* Offset 64+0=64, Len 1 */ | ||
173 | |||
174 | #define ACPI_PLD_GET_DOCK(dword) ACPI_GET_BITS (dword, 1, ACPI_1BIT_MASK) | ||
175 | #define ACPI_PLD_SET_DOCK(dword,value) ACPI_SET_BITS (dword, 1, ACPI_1BIT_MASK, value) /* Offset 64+1=65, Len 1 */ | ||
176 | |||
177 | #define ACPI_PLD_GET_LID(dword) ACPI_GET_BITS (dword, 2, ACPI_1BIT_MASK) | ||
178 | #define ACPI_PLD_SET_LID(dword,value) ACPI_SET_BITS (dword, 2, ACPI_1BIT_MASK, value) /* Offset 64+2=66, Len 1 */ | ||
179 | |||
180 | #define ACPI_PLD_GET_PANEL(dword) ACPI_GET_BITS (dword, 3, ACPI_3BIT_MASK) | ||
181 | #define ACPI_PLD_SET_PANEL(dword,value) ACPI_SET_BITS (dword, 3, ACPI_3BIT_MASK, value) /* Offset 64+3=67, Len 3 */ | ||
182 | |||
183 | #define ACPI_PLD_GET_VERTICAL(dword) ACPI_GET_BITS (dword, 6, ACPI_2BIT_MASK) | ||
184 | #define ACPI_PLD_SET_VERTICAL(dword,value) ACPI_SET_BITS (dword, 6, ACPI_2BIT_MASK, value) /* Offset 64+6=70, Len 2 */ | ||
185 | |||
186 | #define ACPI_PLD_GET_HORIZONTAL(dword) ACPI_GET_BITS (dword, 8, ACPI_2BIT_MASK) | ||
187 | #define ACPI_PLD_SET_HORIZONTAL(dword,value) ACPI_SET_BITS (dword, 8, ACPI_2BIT_MASK, value) /* Offset 64+8=72, Len 2 */ | ||
188 | |||
189 | #define ACPI_PLD_GET_SHAPE(dword) ACPI_GET_BITS (dword, 10, ACPI_4BIT_MASK) | ||
190 | #define ACPI_PLD_SET_SHAPE(dword,value) ACPI_SET_BITS (dword, 10, ACPI_4BIT_MASK, value) /* Offset 64+10=74, Len 4 */ | ||
191 | |||
192 | #define ACPI_PLD_GET_ORIENTATION(dword) ACPI_GET_BITS (dword, 14, ACPI_1BIT_MASK) | ||
193 | #define ACPI_PLD_SET_ORIENTATION(dword,value) ACPI_SET_BITS (dword, 14, ACPI_1BIT_MASK, value) /* Offset 64+14=78, Len 1 */ | ||
194 | |||
195 | #define ACPI_PLD_GET_TOKEN(dword) ACPI_GET_BITS (dword, 15, ACPI_8BIT_MASK) | ||
196 | #define ACPI_PLD_SET_TOKEN(dword,value) ACPI_SET_BITS (dword, 15, ACPI_8BIT_MASK, value) /* Offset 64+15=79, Len 8 */ | ||
197 | |||
198 | #define ACPI_PLD_GET_POSITION(dword) ACPI_GET_BITS (dword, 23, ACPI_8BIT_MASK) | ||
199 | #define ACPI_PLD_SET_POSITION(dword,value) ACPI_SET_BITS (dword, 23, ACPI_8BIT_MASK, value) /* Offset 64+23=87, Len 8 */ | ||
200 | |||
201 | #define ACPI_PLD_GET_BAY(dword) ACPI_GET_BITS (dword, 31, ACPI_1BIT_MASK) | ||
202 | #define ACPI_PLD_SET_BAY(dword,value) ACPI_SET_BITS (dword, 31, ACPI_1BIT_MASK, value) /* Offset 64+31=95, Len 1 */ | ||
203 | |||
204 | /* Fourth 32-bit dword, bits 96:127 */ | ||
205 | |||
206 | #define ACPI_PLD_GET_EJECTABLE(dword) ACPI_GET_BITS (dword, 0, ACPI_1BIT_MASK) | ||
207 | #define ACPI_PLD_SET_EJECTABLE(dword,value) ACPI_SET_BITS (dword, 0, ACPI_1BIT_MASK, value) /* Offset 96+0=96, Len 1 */ | ||
208 | |||
209 | #define ACPI_PLD_GET_OSPM_EJECT(dword) ACPI_GET_BITS (dword, 1, ACPI_1BIT_MASK) | ||
210 | #define ACPI_PLD_SET_OSPM_EJECT(dword,value) ACPI_SET_BITS (dword, 1, ACPI_1BIT_MASK, value) /* Offset 96+1=97, Len 1 */ | ||
211 | |||
212 | #define ACPI_PLD_GET_CABINET(dword) ACPI_GET_BITS (dword, 2, ACPI_8BIT_MASK) | ||
213 | #define ACPI_PLD_SET_CABINET(dword,value) ACPI_SET_BITS (dword, 2, ACPI_8BIT_MASK, value) /* Offset 96+2=98, Len 8 */ | ||
214 | |||
215 | #define ACPI_PLD_GET_CARD_CAGE(dword) ACPI_GET_BITS (dword, 10, ACPI_8BIT_MASK) | ||
216 | #define ACPI_PLD_SET_CARD_CAGE(dword,value) ACPI_SET_BITS (dword, 10, ACPI_8BIT_MASK, value) /* Offset 96+10=106, Len 8 */ | ||
217 | |||
218 | #define ACPI_PLD_GET_REFERENCE(dword) ACPI_GET_BITS (dword, 18, ACPI_1BIT_MASK) | ||
219 | #define ACPI_PLD_SET_REFERENCE(dword,value) ACPI_SET_BITS (dword, 18, ACPI_1BIT_MASK, value) /* Offset 96+18=114, Len 1 */ | ||
220 | |||
221 | #define ACPI_PLD_GET_ROTATION(dword) ACPI_GET_BITS (dword, 19, ACPI_4BIT_MASK) | ||
222 | #define ACPI_PLD_SET_ROTATION(dword,value) ACPI_SET_BITS (dword, 19, ACPI_4BIT_MASK, value) /* Offset 96+19=115, Len 4 */ | ||
223 | |||
224 | #define ACPI_PLD_GET_ORDER(dword) ACPI_GET_BITS (dword, 23, ACPI_5BIT_MASK) | ||
225 | #define ACPI_PLD_SET_ORDER(dword,value) ACPI_SET_BITS (dword, 23, ACPI_5BIT_MASK, value) /* Offset 96+23=119, Len 5 */ | ||
226 | |||
227 | /* Fifth 32-bit dword, bits 128:159 (Revision 2 of _PLD only) */ | ||
228 | |||
229 | #define ACPI_PLD_GET_VERT_OFFSET(dword) ACPI_GET_BITS (dword, 0, ACPI_16BIT_MASK) | ||
230 | #define ACPI_PLD_SET_VERT_OFFSET(dword,value) ACPI_SET_BITS (dword, 0, ACPI_16BIT_MASK, value) /* Offset 128+0=128, Len 16 */ | ||
231 | |||
232 | #define ACPI_PLD_GET_HORIZ_OFFSET(dword) ACPI_GET_BITS (dword, 16, ACPI_16BIT_MASK) | ||
233 | #define ACPI_PLD_SET_HORIZ_OFFSET(dword,value) ACPI_SET_BITS (dword, 16, ACPI_16BIT_MASK, value) /* Offset 128+16=144, Len 16 */ | ||
234 | |||
235 | #endif /* ACBUFFER_H */ | ||
diff --git a/include/acpi/acnames.h b/include/acpi/acnames.h index d988ac54f41e..745dd24e3cb5 100644 --- a/include/acpi/acnames.h +++ b/include/acpi/acnames.h | |||
@@ -63,11 +63,10 @@ | |||
63 | #define METHOD_NAME__PRW "_PRW" | 63 | #define METHOD_NAME__PRW "_PRW" |
64 | #define METHOD_NAME__SRS "_SRS" | 64 | #define METHOD_NAME__SRS "_SRS" |
65 | #define METHOD_NAME__CBA "_CBA" | 65 | #define METHOD_NAME__CBA "_CBA" |
66 | #define METHOD_NAME__PLD "_PLD" | ||
66 | 67 | ||
67 | /* Method names - these methods must appear at the namespace root */ | 68 | /* Method names - these methods must appear at the namespace root */ |
68 | 69 | ||
69 | #define METHOD_PATHNAME__BFS "\\_BFS" | ||
70 | #define METHOD_PATHNAME__GTS "\\_GTS" | ||
71 | #define METHOD_PATHNAME__PTS "\\_PTS" | 70 | #define METHOD_PATHNAME__PTS "\\_PTS" |
72 | #define METHOD_PATHNAME__SST "\\_SI._SST" | 71 | #define METHOD_PATHNAME__SST "\\_SI._SST" |
73 | #define METHOD_PATHNAME__WAK "\\_WAK" | 72 | #define METHOD_PATHNAME__WAK "\\_WAK" |
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index bde976ee068d..0daa0fbd8654 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h | |||
@@ -54,37 +54,8 @@ acpi_status | |||
54 | acpi_evaluate_hotplug_ost(acpi_handle handle, u32 source_event, | 54 | acpi_evaluate_hotplug_ost(acpi_handle handle, u32 source_event, |
55 | u32 status_code, struct acpi_buffer *status_buf); | 55 | u32 status_code, struct acpi_buffer *status_buf); |
56 | 56 | ||
57 | struct acpi_pld { | ||
58 | unsigned int revision:7; /* 0 */ | ||
59 | unsigned int ignore_colour:1; /* 7 */ | ||
60 | unsigned int colour:24; /* 8 */ | ||
61 | unsigned int width:16; /* 32 */ | ||
62 | unsigned int height:16; /* 48 */ | ||
63 | unsigned int user_visible:1; /* 64 */ | ||
64 | unsigned int dock:1; /* 65 */ | ||
65 | unsigned int lid:1; /* 66 */ | ||
66 | unsigned int panel:3; /* 67 */ | ||
67 | unsigned int vertical_pos:2; /* 70 */ | ||
68 | unsigned int horizontal_pos:2; /* 72 */ | ||
69 | unsigned int shape:4; /* 74 */ | ||
70 | unsigned int group_orientation:1; /* 78 */ | ||
71 | unsigned int group_token:8; /* 79 */ | ||
72 | unsigned int group_position:8; /* 87 */ | ||
73 | unsigned int bay:1; /* 95 */ | ||
74 | unsigned int ejectable:1; /* 96 */ | ||
75 | unsigned int ospm_eject_required:1; /* 97 */ | ||
76 | unsigned int cabinet_number:8; /* 98 */ | ||
77 | unsigned int card_cage_number:8; /* 106 */ | ||
78 | unsigned int reference:1; /* 114 */ | ||
79 | unsigned int rotation:4; /* 115 */ | ||
80 | unsigned int order:5; /* 119 */ | ||
81 | unsigned int reserved:4; /* 124 */ | ||
82 | unsigned int vertical_offset:16; /* 128 */ | ||
83 | unsigned int horizontal_offset:16; /* 144 */ | ||
84 | } __attribute__((__packed__)); | ||
85 | |||
86 | acpi_status | 57 | acpi_status |
87 | acpi_get_physical_device_location(acpi_handle handle, struct acpi_pld *pld); | 58 | acpi_get_physical_device_location(acpi_handle handle, struct acpi_pld_info **pld); |
88 | #ifdef CONFIG_ACPI | 59 | #ifdef CONFIG_ACPI |
89 | 60 | ||
90 | #include <linux/proc_fs.h> | 61 | #include <linux/proc_fs.h> |
@@ -208,6 +179,7 @@ struct acpi_device_pnp { | |||
208 | struct list_head ids; /* _HID and _CIDs */ | 179 | struct list_head ids; /* _HID and _CIDs */ |
209 | acpi_device_name device_name; /* Driver-determined */ | 180 | acpi_device_name device_name; /* Driver-determined */ |
210 | acpi_device_class device_class; /* " */ | 181 | acpi_device_class device_class; /* " */ |
182 | union acpi_object *str_obj; /* unicode string for _STR method */ | ||
211 | }; | 183 | }; |
212 | 184 | ||
213 | #define acpi_device_bid(d) ((d)->pnp.bus_id) | 185 | #define acpi_device_bid(d) ((d)->pnp.bus_id) |
@@ -282,8 +254,16 @@ struct acpi_device_wakeup { | |||
282 | int prepare_count; | 254 | int prepare_count; |
283 | }; | 255 | }; |
284 | 256 | ||
285 | /* Device */ | 257 | struct acpi_device_physical_node { |
258 | u8 node_id; | ||
259 | struct list_head node; | ||
260 | struct device *dev; | ||
261 | }; | ||
262 | |||
263 | /* set maximum of physical nodes to 32 for expansibility */ | ||
264 | #define ACPI_MAX_PHYSICAL_NODE 32 | ||
286 | 265 | ||
266 | /* Device */ | ||
287 | struct acpi_device { | 267 | struct acpi_device { |
288 | int device_type; | 268 | int device_type; |
289 | acpi_handle handle; /* no handle for fixed hardware */ | 269 | acpi_handle handle; /* no handle for fixed hardware */ |
@@ -304,6 +284,10 @@ struct acpi_device { | |||
304 | struct device dev; | 284 | struct device dev; |
305 | struct acpi_bus_ops bus_ops; /* workaround for different code path for hotplug */ | 285 | struct acpi_bus_ops bus_ops; /* workaround for different code path for hotplug */ |
306 | enum acpi_bus_removal_type removal_type; /* indicate for different removal type */ | 286 | enum acpi_bus_removal_type removal_type; /* indicate for different removal type */ |
287 | u8 physical_node_count; | ||
288 | struct list_head physical_node_list; | ||
289 | struct mutex physical_node_lock; | ||
290 | DECLARE_BITMAP(physical_node_id_bitmap, ACPI_MAX_PHYSICAL_NODE); | ||
307 | }; | 291 | }; |
308 | 292 | ||
309 | static inline void *acpi_driver_data(struct acpi_device *d) | 293 | static inline void *acpi_driver_data(struct acpi_device *d) |
@@ -381,6 +365,19 @@ int acpi_match_device_ids(struct acpi_device *device, | |||
381 | int acpi_create_dir(struct acpi_device *); | 365 | int acpi_create_dir(struct acpi_device *); |
382 | void acpi_remove_dir(struct acpi_device *); | 366 | void acpi_remove_dir(struct acpi_device *); |
383 | 367 | ||
368 | |||
369 | /** | ||
370 | * module_acpi_driver(acpi_driver) - Helper macro for registering an ACPI driver | ||
371 | * @__acpi_driver: acpi_driver struct | ||
372 | * | ||
373 | * Helper macro for ACPI drivers which do not do anything special in module | ||
374 | * init/exit. This eliminates a lot of boilerplate. Each module may only | ||
375 | * use this macro once, and calling it replaces module_init() and module_exit() | ||
376 | */ | ||
377 | #define module_acpi_driver(__acpi_driver) \ | ||
378 | module_driver(__acpi_driver, acpi_bus_register_driver, \ | ||
379 | acpi_bus_unregister_driver) | ||
380 | |||
384 | /* | 381 | /* |
385 | * Bind physical devices with ACPI devices | 382 | * Bind physical devices with ACPI devices |
386 | */ | 383 | */ |
@@ -394,7 +391,6 @@ struct acpi_bus_type { | |||
394 | }; | 391 | }; |
395 | int register_acpi_bus_type(struct acpi_bus_type *); | 392 | int register_acpi_bus_type(struct acpi_bus_type *); |
396 | int unregister_acpi_bus_type(struct acpi_bus_type *); | 393 | int unregister_acpi_bus_type(struct acpi_bus_type *); |
397 | struct device *acpi_get_physical_device(acpi_handle); | ||
398 | 394 | ||
399 | struct acpi_pci_root { | 395 | struct acpi_pci_root { |
400 | struct list_head node; | 396 | struct list_head node; |
diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h index 51405d32ac64..8b891dbead66 100644 --- a/include/acpi/acpixf.h +++ b/include/acpi/acpixf.h | |||
@@ -47,11 +47,12 @@ | |||
47 | 47 | ||
48 | /* Current ACPICA subsystem version in YYYYMMDD format */ | 48 | /* Current ACPICA subsystem version in YYYYMMDD format */ |
49 | 49 | ||
50 | #define ACPI_CA_VERSION 0x20120711 | 50 | #define ACPI_CA_VERSION 0x20120913 |
51 | 51 | ||
52 | #include <acpi/acconfig.h> | 52 | #include <acpi/acconfig.h> |
53 | #include <acpi/actypes.h> | 53 | #include <acpi/actypes.h> |
54 | #include <acpi/actbl.h> | 54 | #include <acpi/actbl.h> |
55 | #include <acpi/acbuffer.h> | ||
55 | 56 | ||
56 | extern u8 acpi_gbl_permanent_mmap; | 57 | extern u8 acpi_gbl_permanent_mmap; |
57 | 58 | ||
@@ -144,6 +145,10 @@ acpi_check_address_range(acpi_adr_space_type space_id, | |||
144 | acpi_physical_address address, | 145 | acpi_physical_address address, |
145 | acpi_size length, u8 warn); | 146 | acpi_size length, u8 warn); |
146 | 147 | ||
148 | acpi_status | ||
149 | acpi_decode_pld_buffer(u8 *in_buffer, | ||
150 | acpi_size length, struct acpi_pld_info **return_buffer); | ||
151 | |||
147 | /* | 152 | /* |
148 | * ACPI Memory management | 153 | * ACPI Memory management |
149 | */ | 154 | */ |
diff --git a/include/acpi/actbl.h b/include/acpi/actbl.h index 59a73e1b2845..4f94b1d812d5 100644 --- a/include/acpi/actbl.h +++ b/include/acpi/actbl.h | |||
@@ -79,9 +79,15 @@ | |||
79 | #pragma pack(1) | 79 | #pragma pack(1) |
80 | 80 | ||
81 | /* | 81 | /* |
82 | * Note about bitfields: The u8 type is used for bitfields in ACPI tables. | 82 | * Note: C bitfields are not used for this reason: |
83 | * This is the only type that is even remotely portable. Anything else is not | 83 | * |
84 | * portable, so do not use any other bitfield types. | 84 | * "Bitfields are great and easy to read, but unfortunately the C language |
85 | * does not specify the layout of bitfields in memory, which means they are | ||
86 | * essentially useless for dealing with packed data in on-disk formats or | ||
87 | * binary wire protocols." (Or ACPI tables and buffers.) "If you ask me, | ||
88 | * this decision was a design error in C. Ritchie could have picked an order | ||
89 | * and stuck with it." Norman Ramsey. | ||
90 | * See http://stackoverflow.com/a/1053662/41661 | ||
85 | */ | 91 | */ |
86 | 92 | ||
87 | /******************************************************************************* | 93 | /******************************************************************************* |
@@ -94,7 +100,7 @@ | |||
94 | struct acpi_table_header { | 100 | struct acpi_table_header { |
95 | char signature[ACPI_NAME_SIZE]; /* ASCII table signature */ | 101 | char signature[ACPI_NAME_SIZE]; /* ASCII table signature */ |
96 | u32 length; /* Length of table in bytes, including this header */ | 102 | u32 length; /* Length of table in bytes, including this header */ |
97 | u8 revision; /* ACPI Specification minor version # */ | 103 | u8 revision; /* ACPI Specification minor version number */ |
98 | u8 checksum; /* To make sum of entire table == 0 */ | 104 | u8 checksum; /* To make sum of entire table == 0 */ |
99 | char oem_id[ACPI_OEM_ID_SIZE]; /* ASCII OEM identification */ | 105 | char oem_id[ACPI_OEM_ID_SIZE]; /* ASCII OEM identification */ |
100 | char oem_table_id[ACPI_OEM_TABLE_ID_SIZE]; /* ASCII OEM table identification */ | 106 | char oem_table_id[ACPI_OEM_TABLE_ID_SIZE]; /* ASCII OEM table identification */ |
@@ -108,7 +114,7 @@ struct acpi_table_header { | |||
108 | * GAS - Generic Address Structure (ACPI 2.0+) | 114 | * GAS - Generic Address Structure (ACPI 2.0+) |
109 | * | 115 | * |
110 | * Note: Since this structure is used in the ACPI tables, it is byte aligned. | 116 | * Note: Since this structure is used in the ACPI tables, it is byte aligned. |
111 | * If misaliged access is not supported by the hardware, accesses to the | 117 | * If misaligned access is not supported by the hardware, accesses to the |
112 | * 64-bit Address field must be performed with care. | 118 | * 64-bit Address field must be performed with care. |
113 | * | 119 | * |
114 | ******************************************************************************/ | 120 | ******************************************************************************/ |
@@ -210,18 +216,18 @@ struct acpi_table_fadt { | |||
210 | u8 preferred_profile; /* Conveys preferred power management profile to OSPM. */ | 216 | u8 preferred_profile; /* Conveys preferred power management profile to OSPM. */ |
211 | u16 sci_interrupt; /* System vector of SCI interrupt */ | 217 | u16 sci_interrupt; /* System vector of SCI interrupt */ |
212 | u32 smi_command; /* 32-bit Port address of SMI command port */ | 218 | u32 smi_command; /* 32-bit Port address of SMI command port */ |
213 | u8 acpi_enable; /* Value to write to smi_cmd to enable ACPI */ | 219 | u8 acpi_enable; /* Value to write to SMI_CMD to enable ACPI */ |
214 | u8 acpi_disable; /* Value to write to smi_cmd to disable ACPI */ | 220 | u8 acpi_disable; /* Value to write to SMI_CMD to disable ACPI */ |
215 | u8 s4_bios_request; /* Value to write to SMI CMD to enter S4BIOS state */ | 221 | u8 s4_bios_request; /* Value to write to SMI_CMD to enter S4BIOS state */ |
216 | u8 pstate_control; /* Processor performance state control */ | 222 | u8 pstate_control; /* Processor performance state control */ |
217 | u32 pm1a_event_block; /* 32-bit Port address of Power Mgt 1a Event Reg Blk */ | 223 | u32 pm1a_event_block; /* 32-bit port address of Power Mgt 1a Event Reg Blk */ |
218 | u32 pm1b_event_block; /* 32-bit Port address of Power Mgt 1b Event Reg Blk */ | 224 | u32 pm1b_event_block; /* 32-bit port address of Power Mgt 1b Event Reg Blk */ |
219 | u32 pm1a_control_block; /* 32-bit Port address of Power Mgt 1a Control Reg Blk */ | 225 | u32 pm1a_control_block; /* 32-bit port address of Power Mgt 1a Control Reg Blk */ |
220 | u32 pm1b_control_block; /* 32-bit Port address of Power Mgt 1b Control Reg Blk */ | 226 | u32 pm1b_control_block; /* 32-bit port address of Power Mgt 1b Control Reg Blk */ |
221 | u32 pm2_control_block; /* 32-bit Port address of Power Mgt 2 Control Reg Blk */ | 227 | u32 pm2_control_block; /* 32-bit port address of Power Mgt 2 Control Reg Blk */ |
222 | u32 pm_timer_block; /* 32-bit Port address of Power Mgt Timer Ctrl Reg Blk */ | 228 | u32 pm_timer_block; /* 32-bit port address of Power Mgt Timer Ctrl Reg Blk */ |
223 | u32 gpe0_block; /* 32-bit Port address of General Purpose Event 0 Reg Blk */ | 229 | u32 gpe0_block; /* 32-bit port address of General Purpose Event 0 Reg Blk */ |
224 | u32 gpe1_block; /* 32-bit Port address of General Purpose Event 1 Reg Blk */ | 230 | u32 gpe1_block; /* 32-bit port address of General Purpose Event 1 Reg Blk */ |
225 | u8 pm1_event_length; /* Byte Length of ports at pm1x_event_block */ | 231 | u8 pm1_event_length; /* Byte Length of ports at pm1x_event_block */ |
226 | u8 pm1_control_length; /* Byte Length of ports at pm1x_control_block */ | 232 | u8 pm1_control_length; /* Byte Length of ports at pm1x_control_block */ |
227 | u8 pm2_control_length; /* Byte Length of ports at pm2_control_block */ | 233 | u8 pm2_control_length; /* Byte Length of ports at pm2_control_block */ |
@@ -229,12 +235,12 @@ struct acpi_table_fadt { | |||
229 | u8 gpe0_block_length; /* Byte Length of ports at gpe0_block */ | 235 | u8 gpe0_block_length; /* Byte Length of ports at gpe0_block */ |
230 | u8 gpe1_block_length; /* Byte Length of ports at gpe1_block */ | 236 | u8 gpe1_block_length; /* Byte Length of ports at gpe1_block */ |
231 | u8 gpe1_base; /* Offset in GPE number space where GPE1 events start */ | 237 | u8 gpe1_base; /* Offset in GPE number space where GPE1 events start */ |
232 | u8 cst_control; /* Support for the _CST object and C States change notification */ | 238 | u8 cst_control; /* Support for the _CST object and C-States change notification */ |
233 | u16 c2_latency; /* Worst case HW latency to enter/exit C2 state */ | 239 | u16 c2_latency; /* Worst case HW latency to enter/exit C2 state */ |
234 | u16 c3_latency; /* Worst case HW latency to enter/exit C3 state */ | 240 | u16 c3_latency; /* Worst case HW latency to enter/exit C3 state */ |
235 | u16 flush_size; /* Processor's memory cache line width, in bytes */ | 241 | u16 flush_size; /* Processor memory cache line width, in bytes */ |
236 | u16 flush_stride; /* Number of flush strides that need to be read */ | 242 | u16 flush_stride; /* Number of flush strides that need to be read */ |
237 | u8 duty_offset; /* Processor duty cycle index in processor's P_CNT reg */ | 243 | u8 duty_offset; /* Processor duty cycle index in processor P_CNT reg */ |
238 | u8 duty_width; /* Processor duty cycle value bit width in P_CNT register */ | 244 | u8 duty_width; /* Processor duty cycle value bit width in P_CNT register */ |
239 | u8 day_alarm; /* Index to day-of-month alarm in RTC CMOS RAM */ | 245 | u8 day_alarm; /* Index to day-of-month alarm in RTC CMOS RAM */ |
240 | u8 month_alarm; /* Index to month-of-year alarm in RTC CMOS RAM */ | 246 | u8 month_alarm; /* Index to month-of-year alarm in RTC CMOS RAM */ |
@@ -255,11 +261,11 @@ struct acpi_table_fadt { | |||
255 | struct acpi_generic_address xpm_timer_block; /* 64-bit Extended Power Mgt Timer Ctrl Reg Blk address */ | 261 | struct acpi_generic_address xpm_timer_block; /* 64-bit Extended Power Mgt Timer Ctrl Reg Blk address */ |
256 | struct acpi_generic_address xgpe0_block; /* 64-bit Extended General Purpose Event 0 Reg Blk address */ | 262 | struct acpi_generic_address xgpe0_block; /* 64-bit Extended General Purpose Event 0 Reg Blk address */ |
257 | struct acpi_generic_address xgpe1_block; /* 64-bit Extended General Purpose Event 1 Reg Blk address */ | 263 | struct acpi_generic_address xgpe1_block; /* 64-bit Extended General Purpose Event 1 Reg Blk address */ |
258 | struct acpi_generic_address sleep_control; /* 64-bit Sleep Control register */ | 264 | struct acpi_generic_address sleep_control; /* 64-bit Sleep Control register (ACPI 5.0) */ |
259 | struct acpi_generic_address sleep_status; /* 64-bit Sleep Status register */ | 265 | struct acpi_generic_address sleep_status; /* 64-bit Sleep Status register (ACPI 5.0) */ |
260 | }; | 266 | }; |
261 | 267 | ||
262 | /* Masks for FADT Boot Architecture Flags (boot_flags) */ | 268 | /* Masks for FADT Boot Architecture Flags (boot_flags) [Vx]=Introduced in this FADT revision */ |
263 | 269 | ||
264 | #define ACPI_FADT_LEGACY_DEVICES (1) /* 00: [V2] System has LPC or ISA bus devices */ | 270 | #define ACPI_FADT_LEGACY_DEVICES (1) /* 00: [V2] System has LPC or ISA bus devices */ |
265 | #define ACPI_FADT_8042 (1<<1) /* 01: [V3] System has an 8042 controller on port 60/64 */ | 271 | #define ACPI_FADT_8042 (1<<1) /* 01: [V3] System has an 8042 controller on port 60/64 */ |
@@ -272,13 +278,13 @@ struct acpi_table_fadt { | |||
272 | 278 | ||
273 | /* Masks for FADT flags */ | 279 | /* Masks for FADT flags */ |
274 | 280 | ||
275 | #define ACPI_FADT_WBINVD (1) /* 00: [V1] The wbinvd instruction works properly */ | 281 | #define ACPI_FADT_WBINVD (1) /* 00: [V1] The WBINVD instruction works properly */ |
276 | #define ACPI_FADT_WBINVD_FLUSH (1<<1) /* 01: [V1] wbinvd flushes but does not invalidate caches */ | 282 | #define ACPI_FADT_WBINVD_FLUSH (1<<1) /* 01: [V1] WBINVD flushes but does not invalidate caches */ |
277 | #define ACPI_FADT_C1_SUPPORTED (1<<2) /* 02: [V1] All processors support C1 state */ | 283 | #define ACPI_FADT_C1_SUPPORTED (1<<2) /* 02: [V1] All processors support C1 state */ |
278 | #define ACPI_FADT_C2_MP_SUPPORTED (1<<3) /* 03: [V1] C2 state works on MP system */ | 284 | #define ACPI_FADT_C2_MP_SUPPORTED (1<<3) /* 03: [V1] C2 state works on MP system */ |
279 | #define ACPI_FADT_POWER_BUTTON (1<<4) /* 04: [V1] Power button is handled as a control method device */ | 285 | #define ACPI_FADT_POWER_BUTTON (1<<4) /* 04: [V1] Power button is handled as a control method device */ |
280 | #define ACPI_FADT_SLEEP_BUTTON (1<<5) /* 05: [V1] Sleep button is handled as a control method device */ | 286 | #define ACPI_FADT_SLEEP_BUTTON (1<<5) /* 05: [V1] Sleep button is handled as a control method device */ |
281 | #define ACPI_FADT_FIXED_RTC (1<<6) /* 06: [V1] RTC wakeup status not in fixed register space */ | 287 | #define ACPI_FADT_FIXED_RTC (1<<6) /* 06: [V1] RTC wakeup status is not in fixed register space */ |
282 | #define ACPI_FADT_S4_RTC_WAKE (1<<7) /* 07: [V1] RTC alarm can wake system from S4 */ | 288 | #define ACPI_FADT_S4_RTC_WAKE (1<<7) /* 07: [V1] RTC alarm can wake system from S4 */ |
283 | #define ACPI_FADT_32BIT_TIMER (1<<8) /* 08: [V1] ACPI timer width is 32-bit (0=24-bit) */ | 289 | #define ACPI_FADT_32BIT_TIMER (1<<8) /* 08: [V1] ACPI timer width is 32-bit (0=24-bit) */ |
284 | #define ACPI_FADT_DOCKING_SUPPORTED (1<<9) /* 09: [V1] Docking supported */ | 290 | #define ACPI_FADT_DOCKING_SUPPORTED (1<<9) /* 09: [V1] Docking supported */ |
@@ -297,7 +303,7 @@ struct acpi_table_fadt { | |||
297 | 303 | ||
298 | /* Values for preferred_profile (Preferred Power Management Profiles) */ | 304 | /* Values for preferred_profile (Preferred Power Management Profiles) */ |
299 | 305 | ||
300 | enum acpi_prefered_pm_profiles { | 306 | enum acpi_preferred_pm_profiles { |
301 | PM_UNSPECIFIED = 0, | 307 | PM_UNSPECIFIED = 0, |
302 | PM_DESKTOP = 1, | 308 | PM_DESKTOP = 1, |
303 | PM_MOBILE = 2, | 309 | PM_MOBILE = 2, |
@@ -335,7 +341,7 @@ union acpi_name_union { | |||
335 | struct acpi_table_desc { | 341 | struct acpi_table_desc { |
336 | acpi_physical_address address; | 342 | acpi_physical_address address; |
337 | struct acpi_table_header *pointer; | 343 | struct acpi_table_header *pointer; |
338 | u32 length; /* Length fixed at 32 bits */ | 344 | u32 length; /* Length fixed at 32 bits (fixed in table header) */ |
339 | union acpi_name_union signature; | 345 | union acpi_name_union signature; |
340 | acpi_owner_id owner_id; | 346 | acpi_owner_id owner_id; |
341 | u8 flags; | 347 | u8 flags; |
diff --git a/include/acpi/actbl1.h b/include/acpi/actbl1.h index 300d14e7c5d5..280fc45b59dd 100644 --- a/include/acpi/actbl1.h +++ b/include/acpi/actbl1.h | |||
@@ -79,9 +79,15 @@ | |||
79 | #pragma pack(1) | 79 | #pragma pack(1) |
80 | 80 | ||
81 | /* | 81 | /* |
82 | * Note about bitfields: The u8 type is used for bitfields in ACPI tables. | 82 | * Note: C bitfields are not used for this reason: |
83 | * This is the only type that is even remotely portable. Anything else is not | 83 | * |
84 | * portable, so do not use any other bitfield types. | 84 | * "Bitfields are great and easy to read, but unfortunately the C language |
85 | * does not specify the layout of bitfields in memory, which means they are | ||
86 | * essentially useless for dealing with packed data in on-disk formats or | ||
87 | * binary wire protocols." (Or ACPI tables and buffers.) "If you ask me, | ||
88 | * this decision was a design error in C. Ritchie could have picked an order | ||
89 | * and stuck with it." Norman Ramsey. | ||
90 | * See http://stackoverflow.com/a/1053662/41661 | ||
85 | */ | 91 | */ |
86 | 92 | ||
87 | /******************************************************************************* | 93 | /******************************************************************************* |
@@ -489,7 +495,9 @@ enum acpi_hest_notify_types { | |||
489 | ACPI_HEST_NOTIFY_LOCAL = 2, | 495 | ACPI_HEST_NOTIFY_LOCAL = 2, |
490 | ACPI_HEST_NOTIFY_SCI = 3, | 496 | ACPI_HEST_NOTIFY_SCI = 3, |
491 | ACPI_HEST_NOTIFY_NMI = 4, | 497 | ACPI_HEST_NOTIFY_NMI = 4, |
492 | ACPI_HEST_NOTIFY_RESERVED = 5 /* 5 and greater are reserved */ | 498 | ACPI_HEST_NOTIFY_CMCI = 5, /* ACPI 5.0 */ |
499 | ACPI_HEST_NOTIFY_MCE = 6, /* ACPI 5.0 */ | ||
500 | ACPI_HEST_NOTIFY_RESERVED = 7 /* 7 and greater are reserved */ | ||
493 | }; | 501 | }; |
494 | 502 | ||
495 | /* Values for config_write_enable bitfield above */ | 503 | /* Values for config_write_enable bitfield above */ |
diff --git a/include/acpi/actbl2.h b/include/acpi/actbl2.h index d9ceb3d31629..1b2b356486d1 100644 --- a/include/acpi/actbl2.h +++ b/include/acpi/actbl2.h | |||
@@ -63,6 +63,8 @@ | |||
63 | */ | 63 | */ |
64 | #define ACPI_SIG_ASF "ASF!" /* Alert Standard Format table */ | 64 | #define ACPI_SIG_ASF "ASF!" /* Alert Standard Format table */ |
65 | #define ACPI_SIG_BOOT "BOOT" /* Simple Boot Flag Table */ | 65 | #define ACPI_SIG_BOOT "BOOT" /* Simple Boot Flag Table */ |
66 | #define ACPI_SIG_CSRT "CSRT" /* Core System Resource Table */ | ||
67 | #define ACPI_SIG_DBG2 "DBG2" /* Debug Port table type 2 */ | ||
66 | #define ACPI_SIG_DBGP "DBGP" /* Debug Port table */ | 68 | #define ACPI_SIG_DBGP "DBGP" /* Debug Port table */ |
67 | #define ACPI_SIG_DMAR "DMAR" /* DMA Remapping table */ | 69 | #define ACPI_SIG_DMAR "DMAR" /* DMA Remapping table */ |
68 | #define ACPI_SIG_HPET "HPET" /* High Precision Event Timer table */ | 70 | #define ACPI_SIG_HPET "HPET" /* High Precision Event Timer table */ |
@@ -96,9 +98,15 @@ | |||
96 | #pragma pack(1) | 98 | #pragma pack(1) |
97 | 99 | ||
98 | /* | 100 | /* |
99 | * Note about bitfields: The u8 type is used for bitfields in ACPI tables. | 101 | * Note: C bitfields are not used for this reason: |
100 | * This is the only type that is even remotely portable. Anything else is not | 102 | * |
101 | * portable, so do not use any other bitfield types. | 103 | * "Bitfields are great and easy to read, but unfortunately the C language |
104 | * does not specify the layout of bitfields in memory, which means they are | ||
105 | * essentially useless for dealing with packed data in on-disk formats or | ||
106 | * binary wire protocols." (Or ACPI tables and buffers.) "If you ask me, | ||
107 | * this decision was a design error in C. Ritchie could have picked an order | ||
108 | * and stuck with it." Norman Ramsey. | ||
109 | * See http://stackoverflow.com/a/1053662/41661 | ||
102 | */ | 110 | */ |
103 | 111 | ||
104 | /******************************************************************************* | 112 | /******************************************************************************* |
@@ -232,6 +240,115 @@ struct acpi_table_boot { | |||
232 | 240 | ||
233 | /******************************************************************************* | 241 | /******************************************************************************* |
234 | * | 242 | * |
243 | * CSRT - Core System Resource Table | ||
244 | * Version 0 | ||
245 | * | ||
246 | * Conforms to the "Core System Resource Table (CSRT)", November 14, 2011 | ||
247 | * | ||
248 | ******************************************************************************/ | ||
249 | |||
250 | struct acpi_table_csrt { | ||
251 | struct acpi_table_header header; /* Common ACPI table header */ | ||
252 | }; | ||
253 | |||
254 | /* Resource Group subtable */ | ||
255 | |||
256 | struct acpi_csrt_group { | ||
257 | u32 length; | ||
258 | u32 vendor_id; | ||
259 | u32 subvendor_id; | ||
260 | u16 device_id; | ||
261 | u16 subdevice_id; | ||
262 | u16 revision; | ||
263 | u16 reserved; | ||
264 | u32 info_length; | ||
265 | |||
266 | /* Shared data (length = info_length) immediately follows */ | ||
267 | }; | ||
268 | |||
269 | /* Resource Descriptor subtable */ | ||
270 | |||
271 | struct acpi_csrt_descriptor { | ||
272 | u32 length; | ||
273 | u16 type; | ||
274 | u16 subtype; | ||
275 | u32 uid; | ||
276 | |||
277 | /* Resource-specific information immediately follows */ | ||
278 | }; | ||
279 | |||
280 | /* Resource Types */ | ||
281 | |||
282 | #define ACPI_CSRT_TYPE_INTERRUPT 0x0001 | ||
283 | #define ACPI_CSRT_TYPE_TIMER 0x0002 | ||
284 | #define ACPI_CSRT_TYPE_DMA 0x0003 | ||
285 | |||
286 | /* Resource Subtypes */ | ||
287 | |||
288 | #define ACPI_CSRT_XRUPT_LINE 0x0000 | ||
289 | #define ACPI_CSRT_XRUPT_CONTROLLER 0x0001 | ||
290 | #define ACPI_CSRT_TIMER 0x0000 | ||
291 | #define ACPI_CSRT_DMA_CHANNEL 0x0000 | ||
292 | #define ACPI_CSRT_DMA_CONTROLLER 0x0001 | ||
293 | |||
294 | /******************************************************************************* | ||
295 | * | ||
296 | * DBG2 - Debug Port Table 2 | ||
297 | * Version 0 (Both main table and subtables) | ||
298 | * | ||
299 | * Conforms to "Microsoft Debug Port Table 2 (DBG2)", May 22 2012. | ||
300 | * | ||
301 | ******************************************************************************/ | ||
302 | |||
303 | struct acpi_table_dbg2 { | ||
304 | struct acpi_table_header header; /* Common ACPI table header */ | ||
305 | u32 info_offset; | ||
306 | u32 info_count; | ||
307 | }; | ||
308 | |||
309 | /* Debug Device Information Subtable */ | ||
310 | |||
311 | struct acpi_dbg2_device { | ||
312 | u8 revision; | ||
313 | u16 length; | ||
314 | u8 register_count; /* Number of base_address registers */ | ||
315 | u16 namepath_length; | ||
316 | u16 namepath_offset; | ||
317 | u16 oem_data_length; | ||
318 | u16 oem_data_offset; | ||
319 | u16 port_type; | ||
320 | u16 port_subtype; | ||
321 | u16 reserved; | ||
322 | u16 base_address_offset; | ||
323 | u16 address_size_offset; | ||
324 | /* | ||
325 | * Data that follows: | ||
326 | * base_address (required) - Each in 12-byte Generic Address Structure format. | ||
327 | * address_size (required) - Array of u32 sizes corresponding to each base_address register. | ||
328 | * Namepath (required) - Null terminated string. Single dot if not supported. | ||
329 | * oem_data (optional) - Length is oem_data_length. | ||
330 | */ | ||
331 | }; | ||
332 | |||
333 | /* Types for port_type field above */ | ||
334 | |||
335 | #define ACPI_DBG2_SERIAL_PORT 0x8000 | ||
336 | #define ACPI_DBG2_1394_PORT 0x8001 | ||
337 | #define ACPI_DBG2_USB_PORT 0x8002 | ||
338 | #define ACPI_DBG2_NET_PORT 0x8003 | ||
339 | |||
340 | /* Subtypes for port_subtype field above */ | ||
341 | |||
342 | #define ACPI_DBG2_16550_COMPATIBLE 0x0000 | ||
343 | #define ACPI_DBG2_16550_SUBSET 0x0001 | ||
344 | |||
345 | #define ACPI_DBG2_1394_STANDARD 0x0000 | ||
346 | |||
347 | #define ACPI_DBG2_USB_XHCI 0x0000 | ||
348 | #define ACPI_DBG2_USB_EHCI 0x0001 | ||
349 | |||
350 | /******************************************************************************* | ||
351 | * | ||
235 | * DBGP - Debug Port table | 352 | * DBGP - Debug Port table |
236 | * Version 1 | 353 | * Version 1 |
237 | * | 354 | * |
diff --git a/include/acpi/actbl3.h b/include/acpi/actbl3.h index f65a0ed869eb..8c61b5fe42a4 100644 --- a/include/acpi/actbl3.h +++ b/include/acpi/actbl3.h | |||
@@ -75,7 +75,6 @@ | |||
75 | /* Reserved table signatures */ | 75 | /* Reserved table signatures */ |
76 | 76 | ||
77 | #define ACPI_SIG_CSRT "CSRT" /* Core System Resources Table */ | 77 | #define ACPI_SIG_CSRT "CSRT" /* Core System Resources Table */ |
78 | #define ACPI_SIG_DBG2 "DBG2" /* Debug Port table 2 */ | ||
79 | #define ACPI_SIG_MATR "MATR" /* Memory Address Translation Table */ | 78 | #define ACPI_SIG_MATR "MATR" /* Memory Address Translation Table */ |
80 | #define ACPI_SIG_MSDM "MSDM" /* Microsoft Data Management Table */ | 79 | #define ACPI_SIG_MSDM "MSDM" /* Microsoft Data Management Table */ |
81 | #define ACPI_SIG_WPBT "WPBT" /* Windows Platform Binary Table */ | 80 | #define ACPI_SIG_WPBT "WPBT" /* Windows Platform Binary Table */ |
@@ -87,9 +86,15 @@ | |||
87 | #pragma pack(1) | 86 | #pragma pack(1) |
88 | 87 | ||
89 | /* | 88 | /* |
90 | * Note about bitfields: The u8 type is used for bitfields in ACPI tables. | 89 | * Note: C bitfields are not used for this reason: |
91 | * This is the only type that is even remotely portable. Anything else is not | 90 | * |
92 | * portable, so do not use any other bitfield types. | 91 | * "Bitfields are great and easy to read, but unfortunately the C language |
92 | * does not specify the layout of bitfields in memory, which means they are | ||
93 | * essentially useless for dealing with packed data in on-disk formats or | ||
94 | * binary wire protocols." (Or ACPI tables and buffers.) "If you ask me, | ||
95 | * this decision was a design error in C. Ritchie could have picked an order | ||
96 | * and stuck with it." Norman Ramsey. | ||
97 | * See http://stackoverflow.com/a/1053662/41661 | ||
93 | */ | 98 | */ |
94 | 99 | ||
95 | /******************************************************************************* | 100 | /******************************************************************************* |
diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h index 3d00bd5bd7e3..a85bae968262 100644 --- a/include/acpi/actypes.h +++ b/include/acpi/actypes.h | |||
@@ -519,13 +519,6 @@ typedef u64 acpi_integer; | |||
519 | #define ACPI_SLEEP_TYPE_INVALID 0xFF | 519 | #define ACPI_SLEEP_TYPE_INVALID 0xFF |
520 | 520 | ||
521 | /* | 521 | /* |
522 | * Sleep/Wake flags | ||
523 | */ | ||
524 | #define ACPI_NO_OPTIONAL_METHODS 0x00 /* Do not execute any optional methods */ | ||
525 | #define ACPI_EXECUTE_GTS 0x01 /* For enter sleep interface */ | ||
526 | #define ACPI_EXECUTE_BFS 0x02 /* For leave sleep prep interface */ | ||
527 | |||
528 | /* | ||
529 | * Standard notify values | 522 | * Standard notify values |
530 | */ | 523 | */ |
531 | #define ACPI_NOTIFY_BUS_CHECK (u8) 0x00 | 524 | #define ACPI_NOTIFY_BUS_CHECK (u8) 0x00 |
diff --git a/tools/power/acpi/Makefile b/tools/power/acpi/Makefile new file mode 100644 index 000000000000..6b9cf7a987c7 --- /dev/null +++ b/tools/power/acpi/Makefile | |||
@@ -0,0 +1,18 @@ | |||
1 | PROG= acpidump | ||
2 | SRCS= acpidump.c | ||
3 | KERNEL_INCLUDE := ../../../include | ||
4 | CFLAGS += -Wall -Wstrict-prototypes -Wdeclaration-after-statement -Os -s -D_LINUX -DDEFINE_ALTERNATE_TYPES -I$(KERNEL_INCLUDE) | ||
5 | |||
6 | all: acpidump | ||
7 | $(PROG) : $(SRCS) | ||
8 | $(CC) $(CFLAGS) $(SRCS) -o $(PROG) | ||
9 | |||
10 | CLEANFILES= $(PROG) | ||
11 | |||
12 | clean : | ||
13 | rm -f $(CLEANFILES) $(patsubst %.c,%.o, $(SRCS)) *~ | ||
14 | |||
15 | install : | ||
16 | install acpidump /usr/bin/acpidump | ||
17 | install acpidump.8 /usr/share/man/man8 | ||
18 | |||
diff --git a/tools/power/acpi/acpidump.8 b/tools/power/acpi/acpidump.8 new file mode 100644 index 000000000000..adfa99166e5e --- /dev/null +++ b/tools/power/acpi/acpidump.8 | |||
@@ -0,0 +1,59 @@ | |||
1 | .TH ACPIDUMP 8 | ||
2 | .SH NAME | ||
3 | acpidump \- Dump system's ACPI tables to an ASCII file. | ||
4 | .SH SYNOPSIS | ||
5 | .ft B | ||
6 | .B acpidump > acpidump.out | ||
7 | .SH DESCRIPTION | ||
8 | \fBacpidump \fP dumps the systems ACPI tables to an ASCII file | ||
9 | appropriate for attaching to a bug report. | ||
10 | |||
11 | Subsequently, they can be processed by utilities in the ACPICA package. | ||
12 | .SS Options | ||
13 | no options worth worrying about. | ||
14 | .PP | ||
15 | .SH EXAMPLE | ||
16 | |||
17 | .nf | ||
18 | # acpidump > acpidump.out | ||
19 | |||
20 | $ acpixtract -a acpidump.out | ||
21 | Acpi table [DSDT] - 15974 bytes written to DSDT.dat | ||
22 | Acpi table [FACS] - 64 bytes written to FACS.dat | ||
23 | Acpi table [FACP] - 116 bytes written to FACP.dat | ||
24 | Acpi table [APIC] - 120 bytes written to APIC.dat | ||
25 | Acpi table [MCFG] - 60 bytes written to MCFG.dat | ||
26 | Acpi table [SSDT] - 444 bytes written to SSDT1.dat | ||
27 | Acpi table [SSDT] - 439 bytes written to SSDT2.dat | ||
28 | Acpi table [SSDT] - 439 bytes written to SSDT3.dat | ||
29 | Acpi table [SSDT] - 439 bytes written to SSDT4.dat | ||
30 | Acpi table [SSDT] - 439 bytes written to SSDT5.dat | ||
31 | Acpi table [RSDT] - 76 bytes written to RSDT.dat | ||
32 | Acpi table [RSDP] - 20 bytes written to RSDP.dat | ||
33 | |||
34 | $ iasl -d *.dat | ||
35 | ... | ||
36 | .fi | ||
37 | creates *.dsl, a human readable form which can be edited | ||
38 | and compiled using iasl. | ||
39 | |||
40 | |||
41 | .SH NOTES | ||
42 | |||
43 | .B "acpidump " | ||
44 | must be run as root. | ||
45 | |||
46 | .SH REFERENCES | ||
47 | ACPICA: https://acpica.org/ | ||
48 | |||
49 | .SH FILES | ||
50 | .ta | ||
51 | .nf | ||
52 | /dev/mem | ||
53 | /sys/firmware/acpi/tables/dynamic/* | ||
54 | .fi | ||
55 | |||
56 | .PP | ||
57 | .SH AUTHOR | ||
58 | .nf | ||
59 | Written by Len Brown <len.brown@intel.com> | ||
diff --git a/tools/power/acpi/acpidump.c b/tools/power/acpi/acpidump.c new file mode 100644 index 000000000000..07779871421c --- /dev/null +++ b/tools/power/acpi/acpidump.c | |||
@@ -0,0 +1,560 @@ | |||
1 | /* | ||
2 | * (c) Alexey Starikovskiy, Intel, 2005-2006. | ||
3 | * All rights reserved. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions | ||
7 | * are met: | ||
8 | * 1. Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions, and the following disclaimer, | ||
10 | * without modification. | ||
11 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
12 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
13 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
14 | * including a substantially similar Disclaimer requirement for further | ||
15 | * binary redistribution. | ||
16 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
17 | * of any contributors may be used to endorse or promote products derived | ||
18 | * from this software without specific prior written permission. | ||
19 | * | ||
20 | * Alternatively, this software may be distributed under the terms of the | ||
21 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
22 | * Software Foundation. | ||
23 | * | ||
24 | * NO WARRANTY | ||
25 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
26 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
27 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
28 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
29 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
30 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
31 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
32 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
33 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
34 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
35 | * POSSIBILITY OF SUCH DAMAGES. | ||
36 | */ | ||
37 | |||
38 | #ifdef DEFINE_ALTERNATE_TYPES | ||
39 | /* hack to enable building old application with new headers -lenb */ | ||
40 | #define acpi_fadt_descriptor acpi_table_fadt | ||
41 | #define acpi_rsdp_descriptor acpi_table_rsdp | ||
42 | #define DSDT_SIG ACPI_SIG_DSDT | ||
43 | #define FACS_SIG ACPI_SIG_FACS | ||
44 | #define FADT_SIG ACPI_SIG_FADT | ||
45 | #define xfirmware_ctrl Xfacs | ||
46 | #define firmware_ctrl facs | ||
47 | |||
48 | typedef int s32; | ||
49 | typedef unsigned char u8; | ||
50 | typedef unsigned short u16; | ||
51 | typedef unsigned int u32; | ||
52 | typedef unsigned long long u64; | ||
53 | typedef long long s64; | ||
54 | #endif | ||
55 | |||
56 | #include <sys/mman.h> | ||
57 | #include <sys/types.h> | ||
58 | #include <sys/stat.h> | ||
59 | #include <fcntl.h> | ||
60 | #include <stdio.h> | ||
61 | #include <string.h> | ||
62 | #include <unistd.h> | ||
63 | #include <getopt.h> | ||
64 | |||
65 | #include <sys/types.h> | ||
66 | #include <dirent.h> | ||
67 | |||
68 | #include <acpi/acconfig.h> | ||
69 | #include <acpi/platform/acenv.h> | ||
70 | #include <acpi/actypes.h> | ||
71 | #include <acpi/actbl.h> | ||
72 | |||
73 | static inline u8 checksum(u8 * buffer, u32 length) | ||
74 | { | ||
75 | u8 sum = 0, *i = buffer; | ||
76 | buffer += length; | ||
77 | for (; i < buffer; sum += *(i++)); | ||
78 | return sum; | ||
79 | } | ||
80 | |||
81 | static unsigned long psz, addr, length; | ||
82 | static int print, connect, skip; | ||
83 | static u8 select_sig[4]; | ||
84 | |||
85 | static unsigned long read_efi_systab( void ) | ||
86 | { | ||
87 | char buffer[80]; | ||
88 | unsigned long addr; | ||
89 | FILE *f = fopen("/sys/firmware/efi/systab", "r"); | ||
90 | if (f) { | ||
91 | while (fgets(buffer, 80, f)) { | ||
92 | if (sscanf(buffer, "ACPI20=0x%lx", &addr) == 1) | ||
93 | return addr; | ||
94 | } | ||
95 | fclose(f); | ||
96 | } | ||
97 | return 0; | ||
98 | } | ||
99 | |||
100 | static u8 *acpi_map_memory(unsigned long where, unsigned length) | ||
101 | { | ||
102 | unsigned long offset; | ||
103 | u8 *there; | ||
104 | int fd = open("/dev/mem", O_RDONLY); | ||
105 | if (fd < 0) { | ||
106 | fprintf(stderr, "acpi_os_map_memory: cannot open /dev/mem\n"); | ||
107 | exit(1); | ||
108 | } | ||
109 | offset = where % psz; | ||
110 | there = mmap(NULL, length + offset, PROT_READ, MAP_PRIVATE, | ||
111 | fd, where - offset); | ||
112 | close(fd); | ||
113 | if (there == MAP_FAILED) return 0; | ||
114 | return (there + offset); | ||
115 | } | ||
116 | |||
117 | static void acpi_unmap_memory(u8 * there, unsigned length) | ||
118 | { | ||
119 | unsigned long offset = (unsigned long)there % psz; | ||
120 | munmap(there - offset, length + offset); | ||
121 | } | ||
122 | |||
123 | static struct acpi_table_header *acpi_map_table(unsigned long where, char *sig) | ||
124 | { | ||
125 | unsigned size; | ||
126 | struct acpi_table_header *tbl = (struct acpi_table_header *) | ||
127 | acpi_map_memory(where, sizeof(struct acpi_table_header)); | ||
128 | if (!tbl || (sig && memcmp(sig, tbl->signature, 4))) return 0; | ||
129 | size = tbl->length; | ||
130 | acpi_unmap_memory((u8 *) tbl, sizeof(struct acpi_table_header)); | ||
131 | return (struct acpi_table_header *)acpi_map_memory(where, size); | ||
132 | } | ||
133 | |||
134 | static void acpi_unmap_table(struct acpi_table_header *tbl) | ||
135 | { | ||
136 | acpi_unmap_memory((u8 *)tbl, tbl->length); | ||
137 | } | ||
138 | |||
139 | static struct acpi_rsdp_descriptor *acpi_scan_for_rsdp(u8 *begin, u32 length) | ||
140 | { | ||
141 | struct acpi_rsdp_descriptor *rsdp; | ||
142 | u8 *i, *end = begin + length; | ||
143 | /* Search from given start address for the requested length */ | ||
144 | for (i = begin; i < end; i += ACPI_RSDP_SCAN_STEP) { | ||
145 | /* The signature and checksum must both be correct */ | ||
146 | if (memcmp((char *)i, "RSD PTR ", 8)) continue; | ||
147 | rsdp = (struct acpi_rsdp_descriptor *)i; | ||
148 | /* Signature matches, check the appropriate checksum */ | ||
149 | if (!checksum((u8 *) rsdp, (rsdp->revision < 2) ? | ||
150 | ACPI_RSDP_CHECKSUM_LENGTH : | ||
151 | ACPI_RSDP_XCHECKSUM_LENGTH)) | ||
152 | /* Checksum valid, we have found a valid RSDP */ | ||
153 | return rsdp; | ||
154 | } | ||
155 | /* Searched entire block, no RSDP was found */ | ||
156 | return 0; | ||
157 | } | ||
158 | |||
159 | /* | ||
160 | * Output data | ||
161 | */ | ||
162 | static void acpi_show_data(int fd, u8 * data, int size) | ||
163 | { | ||
164 | char buffer[256]; | ||
165 | int len; | ||
166 | int i, remain = size; | ||
167 | while (remain > 0) { | ||
168 | len = snprintf(buffer, 256, " %04x:", size - remain); | ||
169 | for (i = 0; i < 16 && i < remain; i++) { | ||
170 | len += | ||
171 | snprintf(&buffer[len], 256 - len, " %02x", data[i]); | ||
172 | } | ||
173 | for (; i < 16; i++) { | ||
174 | len += snprintf(&buffer[len], 256 - len, " "); | ||
175 | } | ||
176 | len += snprintf(&buffer[len], 256 - len, " "); | ||
177 | for (i = 0; i < 16 && i < remain; i++) { | ||
178 | buffer[len++] = (isprint(data[i])) ? data[i] : '.'; | ||
179 | } | ||
180 | buffer[len++] = '\n'; | ||
181 | write(fd, buffer, len); | ||
182 | data += 16; | ||
183 | remain -= 16; | ||
184 | } | ||
185 | } | ||
186 | |||
187 | /* | ||
188 | * Output ACPI table | ||
189 | */ | ||
190 | static void acpi_show_table(int fd, struct acpi_table_header *table, unsigned long addr) | ||
191 | { | ||
192 | char buff[80]; | ||
193 | int len = snprintf(buff, 80, "%.4s @ %p\n", table->signature, (void *)addr); | ||
194 | write(fd, buff, len); | ||
195 | acpi_show_data(fd, (u8 *) table, table->length); | ||
196 | buff[0] = '\n'; | ||
197 | write(fd, buff, 1); | ||
198 | } | ||
199 | |||
200 | static void write_table(int fd, struct acpi_table_header *tbl, unsigned long addr) | ||
201 | { | ||
202 | static int select_done = 0; | ||
203 | if (!select_sig[0]) { | ||
204 | if (print) { | ||
205 | acpi_show_table(fd, tbl, addr); | ||
206 | } else { | ||
207 | write(fd, tbl, tbl->length); | ||
208 | } | ||
209 | } else if (!select_done && !memcmp(select_sig, tbl->signature, 4)) { | ||
210 | if (skip > 0) { | ||
211 | --skip; | ||
212 | return; | ||
213 | } | ||
214 | if (print) { | ||
215 | acpi_show_table(fd, tbl, addr); | ||
216 | } else { | ||
217 | write(fd, tbl, tbl->length); | ||
218 | } | ||
219 | select_done = 1; | ||
220 | } | ||
221 | } | ||
222 | |||
223 | static void acpi_dump_FADT(int fd, struct acpi_table_header *tbl, unsigned long xaddr) { | ||
224 | struct acpi_fadt_descriptor x; | ||
225 | unsigned long addr; | ||
226 | size_t len = sizeof(struct acpi_fadt_descriptor); | ||
227 | if (len > tbl->length) len = tbl->length; | ||
228 | memcpy(&x, tbl, len); | ||
229 | x.header.length = len; | ||
230 | if (checksum((u8 *)tbl, len)) { | ||
231 | fprintf(stderr, "Wrong checksum for FADT!\n"); | ||
232 | } | ||
233 | if (x.header.length >= 148 && x.Xdsdt) { | ||
234 | addr = (unsigned long)x.Xdsdt; | ||
235 | if (connect) { | ||
236 | x.Xdsdt = lseek(fd, 0, SEEK_CUR); | ||
237 | } | ||
238 | } else if (x.header.length >= 44 && x.dsdt) { | ||
239 | addr = (unsigned long)x.dsdt; | ||
240 | if (connect) { | ||
241 | x.dsdt = lseek(fd, 0, SEEK_CUR); | ||
242 | } | ||
243 | } else { | ||
244 | fprintf(stderr, "No DSDT in FADT!\n"); | ||
245 | goto no_dsdt; | ||
246 | } | ||
247 | tbl = acpi_map_table(addr, DSDT_SIG); | ||
248 | if (!tbl) goto no_dsdt; | ||
249 | if (checksum((u8 *)tbl, tbl->length)) | ||
250 | fprintf(stderr, "Wrong checksum for DSDT!\n"); | ||
251 | write_table(fd, tbl, addr); | ||
252 | acpi_unmap_table(tbl); | ||
253 | no_dsdt: | ||
254 | if (x.header.length >= 140 && x.xfirmware_ctrl) { | ||
255 | addr = (unsigned long)x.xfirmware_ctrl; | ||
256 | if (connect) { | ||
257 | x.xfirmware_ctrl = lseek(fd, 0, SEEK_CUR); | ||
258 | } | ||
259 | } else if (x.header.length >= 40 && x.firmware_ctrl) { | ||
260 | addr = (unsigned long)x.firmware_ctrl; | ||
261 | if (connect) { | ||
262 | x.firmware_ctrl = lseek(fd, 0, SEEK_CUR); | ||
263 | } | ||
264 | } else { | ||
265 | fprintf(stderr, "No FACS in FADT!\n"); | ||
266 | goto no_facs; | ||
267 | } | ||
268 | tbl = acpi_map_table(addr, FACS_SIG); | ||
269 | if (!tbl) goto no_facs; | ||
270 | /* do not checksum FACS */ | ||
271 | write_table(fd, tbl, addr); | ||
272 | acpi_unmap_table(tbl); | ||
273 | no_facs: | ||
274 | write_table(fd, (struct acpi_table_header *)&x, xaddr); | ||
275 | } | ||
276 | |||
277 | static int acpi_dump_SDT(int fd, struct acpi_rsdp_descriptor *rsdp) | ||
278 | { | ||
279 | struct acpi_table_header *sdt, *tbl = 0; | ||
280 | int xsdt = 1, i, num; | ||
281 | char *offset; | ||
282 | unsigned long addr; | ||
283 | if (rsdp->revision > 1 && rsdp->xsdt_physical_address) { | ||
284 | tbl = acpi_map_table(rsdp->xsdt_physical_address, "XSDT"); | ||
285 | } | ||
286 | if (!tbl && rsdp->rsdt_physical_address) { | ||
287 | xsdt = 0; | ||
288 | tbl = acpi_map_table(rsdp->rsdt_physical_address, "RSDT"); | ||
289 | } | ||
290 | if (!tbl) return 0; | ||
291 | sdt = malloc(tbl->length); | ||
292 | memcpy(sdt, tbl, tbl->length); | ||
293 | acpi_unmap_table(tbl); | ||
294 | if (checksum((u8 *)sdt, sdt->length)) | ||
295 | fprintf(stderr, "Wrong checksum for %s!\n", (xsdt)?"XSDT":"RSDT"); | ||
296 | num = (sdt->length - sizeof(struct acpi_table_header))/((xsdt)?sizeof(u64):sizeof(u32)); | ||
297 | offset = (char *)sdt + sizeof(struct acpi_table_header); | ||
298 | for (i = 0; i < num; ++i, offset += ((xsdt) ? sizeof(u64) : sizeof(u32))) { | ||
299 | addr = (xsdt) ? (unsigned long)(*(u64 *)offset): | ||
300 | (unsigned long)(*(u32 *)offset); | ||
301 | if (!addr) continue; | ||
302 | tbl = acpi_map_table(addr, 0); | ||
303 | if (!tbl) continue; | ||
304 | if (!memcmp(tbl->signature, FADT_SIG, 4)) { | ||
305 | acpi_dump_FADT(fd, tbl, addr); | ||
306 | } else { | ||
307 | if (checksum((u8 *)tbl, tbl->length)) | ||
308 | fprintf(stderr, "Wrong checksum for generic table!\n"); | ||
309 | write_table(fd, tbl, addr); | ||
310 | } | ||
311 | acpi_unmap_table(tbl); | ||
312 | if (connect) { | ||
313 | if (xsdt) | ||
314 | (*(u64*)offset) = lseek(fd, 0, SEEK_CUR); | ||
315 | else | ||
316 | (*(u32*)offset) = lseek(fd, 0, SEEK_CUR); | ||
317 | } | ||
318 | } | ||
319 | if (xsdt) { | ||
320 | addr = (unsigned long)rsdp->xsdt_physical_address; | ||
321 | if (connect) { | ||
322 | rsdp->xsdt_physical_address = lseek(fd, 0, SEEK_CUR); | ||
323 | } | ||
324 | } else { | ||
325 | addr = (unsigned long)rsdp->rsdt_physical_address; | ||
326 | if (connect) { | ||
327 | rsdp->rsdt_physical_address = lseek(fd, 0, SEEK_CUR); | ||
328 | } | ||
329 | } | ||
330 | write_table(fd, sdt, addr); | ||
331 | free (sdt); | ||
332 | return 1; | ||
333 | } | ||
334 | |||
335 | #define DYNAMIC_SSDT "/sys/firmware/acpi/tables/dynamic" | ||
336 | |||
337 | static void acpi_dump_dynamic_SSDT(int fd) | ||
338 | { | ||
339 | struct stat file_stat; | ||
340 | char filename[256], *ptr; | ||
341 | DIR *tabledir; | ||
342 | struct dirent *entry; | ||
343 | FILE *fp; | ||
344 | int count, readcount, length; | ||
345 | struct acpi_table_header table_header, *ptable; | ||
346 | |||
347 | if (stat(DYNAMIC_SSDT, &file_stat) == -1) { | ||
348 | /* The directory doesn't exist */ | ||
349 | return; | ||
350 | } | ||
351 | tabledir = opendir(DYNAMIC_SSDT); | ||
352 | if(!tabledir){ | ||
353 | /*can't open the directory */ | ||
354 | return; | ||
355 | } | ||
356 | |||
357 | while ((entry = readdir(tabledir)) != 0){ | ||
358 | /* skip the file of . /.. */ | ||
359 | if (entry->d_name[0] == '.') | ||
360 | continue; | ||
361 | |||
362 | sprintf(filename, "%s/%s", DYNAMIC_SSDT, entry->d_name); | ||
363 | fp = fopen(filename, "r"); | ||
364 | if (fp == NULL) { | ||
365 | fprintf(stderr, "Can't open the file of %s\n", | ||
366 | filename); | ||
367 | continue; | ||
368 | } | ||
369 | /* Read the Table header to parse the table length */ | ||
370 | count = fread(&table_header, 1, sizeof(struct acpi_table_header), fp); | ||
371 | if (count < sizeof(table_header)) { | ||
372 | /* the length is lessn than ACPI table header. skip it */ | ||
373 | fclose(fp); | ||
374 | continue; | ||
375 | } | ||
376 | length = table_header.length; | ||
377 | ptr = malloc(table_header.length); | ||
378 | fseek(fp, 0, SEEK_SET); | ||
379 | readcount = 0; | ||
380 | while(!feof(fp) && readcount < length) { | ||
381 | count = fread(ptr + readcount, 1, 256, fp); | ||
382 | readcount += count; | ||
383 | } | ||
384 | fclose(fp); | ||
385 | ptable = (struct acpi_table_header *) ptr; | ||
386 | if (checksum((u8 *) ptable, ptable->length)) | ||
387 | fprintf(stderr, "Wrong checksum " | ||
388 | "for dynamic SSDT table!\n"); | ||
389 | write_table(fd, ptable, 0); | ||
390 | free(ptr); | ||
391 | } | ||
392 | closedir(tabledir); | ||
393 | return; | ||
394 | } | ||
395 | |||
396 | static void usage(const char *progname) | ||
397 | { | ||
398 | puts("Usage:"); | ||
399 | printf("%s [--addr 0x1234][--table DSDT][--output filename]" | ||
400 | "[--binary][--length 0x456][--help]\n", progname); | ||
401 | puts("\t--addr 0x1234 or -a 0x1234 -- look for tables at this physical address"); | ||
402 | puts("\t--table DSDT or -t DSDT -- only dump table with DSDT signature"); | ||
403 | puts("\t--output filename or -o filename -- redirect output from stdin to filename"); | ||
404 | puts("\t--binary or -b -- dump data in binary form rather than in hex-dump format"); | ||
405 | puts("\t--length 0x456 or -l 0x456 -- works only with --addr, dump physical memory" | ||
406 | "\n\t\tregion without trying to understand it's contents"); | ||
407 | puts("\t--skip 2 or -s 2 -- skip 2 tables of the given name and output only 3rd one"); | ||
408 | puts("\t--help or -h -- this help message"); | ||
409 | exit(0); | ||
410 | } | ||
411 | |||
412 | static struct option long_options[] = { | ||
413 | {"addr", 1, 0, 0}, | ||
414 | {"table", 1, 0, 0}, | ||
415 | {"output", 1, 0, 0}, | ||
416 | {"binary", 0, 0, 0}, | ||
417 | {"length", 1, 0, 0}, | ||
418 | {"skip", 1, 0, 0}, | ||
419 | {"help", 0, 0, 0}, | ||
420 | {0, 0, 0, 0} | ||
421 | }; | ||
422 | int main(int argc, char **argv) | ||
423 | { | ||
424 | int option_index, c, fd; | ||
425 | u8 *raw; | ||
426 | struct acpi_rsdp_descriptor rsdpx, *x = 0; | ||
427 | char *filename = 0; | ||
428 | char buff[80]; | ||
429 | memset(select_sig, 0, 4); | ||
430 | print = 1; | ||
431 | connect = 0; | ||
432 | addr = length = 0; | ||
433 | skip = 0; | ||
434 | while (1) { | ||
435 | option_index = 0; | ||
436 | c = getopt_long(argc, argv, "a:t:o:bl:s:h", | ||
437 | long_options, &option_index); | ||
438 | if (c == -1) | ||
439 | break; | ||
440 | |||
441 | switch (c) { | ||
442 | case 0: | ||
443 | switch (option_index) { | ||
444 | case 0: | ||
445 | addr = strtoul(optarg, (char **)NULL, 16); | ||
446 | break; | ||
447 | case 1: | ||
448 | memcpy(select_sig, optarg, 4); | ||
449 | break; | ||
450 | case 2: | ||
451 | filename = optarg; | ||
452 | break; | ||
453 | case 3: | ||
454 | print = 0; | ||
455 | break; | ||
456 | case 4: | ||
457 | length = strtoul(optarg, (char **)NULL, 16); | ||
458 | break; | ||
459 | case 5: | ||
460 | skip = strtoul(optarg, (char **)NULL, 10); | ||
461 | break; | ||
462 | case 6: | ||
463 | usage(argv[0]); | ||
464 | exit(0); | ||
465 | } | ||
466 | break; | ||
467 | case 'a': | ||
468 | addr = strtoul(optarg, (char **)NULL, 16); | ||
469 | break; | ||
470 | case 't': | ||
471 | memcpy(select_sig, optarg, 4); | ||
472 | break; | ||
473 | case 'o': | ||
474 | filename = optarg; | ||
475 | break; | ||
476 | case 'b': | ||
477 | print = 0; | ||
478 | break; | ||
479 | case 'l': | ||
480 | length = strtoul(optarg, (char **)NULL, 16); | ||
481 | break; | ||
482 | case 's': | ||
483 | skip = strtoul(optarg, (char **)NULL, 10); | ||
484 | break; | ||
485 | case 'h': | ||
486 | usage(argv[0]); | ||
487 | exit(0); | ||
488 | default: | ||
489 | printf("Unknown option!\n"); | ||
490 | usage(argv[0]); | ||
491 | exit(0); | ||
492 | } | ||
493 | } | ||
494 | |||
495 | fd = STDOUT_FILENO; | ||
496 | if (filename) { | ||
497 | fd = creat(filename, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); | ||
498 | if (fd < 0) | ||
499 | return fd; | ||
500 | } | ||
501 | |||
502 | if (!select_sig[0] && !print) { | ||
503 | connect = 1; | ||
504 | } | ||
505 | |||
506 | psz = sysconf(_SC_PAGESIZE); | ||
507 | if (length && addr) { | ||
508 | /* We know length and address, it means we just want a memory dump */ | ||
509 | if (!(raw = acpi_map_memory(addr, length))) | ||
510 | goto not_found; | ||
511 | write(fd, raw, length); | ||
512 | acpi_unmap_memory(raw, length); | ||
513 | close(fd); | ||
514 | return 0; | ||
515 | } | ||
516 | |||
517 | length = sizeof(struct acpi_rsdp_descriptor); | ||
518 | if (!addr) { | ||
519 | addr = read_efi_systab(); | ||
520 | if (!addr) { | ||
521 | addr = ACPI_HI_RSDP_WINDOW_BASE; | ||
522 | length = ACPI_HI_RSDP_WINDOW_SIZE; | ||
523 | } | ||
524 | } | ||
525 | |||
526 | if (!(raw = acpi_map_memory(addr, length)) || | ||
527 | !(x = acpi_scan_for_rsdp(raw, length))) | ||
528 | goto not_found; | ||
529 | |||
530 | /* Find RSDP and print all found tables */ | ||
531 | memcpy(&rsdpx, x, sizeof(struct acpi_rsdp_descriptor)); | ||
532 | acpi_unmap_memory(raw, length); | ||
533 | if (connect) { | ||
534 | lseek(fd, sizeof(struct acpi_rsdp_descriptor), SEEK_SET); | ||
535 | } | ||
536 | if (!acpi_dump_SDT(fd, &rsdpx)) | ||
537 | goto not_found; | ||
538 | if (connect) { | ||
539 | lseek(fd, 0, SEEK_SET); | ||
540 | write(fd, x, (rsdpx.revision < 2) ? | ||
541 | ACPI_RSDP_CHECKSUM_LENGTH : ACPI_RSDP_XCHECKSUM_LENGTH); | ||
542 | } else if (!select_sig[0] || !memcmp("RSD PTR ", select_sig, 4)) { | ||
543 | addr += (long)x - (long)raw; | ||
544 | length = snprintf(buff, 80, "RSD PTR @ %p\n", (void *)addr); | ||
545 | write(fd, buff, length); | ||
546 | acpi_show_data(fd, (u8 *) & rsdpx, (rsdpx.revision < 2) ? | ||
547 | ACPI_RSDP_CHECKSUM_LENGTH : ACPI_RSDP_XCHECKSUM_LENGTH); | ||
548 | buff[0] = '\n'; | ||
549 | write(fd, buff, 1); | ||
550 | } | ||
551 | acpi_dump_dynamic_SSDT(fd); | ||
552 | close(fd); | ||
553 | return 0; | ||
554 | not_found: | ||
555 | close(fd); | ||
556 | fprintf(stderr, "ACPI tables were not found. If you know location " | ||
557 | "of RSD PTR table (from dmesg, etc), " | ||
558 | "supply it with either --addr or -a option\n"); | ||
559 | return 1; | ||
560 | } | ||
diff --git a/tools/power/x86/turbostat/turbostat.8 b/tools/power/x86/turbostat/turbostat.8 index 74e44507dfe9..e4d0690cccf9 100644 --- a/tools/power/x86/turbostat/turbostat.8 +++ b/tools/power/x86/turbostat/turbostat.8 | |||
@@ -4,15 +4,11 @@ turbostat \- Report processor frequency and idle statistics | |||
4 | .SH SYNOPSIS | 4 | .SH SYNOPSIS |
5 | .ft B | 5 | .ft B |
6 | .B turbostat | 6 | .B turbostat |
7 | .RB [ "\-s" ] | 7 | .RB [ Options ] |
8 | .RB [ "\-v" ] | ||
9 | .RB [ "\-M MSR#" ] | ||
10 | .RB command | 8 | .RB command |
11 | .br | 9 | .br |
12 | .B turbostat | 10 | .B turbostat |
13 | .RB [ "\-s" ] | 11 | .RB [ Options ] |
14 | .RB [ "\-v" ] | ||
15 | .RB [ "\-M MSR#" ] | ||
16 | .RB [ "\-i interval_sec" ] | 12 | .RB [ "\-i interval_sec" ] |
17 | .SH DESCRIPTION | 13 | .SH DESCRIPTION |
18 | \fBturbostat \fP reports processor topology, frequency | 14 | \fBturbostat \fP reports processor topology, frequency |
@@ -27,16 +23,23 @@ supports an "invariant" TSC, plus the APERF and MPERF MSRs. | |||
27 | on processors that additionally support C-state residency counters. | 23 | on processors that additionally support C-state residency counters. |
28 | 24 | ||
29 | .SS Options | 25 | .SS Options |
30 | The \fB-s\fP option limits output to a 1-line system summary for each interval. | 26 | The \fB-p\fP option limits output to the 1st thread in 1st core of each package. |
31 | .PP | 27 | .PP |
32 | The \fB-c\fP option limits output to the 1st thread in each core. | 28 | The \fB-P\fP option limits output to the 1st thread in each Package. |
33 | .PP | 29 | .PP |
34 | The \fB-p\fP option limits output to the 1st thread in each package. | 30 | The \fB-S\fP option limits output to a 1-line System Summary for each interval. |
35 | .PP | 31 | .PP |
36 | The \fB-v\fP option increases verbosity. | 32 | The \fB-v\fP option increases verbosity. |
37 | .PP | 33 | .PP |
38 | The \fB-M MSR#\fP option dumps the specified MSR, | 34 | The \fB-s\fP option prints the SMI counter, equivalent to "-c 0x34" |
39 | in addition to the usual frequency and idle statistics. | 35 | .PP |
36 | The \fB-c MSR#\fP option includes the delta of the specified 32-bit MSR counter. | ||
37 | .PP | ||
38 | The \fB-C MSR#\fP option includes the delta of the specified 64-bit MSR counter. | ||
39 | .PP | ||
40 | The \fB-m MSR#\fP option includes the the specified 32-bit MSR value. | ||
41 | .PP | ||
42 | The \fB-M MSR#\fP option includes the the specified 64-bit MSR value. | ||
40 | .PP | 43 | .PP |
41 | The \fB-i interval_sec\fP option prints statistics every \fiinterval_sec\fP seconds. | 44 | The \fB-i interval_sec\fP option prints statistics every \fiinterval_sec\fP seconds. |
42 | The default is 5 seconds. | 45 | The default is 5 seconds. |
@@ -150,6 +153,29 @@ Note that turbostat reports average GHz of 3.63, while | |||
150 | the arithmetic average of the GHz column above is lower. | 153 | the arithmetic average of the GHz column above is lower. |
151 | This is a weighted average, where the weight is %c0. ie. it is the total number of | 154 | This is a weighted average, where the weight is %c0. ie. it is the total number of |
152 | un-halted cycles elapsed per time divided by the number of CPUs. | 155 | un-halted cycles elapsed per time divided by the number of CPUs. |
156 | .SH SMI COUNTING EXAMPLE | ||
157 | On Intel Nehalem and newer processors, MSR 0x34 is a System Management Mode Interrupt (SMI) counter. | ||
158 | Using the -m option, you can display how many SMIs have fired since reset, or if there | ||
159 | are SMIs during the measurement interval, you can display the delta using the -d option. | ||
160 | .nf | ||
161 | [root@x980 ~]# turbostat -m 0x34 | ||
162 | cor CPU %c0 GHz TSC MSR 0x034 %c1 %c3 %c6 %pc3 %pc6 | ||
163 | 1.41 1.82 3.38 0x00000000 8.92 37.82 51.85 17.37 0.55 | ||
164 | 0 0 3.73 2.03 3.38 0x00000055 1.72 48.25 46.31 17.38 0.55 | ||
165 | 0 6 0.14 1.63 3.38 0x00000056 5.30 | ||
166 | 1 2 2.51 1.80 3.38 0x00000056 15.65 29.33 52.52 | ||
167 | 1 8 0.10 1.65 3.38 0x00000056 18.05 | ||
168 | 2 4 1.16 1.68 3.38 0x00000056 5.87 24.47 68.50 | ||
169 | 2 10 0.10 1.63 3.38 0x00000056 6.93 | ||
170 | 8 1 3.84 1.91 3.38 0x00000056 1.36 50.65 44.16 | ||
171 | 8 7 0.08 1.64 3.38 0x00000056 5.12 | ||
172 | 9 3 1.82 1.73 3.38 0x00000056 7.59 24.21 66.38 | ||
173 | 9 9 0.09 1.68 3.38 0x00000056 9.32 | ||
174 | 10 5 1.66 1.65 3.38 0x00000056 15.10 50.00 33.23 | ||
175 | 10 11 1.72 1.65 3.38 0x00000056 15.05 | ||
176 | ^C | ||
177 | [root@x980 ~]# | ||
178 | .fi | ||
153 | .SH NOTES | 179 | .SH NOTES |
154 | 180 | ||
155 | .B "turbostat " | 181 | .B "turbostat " |
@@ -165,6 +191,13 @@ may work poorly on Linux-2.6.20 through 2.6.29, | |||
165 | as \fBacpi-cpufreq \fPperiodically cleared the APERF and MPERF | 191 | as \fBacpi-cpufreq \fPperiodically cleared the APERF and MPERF |
166 | in those kernels. | 192 | in those kernels. |
167 | 193 | ||
194 | If the TSC column does not make sense, then | ||
195 | the other numbers will also make no sense. | ||
196 | Turbostat is lightweight, and its data collection is not atomic. | ||
197 | These issues are usually caused by an extremely short measurement | ||
198 | interval (much less than 1 second), or system activity that prevents | ||
199 | turbostat from being able to run on all CPUS to quickly collect data. | ||
200 | |||
168 | The APERF, MPERF MSRs are defined to count non-halted cycles. | 201 | The APERF, MPERF MSRs are defined to count non-halted cycles. |
169 | Although it is not guaranteed by the architecture, turbostat assumes | 202 | Although it is not guaranteed by the architecture, turbostat assumes |
170 | that they count at TSC rate, which is true on all processors tested to date. | 203 | that they count at TSC rate, which is true on all processors tested to date. |
diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index 861d77190206..2655ae9a3ad8 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c | |||
@@ -35,9 +35,9 @@ | |||
35 | #include <ctype.h> | 35 | #include <ctype.h> |
36 | #include <sched.h> | 36 | #include <sched.h> |
37 | 37 | ||
38 | #define MSR_TSC 0x10 | ||
39 | #define MSR_NEHALEM_PLATFORM_INFO 0xCE | 38 | #define MSR_NEHALEM_PLATFORM_INFO 0xCE |
40 | #define MSR_NEHALEM_TURBO_RATIO_LIMIT 0x1AD | 39 | #define MSR_NEHALEM_TURBO_RATIO_LIMIT 0x1AD |
40 | #define MSR_IVT_TURBO_RATIO_LIMIT 0x1AE | ||
41 | #define MSR_APERF 0xE8 | 41 | #define MSR_APERF 0xE8 |
42 | #define MSR_MPERF 0xE7 | 42 | #define MSR_MPERF 0xE7 |
43 | #define MSR_PKG_C2_RESIDENCY 0x60D /* SNB only */ | 43 | #define MSR_PKG_C2_RESIDENCY 0x60D /* SNB only */ |
@@ -62,7 +62,11 @@ unsigned int genuine_intel; | |||
62 | unsigned int has_invariant_tsc; | 62 | unsigned int has_invariant_tsc; |
63 | unsigned int do_nehalem_platform_info; | 63 | unsigned int do_nehalem_platform_info; |
64 | unsigned int do_nehalem_turbo_ratio_limit; | 64 | unsigned int do_nehalem_turbo_ratio_limit; |
65 | unsigned int extra_msr_offset; | 65 | unsigned int do_ivt_turbo_ratio_limit; |
66 | unsigned int extra_msr_offset32; | ||
67 | unsigned int extra_msr_offset64; | ||
68 | unsigned int extra_delta_offset32; | ||
69 | unsigned int extra_delta_offset64; | ||
66 | double bclk; | 70 | double bclk; |
67 | unsigned int show_pkg; | 71 | unsigned int show_pkg; |
68 | unsigned int show_core; | 72 | unsigned int show_core; |
@@ -83,7 +87,10 @@ struct thread_data { | |||
83 | unsigned long long aperf; | 87 | unsigned long long aperf; |
84 | unsigned long long mperf; | 88 | unsigned long long mperf; |
85 | unsigned long long c1; /* derived */ | 89 | unsigned long long c1; /* derived */ |
86 | unsigned long long extra_msr; | 90 | unsigned long long extra_msr64; |
91 | unsigned long long extra_delta64; | ||
92 | unsigned long long extra_msr32; | ||
93 | unsigned long long extra_delta32; | ||
87 | unsigned int cpu_id; | 94 | unsigned int cpu_id; |
88 | unsigned int flags; | 95 | unsigned int flags; |
89 | #define CPU_IS_FIRST_THREAD_IN_CORE 0x2 | 96 | #define CPU_IS_FIRST_THREAD_IN_CORE 0x2 |
@@ -222,6 +229,14 @@ void print_header(void) | |||
222 | if (has_aperf) | 229 | if (has_aperf) |
223 | outp += sprintf(outp, " GHz"); | 230 | outp += sprintf(outp, " GHz"); |
224 | outp += sprintf(outp, " TSC"); | 231 | outp += sprintf(outp, " TSC"); |
232 | if (extra_delta_offset32) | ||
233 | outp += sprintf(outp, " count 0x%03X", extra_delta_offset32); | ||
234 | if (extra_delta_offset64) | ||
235 | outp += sprintf(outp, " COUNT 0x%03X", extra_delta_offset64); | ||
236 | if (extra_msr_offset32) | ||
237 | outp += sprintf(outp, " MSR 0x%03X", extra_msr_offset32); | ||
238 | if (extra_msr_offset64) | ||
239 | outp += sprintf(outp, " MSR 0x%03X", extra_msr_offset64); | ||
225 | if (do_nhm_cstates) | 240 | if (do_nhm_cstates) |
226 | outp += sprintf(outp, " %%c1"); | 241 | outp += sprintf(outp, " %%c1"); |
227 | if (do_nhm_cstates) | 242 | if (do_nhm_cstates) |
@@ -238,8 +253,6 @@ void print_header(void) | |||
238 | outp += sprintf(outp, " %%pc6"); | 253 | outp += sprintf(outp, " %%pc6"); |
239 | if (do_snb_cstates) | 254 | if (do_snb_cstates) |
240 | outp += sprintf(outp, " %%pc7"); | 255 | outp += sprintf(outp, " %%pc7"); |
241 | if (extra_msr_offset) | ||
242 | outp += sprintf(outp, " MSR 0x%x ", extra_msr_offset); | ||
243 | 256 | ||
244 | outp += sprintf(outp, "\n"); | 257 | outp += sprintf(outp, "\n"); |
245 | } | 258 | } |
@@ -255,8 +268,14 @@ int dump_counters(struct thread_data *t, struct core_data *c, | |||
255 | fprintf(stderr, "aperf: %016llX\n", t->aperf); | 268 | fprintf(stderr, "aperf: %016llX\n", t->aperf); |
256 | fprintf(stderr, "mperf: %016llX\n", t->mperf); | 269 | fprintf(stderr, "mperf: %016llX\n", t->mperf); |
257 | fprintf(stderr, "c1: %016llX\n", t->c1); | 270 | fprintf(stderr, "c1: %016llX\n", t->c1); |
271 | fprintf(stderr, "msr0x%x: %08llX\n", | ||
272 | extra_delta_offset32, t->extra_delta32); | ||
258 | fprintf(stderr, "msr0x%x: %016llX\n", | 273 | fprintf(stderr, "msr0x%x: %016llX\n", |
259 | extra_msr_offset, t->extra_msr); | 274 | extra_delta_offset64, t->extra_delta64); |
275 | fprintf(stderr, "msr0x%x: %08llX\n", | ||
276 | extra_msr_offset32, t->extra_msr32); | ||
277 | fprintf(stderr, "msr0x%x: %016llX\n", | ||
278 | extra_msr_offset64, t->extra_msr64); | ||
260 | } | 279 | } |
261 | 280 | ||
262 | if (c) { | 281 | if (c) { |
@@ -360,6 +379,21 @@ int format_counters(struct thread_data *t, struct core_data *c, | |||
360 | /* TSC */ | 379 | /* TSC */ |
361 | outp += sprintf(outp, "%5.2f", 1.0 * t->tsc/units/interval_float); | 380 | outp += sprintf(outp, "%5.2f", 1.0 * t->tsc/units/interval_float); |
362 | 381 | ||
382 | /* delta */ | ||
383 | if (extra_delta_offset32) | ||
384 | outp += sprintf(outp, " %11llu", t->extra_delta32); | ||
385 | |||
386 | /* DELTA */ | ||
387 | if (extra_delta_offset64) | ||
388 | outp += sprintf(outp, " %11llu", t->extra_delta64); | ||
389 | /* msr */ | ||
390 | if (extra_msr_offset32) | ||
391 | outp += sprintf(outp, " 0x%08llx", t->extra_msr32); | ||
392 | |||
393 | /* MSR */ | ||
394 | if (extra_msr_offset64) | ||
395 | outp += sprintf(outp, " 0x%016llx", t->extra_msr64); | ||
396 | |||
363 | if (do_nhm_cstates) { | 397 | if (do_nhm_cstates) { |
364 | if (!skip_c1) | 398 | if (!skip_c1) |
365 | outp += sprintf(outp, " %6.2f", 100.0 * t->c1/t->tsc); | 399 | outp += sprintf(outp, " %6.2f", 100.0 * t->c1/t->tsc); |
@@ -391,8 +425,6 @@ int format_counters(struct thread_data *t, struct core_data *c, | |||
391 | if (do_snb_cstates) | 425 | if (do_snb_cstates) |
392 | outp += sprintf(outp, " %6.2f", 100.0 * p->pc7/t->tsc); | 426 | outp += sprintf(outp, " %6.2f", 100.0 * p->pc7/t->tsc); |
393 | done: | 427 | done: |
394 | if (extra_msr_offset) | ||
395 | outp += sprintf(outp, " 0x%016llx", t->extra_msr); | ||
396 | outp += sprintf(outp, "\n"); | 428 | outp += sprintf(outp, "\n"); |
397 | 429 | ||
398 | return 0; | 430 | return 0; |
@@ -502,10 +534,16 @@ delta_thread(struct thread_data *new, struct thread_data *old, | |||
502 | old->mperf = 1; /* divide by 0 protection */ | 534 | old->mperf = 1; /* divide by 0 protection */ |
503 | } | 535 | } |
504 | 536 | ||
537 | old->extra_delta32 = new->extra_delta32 - old->extra_delta32; | ||
538 | old->extra_delta32 &= 0xFFFFFFFF; | ||
539 | |||
540 | old->extra_delta64 = new->extra_delta64 - old->extra_delta64; | ||
541 | |||
505 | /* | 542 | /* |
506 | * for "extra msr", just copy the latest w/o subtracting | 543 | * Extra MSR is just a snapshot, simply copy latest w/o subtracting |
507 | */ | 544 | */ |
508 | old->extra_msr = new->extra_msr; | 545 | old->extra_msr32 = new->extra_msr32; |
546 | old->extra_msr64 = new->extra_msr64; | ||
509 | } | 547 | } |
510 | 548 | ||
511 | int delta_cpu(struct thread_data *t, struct core_data *c, | 549 | int delta_cpu(struct thread_data *t, struct core_data *c, |
@@ -533,6 +571,9 @@ void clear_counters(struct thread_data *t, struct core_data *c, struct pkg_data | |||
533 | t->mperf = 0; | 571 | t->mperf = 0; |
534 | t->c1 = 0; | 572 | t->c1 = 0; |
535 | 573 | ||
574 | t->extra_delta32 = 0; | ||
575 | t->extra_delta64 = 0; | ||
576 | |||
536 | /* tells format_counters to dump all fields from this set */ | 577 | /* tells format_counters to dump all fields from this set */ |
537 | t->flags = CPU_IS_FIRST_THREAD_IN_CORE | CPU_IS_FIRST_CORE_IN_PACKAGE; | 578 | t->flags = CPU_IS_FIRST_THREAD_IN_CORE | CPU_IS_FIRST_CORE_IN_PACKAGE; |
538 | 579 | ||
@@ -553,6 +594,9 @@ int sum_counters(struct thread_data *t, struct core_data *c, | |||
553 | average.threads.mperf += t->mperf; | 594 | average.threads.mperf += t->mperf; |
554 | average.threads.c1 += t->c1; | 595 | average.threads.c1 += t->c1; |
555 | 596 | ||
597 | average.threads.extra_delta32 += t->extra_delta32; | ||
598 | average.threads.extra_delta64 += t->extra_delta64; | ||
599 | |||
556 | /* sum per-core values only for 1st thread in core */ | 600 | /* sum per-core values only for 1st thread in core */ |
557 | if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE)) | 601 | if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE)) |
558 | return 0; | 602 | return 0; |
@@ -588,6 +632,11 @@ void compute_average(struct thread_data *t, struct core_data *c, | |||
588 | average.threads.mperf /= topo.num_cpus; | 632 | average.threads.mperf /= topo.num_cpus; |
589 | average.threads.c1 /= topo.num_cpus; | 633 | average.threads.c1 /= topo.num_cpus; |
590 | 634 | ||
635 | average.threads.extra_delta32 /= topo.num_cpus; | ||
636 | average.threads.extra_delta32 &= 0xFFFFFFFF; | ||
637 | |||
638 | average.threads.extra_delta64 /= topo.num_cpus; | ||
639 | |||
591 | average.cores.c3 /= topo.num_cores; | 640 | average.cores.c3 /= topo.num_cores; |
592 | average.cores.c6 /= topo.num_cores; | 641 | average.cores.c6 /= topo.num_cores; |
593 | average.cores.c7 /= topo.num_cores; | 642 | average.cores.c7 /= topo.num_cores; |
@@ -629,8 +678,24 @@ int get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p) | |||
629 | return -4; | 678 | return -4; |
630 | } | 679 | } |
631 | 680 | ||
632 | if (extra_msr_offset) | 681 | if (extra_delta_offset32) { |
633 | if (get_msr(cpu, extra_msr_offset, &t->extra_msr)) | 682 | if (get_msr(cpu, extra_delta_offset32, &t->extra_delta32)) |
683 | return -5; | ||
684 | t->extra_delta32 &= 0xFFFFFFFF; | ||
685 | } | ||
686 | |||
687 | if (extra_delta_offset64) | ||
688 | if (get_msr(cpu, extra_delta_offset64, &t->extra_delta64)) | ||
689 | return -5; | ||
690 | |||
691 | if (extra_msr_offset32) { | ||
692 | if (get_msr(cpu, extra_msr_offset32, &t->extra_msr32)) | ||
693 | return -5; | ||
694 | t->extra_msr32 &= 0xFFFFFFFF; | ||
695 | } | ||
696 | |||
697 | if (extra_msr_offset64) | ||
698 | if (get_msr(cpu, extra_msr_offset64, &t->extra_msr64)) | ||
634 | return -5; | 699 | return -5; |
635 | 700 | ||
636 | /* collect core counters only for 1st thread in core */ | 701 | /* collect core counters only for 1st thread in core */ |
@@ -677,6 +742,9 @@ void print_verbose_header(void) | |||
677 | 742 | ||
678 | get_msr(0, MSR_NEHALEM_PLATFORM_INFO, &msr); | 743 | get_msr(0, MSR_NEHALEM_PLATFORM_INFO, &msr); |
679 | 744 | ||
745 | if (verbose > 1) | ||
746 | fprintf(stderr, "MSR_NEHALEM_PLATFORM_INFO: 0x%llx\n", msr); | ||
747 | |||
680 | ratio = (msr >> 40) & 0xFF; | 748 | ratio = (msr >> 40) & 0xFF; |
681 | fprintf(stderr, "%d * %.0f = %.0f MHz max efficiency\n", | 749 | fprintf(stderr, "%d * %.0f = %.0f MHz max efficiency\n", |
682 | ratio, bclk, ratio * bclk); | 750 | ratio, bclk, ratio * bclk); |
@@ -685,14 +753,84 @@ void print_verbose_header(void) | |||
685 | fprintf(stderr, "%d * %.0f = %.0f MHz TSC frequency\n", | 753 | fprintf(stderr, "%d * %.0f = %.0f MHz TSC frequency\n", |
686 | ratio, bclk, ratio * bclk); | 754 | ratio, bclk, ratio * bclk); |
687 | 755 | ||
756 | if (!do_ivt_turbo_ratio_limit) | ||
757 | goto print_nhm_turbo_ratio_limits; | ||
758 | |||
759 | get_msr(0, MSR_IVT_TURBO_RATIO_LIMIT, &msr); | ||
760 | |||
688 | if (verbose > 1) | 761 | if (verbose > 1) |
689 | fprintf(stderr, "MSR_NEHALEM_PLATFORM_INFO: 0x%llx\n", msr); | 762 | fprintf(stderr, "MSR_IVT_TURBO_RATIO_LIMIT: 0x%llx\n", msr); |
763 | |||
764 | ratio = (msr >> 56) & 0xFF; | ||
765 | if (ratio) | ||
766 | fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 16 active cores\n", | ||
767 | ratio, bclk, ratio * bclk); | ||
768 | |||
769 | ratio = (msr >> 48) & 0xFF; | ||
770 | if (ratio) | ||
771 | fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 15 active cores\n", | ||
772 | ratio, bclk, ratio * bclk); | ||
773 | |||
774 | ratio = (msr >> 40) & 0xFF; | ||
775 | if (ratio) | ||
776 | fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 14 active cores\n", | ||
777 | ratio, bclk, ratio * bclk); | ||
778 | |||
779 | ratio = (msr >> 32) & 0xFF; | ||
780 | if (ratio) | ||
781 | fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 13 active cores\n", | ||
782 | ratio, bclk, ratio * bclk); | ||
783 | |||
784 | ratio = (msr >> 24) & 0xFF; | ||
785 | if (ratio) | ||
786 | fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 12 active cores\n", | ||
787 | ratio, bclk, ratio * bclk); | ||
788 | |||
789 | ratio = (msr >> 16) & 0xFF; | ||
790 | if (ratio) | ||
791 | fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 11 active cores\n", | ||
792 | ratio, bclk, ratio * bclk); | ||
793 | |||
794 | ratio = (msr >> 8) & 0xFF; | ||
795 | if (ratio) | ||
796 | fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 10 active cores\n", | ||
797 | ratio, bclk, ratio * bclk); | ||
798 | |||
799 | ratio = (msr >> 0) & 0xFF; | ||
800 | if (ratio) | ||
801 | fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 9 active cores\n", | ||
802 | ratio, bclk, ratio * bclk); | ||
803 | |||
804 | print_nhm_turbo_ratio_limits: | ||
690 | 805 | ||
691 | if (!do_nehalem_turbo_ratio_limit) | 806 | if (!do_nehalem_turbo_ratio_limit) |
692 | return; | 807 | return; |
693 | 808 | ||
694 | get_msr(0, MSR_NEHALEM_TURBO_RATIO_LIMIT, &msr); | 809 | get_msr(0, MSR_NEHALEM_TURBO_RATIO_LIMIT, &msr); |
695 | 810 | ||
811 | if (verbose > 1) | ||
812 | fprintf(stderr, "MSR_NEHALEM_TURBO_RATIO_LIMIT: 0x%llx\n", msr); | ||
813 | |||
814 | ratio = (msr >> 56) & 0xFF; | ||
815 | if (ratio) | ||
816 | fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 8 active cores\n", | ||
817 | ratio, bclk, ratio * bclk); | ||
818 | |||
819 | ratio = (msr >> 48) & 0xFF; | ||
820 | if (ratio) | ||
821 | fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 7 active cores\n", | ||
822 | ratio, bclk, ratio * bclk); | ||
823 | |||
824 | ratio = (msr >> 40) & 0xFF; | ||
825 | if (ratio) | ||
826 | fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 6 active cores\n", | ||
827 | ratio, bclk, ratio * bclk); | ||
828 | |||
829 | ratio = (msr >> 32) & 0xFF; | ||
830 | if (ratio) | ||
831 | fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 5 active cores\n", | ||
832 | ratio, bclk, ratio * bclk); | ||
833 | |||
696 | ratio = (msr >> 24) & 0xFF; | 834 | ratio = (msr >> 24) & 0xFF; |
697 | if (ratio) | 835 | if (ratio) |
698 | fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 4 active cores\n", | 836 | fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 4 active cores\n", |
@@ -712,7 +850,6 @@ void print_verbose_header(void) | |||
712 | if (ratio) | 850 | if (ratio) |
713 | fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 1 active cores\n", | 851 | fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 1 active cores\n", |
714 | ratio, bclk, ratio * bclk); | 852 | ratio, bclk, ratio * bclk); |
715 | |||
716 | } | 853 | } |
717 | 854 | ||
718 | void free_all_buffers(void) | 855 | void free_all_buffers(void) |
@@ -1038,7 +1175,7 @@ int has_nehalem_turbo_ratio_limit(unsigned int family, unsigned int model) | |||
1038 | case 0x2A: /* SNB */ | 1175 | case 0x2A: /* SNB */ |
1039 | case 0x2D: /* SNB Xeon */ | 1176 | case 0x2D: /* SNB Xeon */ |
1040 | case 0x3A: /* IVB */ | 1177 | case 0x3A: /* IVB */ |
1041 | case 0x3D: /* IVB Xeon */ | 1178 | case 0x3E: /* IVB Xeon */ |
1042 | return 1; | 1179 | return 1; |
1043 | case 0x2E: /* Nehalem-EX Xeon - Beckton */ | 1180 | case 0x2E: /* Nehalem-EX Xeon - Beckton */ |
1044 | case 0x2F: /* Westmere-EX Xeon - Eagleton */ | 1181 | case 0x2F: /* Westmere-EX Xeon - Eagleton */ |
@@ -1046,6 +1183,22 @@ int has_nehalem_turbo_ratio_limit(unsigned int family, unsigned int model) | |||
1046 | return 0; | 1183 | return 0; |
1047 | } | 1184 | } |
1048 | } | 1185 | } |
1186 | int has_ivt_turbo_ratio_limit(unsigned int family, unsigned int model) | ||
1187 | { | ||
1188 | if (!genuine_intel) | ||
1189 | return 0; | ||
1190 | |||
1191 | if (family != 6) | ||
1192 | return 0; | ||
1193 | |||
1194 | switch (model) { | ||
1195 | case 0x3E: /* IVB Xeon */ | ||
1196 | return 1; | ||
1197 | default: | ||
1198 | return 0; | ||
1199 | } | ||
1200 | } | ||
1201 | |||
1049 | 1202 | ||
1050 | int is_snb(unsigned int family, unsigned int model) | 1203 | int is_snb(unsigned int family, unsigned int model) |
1051 | { | 1204 | { |
@@ -1056,7 +1209,7 @@ int is_snb(unsigned int family, unsigned int model) | |||
1056 | case 0x2A: | 1209 | case 0x2A: |
1057 | case 0x2D: | 1210 | case 0x2D: |
1058 | case 0x3A: /* IVB */ | 1211 | case 0x3A: /* IVB */ |
1059 | case 0x3D: /* IVB Xeon */ | 1212 | case 0x3E: /* IVB Xeon */ |
1060 | return 1; | 1213 | return 1; |
1061 | } | 1214 | } |
1062 | return 0; | 1215 | return 0; |
@@ -1145,12 +1298,13 @@ void check_cpuid() | |||
1145 | bclk = discover_bclk(family, model); | 1298 | bclk = discover_bclk(family, model); |
1146 | 1299 | ||
1147 | do_nehalem_turbo_ratio_limit = has_nehalem_turbo_ratio_limit(family, model); | 1300 | do_nehalem_turbo_ratio_limit = has_nehalem_turbo_ratio_limit(family, model); |
1301 | do_ivt_turbo_ratio_limit = has_ivt_turbo_ratio_limit(family, model); | ||
1148 | } | 1302 | } |
1149 | 1303 | ||
1150 | 1304 | ||
1151 | void usage() | 1305 | void usage() |
1152 | { | 1306 | { |
1153 | fprintf(stderr, "%s: [-v] [-M MSR#] [-i interval_sec | command ...]\n", | 1307 | fprintf(stderr, "%s: [-v][-p|-P|-S][-c MSR# | -s]][-C MSR#][-m MSR#][-M MSR#][-i interval_sec | command ...]\n", |
1154 | progname); | 1308 | progname); |
1155 | exit(1); | 1309 | exit(1); |
1156 | } | 1310 | } |
@@ -1440,15 +1594,15 @@ void cmdline(int argc, char **argv) | |||
1440 | 1594 | ||
1441 | progname = argv[0]; | 1595 | progname = argv[0]; |
1442 | 1596 | ||
1443 | while ((opt = getopt(argc, argv, "+cpsvi:M:")) != -1) { | 1597 | while ((opt = getopt(argc, argv, "+pPSvisc:sC:m:M:")) != -1) { |
1444 | switch (opt) { | 1598 | switch (opt) { |
1445 | case 'c': | 1599 | case 'p': |
1446 | show_core_only++; | 1600 | show_core_only++; |
1447 | break; | 1601 | break; |
1448 | case 'p': | 1602 | case 'P': |
1449 | show_pkg_only++; | 1603 | show_pkg_only++; |
1450 | break; | 1604 | break; |
1451 | case 's': | 1605 | case 'S': |
1452 | summary_only++; | 1606 | summary_only++; |
1453 | break; | 1607 | break; |
1454 | case 'v': | 1608 | case 'v': |
@@ -1457,10 +1611,20 @@ void cmdline(int argc, char **argv) | |||
1457 | case 'i': | 1611 | case 'i': |
1458 | interval_sec = atoi(optarg); | 1612 | interval_sec = atoi(optarg); |
1459 | break; | 1613 | break; |
1614 | case 'c': | ||
1615 | sscanf(optarg, "%x", &extra_delta_offset32); | ||
1616 | break; | ||
1617 | case 's': | ||
1618 | extra_delta_offset32 = 0x34; /* SMI counter */ | ||
1619 | break; | ||
1620 | case 'C': | ||
1621 | sscanf(optarg, "%x", &extra_delta_offset64); | ||
1622 | break; | ||
1623 | case 'm': | ||
1624 | sscanf(optarg, "%x", &extra_msr_offset32); | ||
1625 | break; | ||
1460 | case 'M': | 1626 | case 'M': |
1461 | sscanf(optarg, "%x", &extra_msr_offset); | 1627 | sscanf(optarg, "%x", &extra_msr_offset64); |
1462 | if (verbose > 1) | ||
1463 | fprintf(stderr, "MSR 0x%X\n", extra_msr_offset); | ||
1464 | break; | 1628 | break; |
1465 | default: | 1629 | default: |
1466 | usage(); | 1630 | usage(); |
@@ -1473,7 +1637,7 @@ int main(int argc, char **argv) | |||
1473 | cmdline(argc, argv); | 1637 | cmdline(argc, argv); |
1474 | 1638 | ||
1475 | if (verbose > 1) | 1639 | if (verbose > 1) |
1476 | fprintf(stderr, "turbostat v2.0 May 16, 2012" | 1640 | fprintf(stderr, "turbostat v2.1 October 6, 2012" |
1477 | " - Len Brown <lenb@kernel.org>\n"); | 1641 | " - Len Brown <lenb@kernel.org>\n"); |
1478 | 1642 | ||
1479 | turbostat_init(); | 1643 | turbostat_init(); |