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() ...
This commit is contained in:
commit
d8dc91b753
51 changed files with 2071 additions and 735 deletions
17
Documentation/ABI/testing/sysfs-devices-firmware_node
Normal file
17
Documentation/ABI/testing/sysfs-devices-firmware_node
Normal file
|
@ -0,0 +1,17 @@
|
|||
What: /sys/devices/.../firmware_node/
|
||||
Date: September 2012
|
||||
Contact: <>
|
||||
Description:
|
||||
The /sys/devices/.../firmware_node directory contains attributes
|
||||
allowing the user space to check and modify some firmware
|
||||
related properties of given device.
|
||||
|
||||
What: /sys/devices/.../firmware_node/description
|
||||
Date: September 2012
|
||||
Contact: Lance Ortiz <lance.ortiz@hp.com>
|
||||
Description:
|
||||
The /sys/devices/.../firmware/description attribute contains a string
|
||||
that describes the device as provided by the _STR method in the ACPI
|
||||
namespace. This attribute is read-only. If the device does not have
|
||||
an _STR method associated with it in the ACPI namespace, this
|
||||
attribute is not present.
|
|
@ -158,5 +158,6 @@ acpi-y += \
|
|||
utresrc.o \
|
||||
utstate.o \
|
||||
utxface.o \
|
||||
utxfinit.o \
|
||||
utxferror.o \
|
||||
utxfmutex.o
|
||||
|
|
|
@ -110,8 +110,7 @@ acpi_status acpi_hw_write_port(acpi_io_address address, u32 value, u32 width);
|
|||
/*
|
||||
* hwgpe - GPE support
|
||||
*/
|
||||
u32 acpi_hw_get_gpe_register_bit(struct acpi_gpe_event_info *gpe_event_info,
|
||||
struct acpi_gpe_register_info *gpe_register_info);
|
||||
u32 acpi_hw_get_gpe_register_bit(struct acpi_gpe_event_info *gpe_event_info);
|
||||
|
||||
acpi_status
|
||||
acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u32 action);
|
||||
|
|
|
@ -707,15 +707,18 @@ union acpi_parse_value {
|
|||
u8 disasm_opcode; /* Subtype used for disassembly */\
|
||||
char aml_op_name[16]) /* Op name (debug only) */
|
||||
|
||||
#define ACPI_DASM_BUFFER 0x00
|
||||
#define ACPI_DASM_RESOURCE 0x01
|
||||
#define ACPI_DASM_STRING 0x02
|
||||
#define ACPI_DASM_UNICODE 0x03
|
||||
#define ACPI_DASM_EISAID 0x04
|
||||
#define ACPI_DASM_MATCHOP 0x05
|
||||
#define ACPI_DASM_LNOT_PREFIX 0x06
|
||||
#define ACPI_DASM_LNOT_SUFFIX 0x07
|
||||
#define ACPI_DASM_IGNORE 0x08
|
||||
/* Flags for disasm_flags field above */
|
||||
|
||||
#define ACPI_DASM_BUFFER 0x00 /* Buffer is a simple data buffer */
|
||||
#define ACPI_DASM_RESOURCE 0x01 /* Buffer is a Resource Descriptor */
|
||||
#define ACPI_DASM_STRING 0x02 /* Buffer is a ASCII string */
|
||||
#define ACPI_DASM_UNICODE 0x03 /* Buffer is a Unicode string */
|
||||
#define ACPI_DASM_PLD_METHOD 0x04 /* Buffer is a _PLD method bit-packed buffer */
|
||||
#define ACPI_DASM_EISAID 0x05 /* Integer is an EISAID */
|
||||
#define ACPI_DASM_MATCHOP 0x06 /* Parent opcode is a Match() operator */
|
||||
#define ACPI_DASM_LNOT_PREFIX 0x07 /* Start of a Lnot_equal (etc.) pair of opcodes */
|
||||
#define ACPI_DASM_LNOT_SUFFIX 0x08 /* End of a Lnot_equal (etc.) pair of opcodes */
|
||||
#define ACPI_DASM_IGNORE 0x09 /* Not used at this time */
|
||||
|
||||
/*
|
||||
* Generic operation (for example: If, While, Store)
|
||||
|
@ -932,6 +935,7 @@ struct acpi_bit_register_info {
|
|||
#define ACPI_OSI_WIN_VISTA_SP1 0x09
|
||||
#define ACPI_OSI_WIN_VISTA_SP2 0x0A
|
||||
#define ACPI_OSI_WIN_7 0x0B
|
||||
#define ACPI_OSI_WIN_8 0x0C
|
||||
|
||||
#define ACPI_ALWAYS_ILLEGAL 0x00
|
||||
|
||||
|
@ -1024,6 +1028,7 @@ struct acpi_port_info {
|
|||
****************************************************************************/
|
||||
|
||||
struct acpi_db_method_info {
|
||||
acpi_handle method;
|
||||
acpi_handle main_thread_gate;
|
||||
acpi_handle thread_complete_gate;
|
||||
acpi_thread_id *threads;
|
||||
|
|
|
@ -277,10 +277,33 @@
|
|||
|
||||
/* Bitfields within ACPI registers */
|
||||
|
||||
#define ACPI_REGISTER_PREPARE_BITS(val, pos, mask) ((val << pos) & mask)
|
||||
#define ACPI_REGISTER_INSERT_VALUE(reg, pos, mask, val) reg = (reg & (~(mask))) | ACPI_REGISTER_PREPARE_BITS(val, pos, mask)
|
||||
#define ACPI_REGISTER_PREPARE_BITS(val, pos, mask) \
|
||||
((val << pos) & mask)
|
||||
|
||||
#define ACPI_INSERT_BITS(target, mask, source) target = ((target & (~(mask))) | (source & mask))
|
||||
#define ACPI_REGISTER_INSERT_VALUE(reg, pos, mask, val) \
|
||||
reg = (reg & (~(mask))) | ACPI_REGISTER_PREPARE_BITS(val, pos, mask)
|
||||
|
||||
#define ACPI_INSERT_BITS(target, mask, source) \
|
||||
target = ((target & (~(mask))) | (source & mask))
|
||||
|
||||
/* Generic bitfield macros and masks */
|
||||
|
||||
#define ACPI_GET_BITS(source_ptr, position, mask) \
|
||||
((*source_ptr >> position) & mask)
|
||||
|
||||
#define ACPI_SET_BITS(target_ptr, position, mask, value) \
|
||||
(*target_ptr |= ((value & mask) << position))
|
||||
|
||||
#define ACPI_1BIT_MASK 0x00000001
|
||||
#define ACPI_2BIT_MASK 0x00000003
|
||||
#define ACPI_3BIT_MASK 0x00000007
|
||||
#define ACPI_4BIT_MASK 0x0000000F
|
||||
#define ACPI_5BIT_MASK 0x0000001F
|
||||
#define ACPI_6BIT_MASK 0x0000003F
|
||||
#define ACPI_7BIT_MASK 0x0000007F
|
||||
#define ACPI_8BIT_MASK 0x000000FF
|
||||
#define ACPI_16BIT_MASK 0x0000FFFF
|
||||
#define ACPI_24BIT_MASK 0x00FFFFFF
|
||||
|
||||
/*
|
||||
* An object of type struct acpi_namespace_node can appear in some contexts
|
||||
|
|
|
@ -230,6 +230,20 @@ acpi_ds_load1_begin_op(struct acpi_walk_state * walk_state,
|
|||
walk_state->scope_info->common.value = ACPI_TYPE_ANY;
|
||||
break;
|
||||
|
||||
case ACPI_TYPE_METHOD:
|
||||
|
||||
/*
|
||||
* Allow scope change to root during execution of module-level
|
||||
* code. Root is typed METHOD during this time.
|
||||
*/
|
||||
if ((node == acpi_gbl_root_node) &&
|
||||
(walk_state->
|
||||
parse_flags & ACPI_PARSE_MODULE_LEVEL)) {
|
||||
break;
|
||||
}
|
||||
|
||||
/*lint -fallthrough */
|
||||
|
||||
default:
|
||||
|
||||
/* All other types are an error */
|
||||
|
|
|
@ -230,6 +230,20 @@ acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state,
|
|||
walk_state->scope_info->common.value = ACPI_TYPE_ANY;
|
||||
break;
|
||||
|
||||
case ACPI_TYPE_METHOD:
|
||||
|
||||
/*
|
||||
* Allow scope change to root during execution of module-level
|
||||
* code. Root is typed METHOD during this time.
|
||||
*/
|
||||
if ((node == acpi_gbl_root_node) &&
|
||||
(walk_state->
|
||||
parse_flags & ACPI_PARSE_MODULE_LEVEL)) {
|
||||
break;
|
||||
}
|
||||
|
||||
/*lint -fallthrough */
|
||||
|
||||
default:
|
||||
|
||||
/* All other types are an error */
|
||||
|
|
|
@ -80,8 +80,7 @@ acpi_ev_update_gpe_enable_mask(struct acpi_gpe_event_info *gpe_event_info)
|
|||
return_ACPI_STATUS(AE_NOT_EXIST);
|
||||
}
|
||||
|
||||
register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info,
|
||||
gpe_register_info);
|
||||
register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info);
|
||||
|
||||
/* Clear the run bit up front */
|
||||
|
||||
|
@ -379,6 +378,18 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list)
|
|||
*/
|
||||
if (!(gpe_register_info->enable_for_run |
|
||||
gpe_register_info->enable_for_wake)) {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INTERRUPTS,
|
||||
"Ignore disabled registers for GPE%02X-GPE%02X: "
|
||||
"RunEnable=%02X, WakeEnable=%02X\n",
|
||||
gpe_register_info->
|
||||
base_gpe_number,
|
||||
gpe_register_info->
|
||||
base_gpe_number +
|
||||
(ACPI_GPE_REGISTER_WIDTH - 1),
|
||||
gpe_register_info->
|
||||
enable_for_run,
|
||||
gpe_register_info->
|
||||
enable_for_wake));
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -401,9 +412,14 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list)
|
|||
}
|
||||
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INTERRUPTS,
|
||||
"Read GPE Register at GPE%02X: Status=%02X, Enable=%02X\n",
|
||||
"Read registers for GPE%02X-GPE%02X: Status=%02X, Enable=%02X, "
|
||||
"RunEnable=%02X, WakeEnable=%02X\n",
|
||||
gpe_register_info->base_gpe_number,
|
||||
status_reg, enable_reg));
|
||||
gpe_register_info->base_gpe_number +
|
||||
(ACPI_GPE_REGISTER_WIDTH - 1),
|
||||
status_reg, enable_reg,
|
||||
gpe_register_info->enable_for_run,
|
||||
gpe_register_info->enable_for_wake));
|
||||
|
||||
/* Check if there is anything active at all in this register */
|
||||
|
||||
|
|
|
@ -357,8 +357,7 @@ acpi_status acpi_set_gpe_wake_mask(acpi_handle gpe_device, u32 gpe_number, u8 ac
|
|||
goto unlock_and_exit;
|
||||
}
|
||||
|
||||
register_bit =
|
||||
acpi_hw_get_gpe_register_bit(gpe_event_info, gpe_register_info);
|
||||
register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info);
|
||||
|
||||
/* Perform the action */
|
||||
|
||||
|
|
|
@ -60,7 +60,6 @@ acpi_hw_enable_wakeup_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
|
|||
* FUNCTION: acpi_hw_get_gpe_register_bit
|
||||
*
|
||||
* PARAMETERS: gpe_event_info - Info block for the GPE
|
||||
* gpe_register_info - Info block for the GPE register
|
||||
*
|
||||
* RETURN: Register mask with a one in the GPE bit position
|
||||
*
|
||||
|
@ -69,11 +68,10 @@ acpi_hw_enable_wakeup_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
|
|||
*
|
||||
******************************************************************************/
|
||||
|
||||
u32 acpi_hw_get_gpe_register_bit(struct acpi_gpe_event_info *gpe_event_info,
|
||||
struct acpi_gpe_register_info *gpe_register_info)
|
||||
u32 acpi_hw_get_gpe_register_bit(struct acpi_gpe_event_info *gpe_event_info)
|
||||
{
|
||||
return (u32)1 << (gpe_event_info->gpe_number -
|
||||
gpe_register_info->base_gpe_number);
|
||||
gpe_event_info->register_info->base_gpe_number);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
|
@ -115,8 +113,7 @@ acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u32 action)
|
|||
|
||||
/* Set or clear just the bit that corresponds to this GPE */
|
||||
|
||||
register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info,
|
||||
gpe_register_info);
|
||||
register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info);
|
||||
switch (action) {
|
||||
case ACPI_GPE_CONDITIONAL_ENABLE:
|
||||
|
||||
|
@ -178,8 +175,7 @@ acpi_status acpi_hw_clear_gpe(struct acpi_gpe_event_info * gpe_event_info)
|
|||
* Write a one to the appropriate bit in the status register to
|
||||
* clear this GPE.
|
||||
*/
|
||||
register_bit =
|
||||
acpi_hw_get_gpe_register_bit(gpe_event_info, gpe_register_info);
|
||||
register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info);
|
||||
|
||||
status = acpi_hw_write(register_bit,
|
||||
&gpe_register_info->status_address);
|
||||
|
@ -222,8 +218,7 @@ acpi_hw_get_gpe_status(struct acpi_gpe_event_info * gpe_event_info,
|
|||
|
||||
/* Get the register bitmask for this GPE */
|
||||
|
||||
register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info,
|
||||
gpe_register_info);
|
||||
register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info);
|
||||
|
||||
/* GPE currently enabled? (enabled for runtime?) */
|
||||
|
||||
|
|
|
@ -381,7 +381,6 @@ ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state)
|
|||
* FUNCTION: acpi_leave_sleep_state_prep
|
||||
*
|
||||
* PARAMETERS: sleep_state - Which sleep state we are exiting
|
||||
* flags - ACPI_EXECUTE_BFS to run optional method
|
||||
*
|
||||
* RETURN: Status
|
||||
*
|
||||
|
|
|
@ -264,7 +264,7 @@ acpi_ns_dump_one_object(acpi_handle obj_handle,
|
|||
switch (type) {
|
||||
case ACPI_TYPE_PROCESSOR:
|
||||
|
||||
acpi_os_printf("ID %X Len %.4X Addr %p\n",
|
||||
acpi_os_printf("ID %02X Len %02X Addr %p\n",
|
||||
obj_desc->processor.proc_id,
|
||||
obj_desc->processor.length,
|
||||
ACPI_CAST_PTR(void,
|
||||
|
|
|
@ -350,6 +350,7 @@ struct acpi_table_header *acpi_tb_table_override(struct acpi_table_header
|
|||
acpi_status acpi_tb_resize_root_table_list(void)
|
||||
{
|
||||
struct acpi_table_desc *tables;
|
||||
u32 table_count;
|
||||
|
||||
ACPI_FUNCTION_TRACE(tb_resize_root_table_list);
|
||||
|
||||
|
@ -363,8 +364,13 @@ acpi_status acpi_tb_resize_root_table_list(void)
|
|||
|
||||
/* Increase the Table Array size */
|
||||
|
||||
tables = ACPI_ALLOCATE_ZEROED(((acpi_size) acpi_gbl_root_table_list.
|
||||
max_table_count +
|
||||
if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) {
|
||||
table_count = acpi_gbl_root_table_list.max_table_count;
|
||||
} else {
|
||||
table_count = acpi_gbl_root_table_list.current_table_count;
|
||||
}
|
||||
|
||||
tables = ACPI_ALLOCATE_ZEROED(((acpi_size) table_count +
|
||||
ACPI_ROOT_TABLE_SIZE_INCREMENT) *
|
||||
sizeof(struct acpi_table_desc));
|
||||
if (!tables) {
|
||||
|
@ -377,8 +383,8 @@ acpi_status acpi_tb_resize_root_table_list(void)
|
|||
|
||||
if (acpi_gbl_root_table_list.tables) {
|
||||
ACPI_MEMCPY(tables, acpi_gbl_root_table_list.tables,
|
||||
(acpi_size) acpi_gbl_root_table_list.
|
||||
max_table_count * sizeof(struct acpi_table_desc));
|
||||
(acpi_size) table_count *
|
||||
sizeof(struct acpi_table_desc));
|
||||
|
||||
if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) {
|
||||
ACPI_FREE(acpi_gbl_root_table_list.tables);
|
||||
|
@ -386,9 +392,9 @@ acpi_status acpi_tb_resize_root_table_list(void)
|
|||
}
|
||||
|
||||
acpi_gbl_root_table_list.tables = tables;
|
||||
acpi_gbl_root_table_list.max_table_count +=
|
||||
ACPI_ROOT_TABLE_SIZE_INCREMENT;
|
||||
acpi_gbl_root_table_list.flags |= (u8)ACPI_ROOT_ORIGIN_ALLOCATED;
|
||||
acpi_gbl_root_table_list.max_table_count =
|
||||
table_count + ACPI_ROOT_TABLE_SIZE_INCREMENT;
|
||||
acpi_gbl_root_table_list.flags |= ACPI_ROOT_ORIGIN_ALLOCATED;
|
||||
|
||||
return_ACPI_STATUS(AE_OK);
|
||||
}
|
||||
|
|
|
@ -159,14 +159,12 @@ acpi_initialize_tables(struct acpi_table_desc * initial_table_array,
|
|||
* DESCRIPTION: Reallocate Root Table List into dynamic memory. Copies the
|
||||
* root list from the previously provided scratch area. Should
|
||||
* be called once dynamic memory allocation is available in the
|
||||
* kernel
|
||||
* kernel.
|
||||
*
|
||||
******************************************************************************/
|
||||
acpi_status acpi_reallocate_root_table(void)
|
||||
{
|
||||
struct acpi_table_desc *tables;
|
||||
acpi_size new_size;
|
||||
acpi_size current_size;
|
||||
acpi_status status;
|
||||
|
||||
ACPI_FUNCTION_TRACE(acpi_reallocate_root_table);
|
||||
|
||||
|
@ -178,39 +176,10 @@ acpi_status acpi_reallocate_root_table(void)
|
|||
return_ACPI_STATUS(AE_SUPPORT);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the current size of the root table and add the default
|
||||
* increment to create the new table size.
|
||||
*/
|
||||
current_size = (acpi_size)
|
||||
acpi_gbl_root_table_list.current_table_count *
|
||||
sizeof(struct acpi_table_desc);
|
||||
acpi_gbl_root_table_list.flags |= ACPI_ROOT_ALLOW_RESIZE;
|
||||
|
||||
new_size = current_size +
|
||||
(ACPI_ROOT_TABLE_SIZE_INCREMENT * sizeof(struct acpi_table_desc));
|
||||
|
||||
/* Create new array and copy the old array */
|
||||
|
||||
tables = ACPI_ALLOCATE_ZEROED(new_size);
|
||||
if (!tables) {
|
||||
return_ACPI_STATUS(AE_NO_MEMORY);
|
||||
}
|
||||
|
||||
ACPI_MEMCPY(tables, acpi_gbl_root_table_list.tables, current_size);
|
||||
|
||||
/*
|
||||
* Update the root table descriptor. The new size will be the current
|
||||
* number of tables plus the increment, independent of the reserved
|
||||
* size of the original table list.
|
||||
*/
|
||||
acpi_gbl_root_table_list.tables = tables;
|
||||
acpi_gbl_root_table_list.max_table_count =
|
||||
acpi_gbl_root_table_list.current_table_count +
|
||||
ACPI_ROOT_TABLE_SIZE_INCREMENT;
|
||||
acpi_gbl_root_table_list.flags =
|
||||
ACPI_ROOT_ORIGIN_ALLOCATED | ACPI_ROOT_ALLOW_RESIZE;
|
||||
|
||||
return_ACPI_STATUS(AE_OK);
|
||||
status = acpi_tb_resize_root_table_list();
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
|
|
|
@ -73,6 +73,7 @@ static struct acpi_interface_info acpi_default_supported_interfaces[] = {
|
|||
{"Windows 2006 SP1", NULL, 0, ACPI_OSI_WIN_VISTA_SP1}, /* Windows Vista SP1 - Added 09/2009 */
|
||||
{"Windows 2006 SP2", NULL, 0, ACPI_OSI_WIN_VISTA_SP2}, /* Windows Vista SP2 - Added 09/2010 */
|
||||
{"Windows 2009", NULL, 0, ACPI_OSI_WIN_7}, /* Windows 7 and Server 2008 R2 - Added 09/2009 */
|
||||
{"Windows 2012", NULL, 0, ACPI_OSI_WIN_8}, /* Windows 8 and Server 2012 - Added 08/2012 */
|
||||
|
||||
/* Feature Group Strings */
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Module Name: utxface - External interfaces for "global" ACPI functions
|
||||
* Module Name: utxface - External interfaces, miscellaneous utility functions
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
|
@ -53,271 +53,6 @@
|
|||
#define _COMPONENT ACPI_UTILITIES
|
||||
ACPI_MODULE_NAME("utxface")
|
||||
|
||||
#ifndef ACPI_ASL_COMPILER
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_initialize_subsystem
|
||||
*
|
||||
* PARAMETERS: None
|
||||
*
|
||||
* RETURN: Status
|
||||
*
|
||||
* DESCRIPTION: Initializes all global variables. This is the first function
|
||||
* called, so any early initialization belongs here.
|
||||
*
|
||||
******************************************************************************/
|
||||
acpi_status __init acpi_initialize_subsystem(void)
|
||||
{
|
||||
acpi_status status;
|
||||
|
||||
ACPI_FUNCTION_TRACE(acpi_initialize_subsystem);
|
||||
|
||||
acpi_gbl_startup_flags = ACPI_SUBSYSTEM_INITIALIZE;
|
||||
ACPI_DEBUG_EXEC(acpi_ut_init_stack_ptr_trace());
|
||||
|
||||
/* Initialize the OS-Dependent layer */
|
||||
|
||||
status = acpi_os_initialize();
|
||||
if (ACPI_FAILURE(status)) {
|
||||
ACPI_EXCEPTION((AE_INFO, status, "During OSL initialization"));
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
/* Initialize all globals used by the subsystem */
|
||||
|
||||
status = acpi_ut_init_globals();
|
||||
if (ACPI_FAILURE(status)) {
|
||||
ACPI_EXCEPTION((AE_INFO, status,
|
||||
"During initialization of globals"));
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
/* Create the default mutex objects */
|
||||
|
||||
status = acpi_ut_mutex_initialize();
|
||||
if (ACPI_FAILURE(status)) {
|
||||
ACPI_EXCEPTION((AE_INFO, status,
|
||||
"During Global Mutex creation"));
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the namespace manager and
|
||||
* the root of the namespace tree
|
||||
*/
|
||||
status = acpi_ns_root_initialize();
|
||||
if (ACPI_FAILURE(status)) {
|
||||
ACPI_EXCEPTION((AE_INFO, status,
|
||||
"During Namespace initialization"));
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
/* Initialize the global OSI interfaces list with the static names */
|
||||
|
||||
status = acpi_ut_initialize_interfaces();
|
||||
if (ACPI_FAILURE(status)) {
|
||||
ACPI_EXCEPTION((AE_INFO, status,
|
||||
"During OSI interfaces initialization"));
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
/* If configured, initialize the AML debugger */
|
||||
|
||||
ACPI_DEBUGGER_EXEC(status = acpi_db_initialize());
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_enable_subsystem
|
||||
*
|
||||
* PARAMETERS: flags - Init/enable Options
|
||||
*
|
||||
* RETURN: Status
|
||||
*
|
||||
* DESCRIPTION: Completes the subsystem initialization including hardware.
|
||||
* Puts system into ACPI mode if it isn't already.
|
||||
*
|
||||
******************************************************************************/
|
||||
acpi_status acpi_enable_subsystem(u32 flags)
|
||||
{
|
||||
acpi_status status = AE_OK;
|
||||
|
||||
ACPI_FUNCTION_TRACE(acpi_enable_subsystem);
|
||||
|
||||
#if (!ACPI_REDUCED_HARDWARE)
|
||||
|
||||
/* Enable ACPI mode */
|
||||
|
||||
if (!(flags & ACPI_NO_ACPI_ENABLE)) {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
|
||||
"[Init] Going into ACPI mode\n"));
|
||||
|
||||
acpi_gbl_original_mode = acpi_hw_get_mode();
|
||||
|
||||
status = acpi_enable();
|
||||
if (ACPI_FAILURE(status)) {
|
||||
ACPI_WARNING((AE_INFO, "AcpiEnable failed"));
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Obtain a permanent mapping for the FACS. This is required for the
|
||||
* Global Lock and the Firmware Waking Vector
|
||||
*/
|
||||
status = acpi_tb_initialize_facs();
|
||||
if (ACPI_FAILURE(status)) {
|
||||
ACPI_WARNING((AE_INFO, "Could not map the FACS table"));
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
#endif /* !ACPI_REDUCED_HARDWARE */
|
||||
|
||||
/*
|
||||
* Install the default op_region handlers. These are installed unless
|
||||
* other handlers have already been installed via the
|
||||
* install_address_space_handler interface.
|
||||
*/
|
||||
if (!(flags & ACPI_NO_ADDRESS_SPACE_INIT)) {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
|
||||
"[Init] Installing default address space handlers\n"));
|
||||
|
||||
status = acpi_ev_install_region_handlers();
|
||||
if (ACPI_FAILURE(status)) {
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
}
|
||||
#if (!ACPI_REDUCED_HARDWARE)
|
||||
/*
|
||||
* Initialize ACPI Event handling (Fixed and General Purpose)
|
||||
*
|
||||
* Note1: We must have the hardware and events initialized before we can
|
||||
* execute any control methods safely. Any control method can require
|
||||
* ACPI hardware support, so the hardware must be fully initialized before
|
||||
* any method execution!
|
||||
*
|
||||
* Note2: Fixed events are initialized and enabled here. GPEs are
|
||||
* initialized, but cannot be enabled until after the hardware is
|
||||
* completely initialized (SCI and global_lock activated)
|
||||
*/
|
||||
if (!(flags & ACPI_NO_EVENT_INIT)) {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
|
||||
"[Init] Initializing ACPI events\n"));
|
||||
|
||||
status = acpi_ev_initialize_events();
|
||||
if (ACPI_FAILURE(status)) {
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Install the SCI handler and Global Lock handler. This completes the
|
||||
* hardware initialization.
|
||||
*/
|
||||
if (!(flags & ACPI_NO_HANDLER_INIT)) {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
|
||||
"[Init] Installing SCI/GL handlers\n"));
|
||||
|
||||
status = acpi_ev_install_xrupt_handlers();
|
||||
if (ACPI_FAILURE(status)) {
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
}
|
||||
#endif /* !ACPI_REDUCED_HARDWARE */
|
||||
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
ACPI_EXPORT_SYMBOL(acpi_enable_subsystem)
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_initialize_objects
|
||||
*
|
||||
* PARAMETERS: flags - Init/enable Options
|
||||
*
|
||||
* RETURN: Status
|
||||
*
|
||||
* DESCRIPTION: Completes namespace initialization by initializing device
|
||||
* objects and executing AML code for Regions, buffers, etc.
|
||||
*
|
||||
******************************************************************************/
|
||||
acpi_status acpi_initialize_objects(u32 flags)
|
||||
{
|
||||
acpi_status status = AE_OK;
|
||||
|
||||
ACPI_FUNCTION_TRACE(acpi_initialize_objects);
|
||||
|
||||
/*
|
||||
* Run all _REG methods
|
||||
*
|
||||
* Note: Any objects accessed by the _REG methods will be automatically
|
||||
* initialized, even if they contain executable AML (see the call to
|
||||
* acpi_ns_initialize_objects below).
|
||||
*/
|
||||
if (!(flags & ACPI_NO_ADDRESS_SPACE_INIT)) {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
|
||||
"[Init] Executing _REG OpRegion methods\n"));
|
||||
|
||||
status = acpi_ev_initialize_op_regions();
|
||||
if (ACPI_FAILURE(status)) {
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Execute any module-level code that was detected during the table load
|
||||
* phase. Although illegal since ACPI 2.0, there are many machines that
|
||||
* contain this type of code. Each block of detected executable AML code
|
||||
* outside of any control method is wrapped with a temporary control
|
||||
* method object and placed on a global list. The methods on this list
|
||||
* are executed below.
|
||||
*/
|
||||
acpi_ns_exec_module_code_list();
|
||||
|
||||
/*
|
||||
* Initialize the objects that remain uninitialized. This runs the
|
||||
* executable AML that may be part of the declaration of these objects:
|
||||
* operation_regions, buffer_fields, Buffers, and Packages.
|
||||
*/
|
||||
if (!(flags & ACPI_NO_OBJECT_INIT)) {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
|
||||
"[Init] Completing Initialization of ACPI Objects\n"));
|
||||
|
||||
status = acpi_ns_initialize_objects();
|
||||
if (ACPI_FAILURE(status)) {
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize all device objects in the namespace. This runs the device
|
||||
* _STA and _INI methods.
|
||||
*/
|
||||
if (!(flags & ACPI_NO_DEVICE_INIT)) {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
|
||||
"[Init] Initializing ACPI Devices\n"));
|
||||
|
||||
status = acpi_ns_initialize_devices();
|
||||
if (ACPI_FAILURE(status)) {
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Empty the caches (delete the cached objects) on the assumption that
|
||||
* the table load filled them up more than they will be at runtime --
|
||||
* thus wasting non-paged memory.
|
||||
*/
|
||||
status = acpi_purge_cached_objects();
|
||||
|
||||
acpi_gbl_startup_flags |= ACPI_INITIALIZED_OK;
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
ACPI_EXPORT_SYMBOL(acpi_initialize_objects)
|
||||
|
||||
#endif
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_terminate
|
||||
|
@ -683,3 +418,90 @@ acpi_check_address_range(acpi_adr_space_type space_id,
|
|||
|
||||
ACPI_EXPORT_SYMBOL(acpi_check_address_range)
|
||||
#endif /* !ACPI_ASL_COMPILER */
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_decode_pld_buffer
|
||||
*
|
||||
* PARAMETERS: in_buffer - Buffer returned by _PLD method
|
||||
* length - Length of the in_buffer
|
||||
* return_buffer - Where the decode buffer is returned
|
||||
*
|
||||
* RETURN: Status and the decoded _PLD buffer. User must deallocate
|
||||
* the buffer via ACPI_FREE.
|
||||
*
|
||||
* DESCRIPTION: Decode the bit-packed buffer returned by the _PLD method into
|
||||
* a local struct that is much more useful to an ACPI driver.
|
||||
*
|
||||
******************************************************************************/
|
||||
acpi_status
|
||||
acpi_decode_pld_buffer(u8 *in_buffer,
|
||||
acpi_size length, struct acpi_pld_info ** return_buffer)
|
||||
{
|
||||
struct acpi_pld_info *pld_info;
|
||||
u32 *buffer = ACPI_CAST_PTR(u32, in_buffer);
|
||||
u32 dword;
|
||||
|
||||
/* Parameter validation */
|
||||
|
||||
if (!in_buffer || !return_buffer || (length < 16)) {
|
||||
return (AE_BAD_PARAMETER);
|
||||
}
|
||||
|
||||
pld_info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_pld_info));
|
||||
if (!pld_info) {
|
||||
return (AE_NO_MEMORY);
|
||||
}
|
||||
|
||||
/* First 32-bit DWord */
|
||||
|
||||
ACPI_MOVE_32_TO_32(&dword, &buffer[0]);
|
||||
pld_info->revision = ACPI_PLD_GET_REVISION(&dword);
|
||||
pld_info->ignore_color = ACPI_PLD_GET_IGNORE_COLOR(&dword);
|
||||
pld_info->color = ACPI_PLD_GET_COLOR(&dword);
|
||||
|
||||
/* Second 32-bit DWord */
|
||||
|
||||
ACPI_MOVE_32_TO_32(&dword, &buffer[1]);
|
||||
pld_info->width = ACPI_PLD_GET_WIDTH(&dword);
|
||||
pld_info->height = ACPI_PLD_GET_HEIGHT(&dword);
|
||||
|
||||
/* Third 32-bit DWord */
|
||||
|
||||
ACPI_MOVE_32_TO_32(&dword, &buffer[2]);
|
||||
pld_info->user_visible = ACPI_PLD_GET_USER_VISIBLE(&dword);
|
||||
pld_info->dock = ACPI_PLD_GET_DOCK(&dword);
|
||||
pld_info->lid = ACPI_PLD_GET_LID(&dword);
|
||||
pld_info->panel = ACPI_PLD_GET_PANEL(&dword);
|
||||
pld_info->vertical_position = ACPI_PLD_GET_VERTICAL(&dword);
|
||||
pld_info->horizontal_position = ACPI_PLD_GET_HORIZONTAL(&dword);
|
||||
pld_info->shape = ACPI_PLD_GET_SHAPE(&dword);
|
||||
pld_info->group_orientation = ACPI_PLD_GET_ORIENTATION(&dword);
|
||||
pld_info->group_token = ACPI_PLD_GET_TOKEN(&dword);
|
||||
pld_info->group_position = ACPI_PLD_GET_POSITION(&dword);
|
||||
pld_info->bay = ACPI_PLD_GET_BAY(&dword);
|
||||
|
||||
/* Fourth 32-bit DWord */
|
||||
|
||||
ACPI_MOVE_32_TO_32(&dword, &buffer[3]);
|
||||
pld_info->ejectable = ACPI_PLD_GET_EJECTABLE(&dword);
|
||||
pld_info->ospm_eject_required = ACPI_PLD_GET_OSPM_EJECT(&dword);
|
||||
pld_info->cabinet_number = ACPI_PLD_GET_CABINET(&dword);
|
||||
pld_info->card_cage_number = ACPI_PLD_GET_CARD_CAGE(&dword);
|
||||
pld_info->reference = ACPI_PLD_GET_REFERENCE(&dword);
|
||||
pld_info->rotation = ACPI_PLD_GET_ROTATION(&dword);
|
||||
pld_info->order = ACPI_PLD_GET_ORDER(&dword);
|
||||
|
||||
if (length >= ACPI_PLD_BUFFER_SIZE) {
|
||||
|
||||
/* Fifth 32-bit DWord (Revision 2 of _PLD) */
|
||||
|
||||
ACPI_MOVE_32_TO_32(&dword, &buffer[4]);
|
||||
pld_info->vertical_offset = ACPI_PLD_GET_VERT_OFFSET(&dword);
|
||||
pld_info->horizontal_offset = ACPI_PLD_GET_HORIZ_OFFSET(&dword);
|
||||
}
|
||||
|
||||
*return_buffer = pld_info;
|
||||
return (AE_OK);
|
||||
}
|
||||
|
||||
ACPI_EXPORT_SYMBOL(acpi_decode_pld_buffer)
|
||||
|
|
317
drivers/acpi/acpica/utxfinit.c
Normal file
317
drivers/acpi/acpica/utxfinit.c
Normal file
|
@ -0,0 +1,317 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Module Name: utxfinit - External interfaces for ACPICA initialization
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2000 - 2012, Intel Corp.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions, and the following disclaimer,
|
||||
* without modification.
|
||||
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
|
||||
* substantially similar to the "NO WARRANTY" disclaimer below
|
||||
* ("Disclaimer") and any redistribution must be conditioned upon
|
||||
* including a substantially similar Disclaimer requirement for further
|
||||
* binary redistribution.
|
||||
* 3. Neither the names of the above-listed copyright holders nor the names
|
||||
* of any contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* Alternatively, this software may be distributed under the terms of the
|
||||
* GNU General Public License ("GPL") version 2 as published by the Free
|
||||
* Software Foundation.
|
||||
*
|
||||
* NO WARRANTY
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGES.
|
||||
*/
|
||||
|
||||
#include <linux/export.h>
|
||||
#include <acpi/acpi.h>
|
||||
#include "accommon.h"
|
||||
#include "acevents.h"
|
||||
#include "acnamesp.h"
|
||||
#include "acdebug.h"
|
||||
#include "actables.h"
|
||||
|
||||
#define _COMPONENT ACPI_UTILITIES
|
||||
ACPI_MODULE_NAME("utxfinit")
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_initialize_subsystem
|
||||
*
|
||||
* PARAMETERS: None
|
||||
*
|
||||
* RETURN: Status
|
||||
*
|
||||
* DESCRIPTION: Initializes all global variables. This is the first function
|
||||
* called, so any early initialization belongs here.
|
||||
*
|
||||
******************************************************************************/
|
||||
acpi_status acpi_initialize_subsystem(void)
|
||||
{
|
||||
acpi_status status;
|
||||
|
||||
ACPI_FUNCTION_TRACE(acpi_initialize_subsystem);
|
||||
|
||||
acpi_gbl_startup_flags = ACPI_SUBSYSTEM_INITIALIZE;
|
||||
ACPI_DEBUG_EXEC(acpi_ut_init_stack_ptr_trace());
|
||||
|
||||
/* Initialize the OS-Dependent layer */
|
||||
|
||||
status = acpi_os_initialize();
|
||||
if (ACPI_FAILURE(status)) {
|
||||
ACPI_EXCEPTION((AE_INFO, status, "During OSL initialization"));
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
/* Initialize all globals used by the subsystem */
|
||||
|
||||
status = acpi_ut_init_globals();
|
||||
if (ACPI_FAILURE(status)) {
|
||||
ACPI_EXCEPTION((AE_INFO, status,
|
||||
"During initialization of globals"));
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
/* Create the default mutex objects */
|
||||
|
||||
status = acpi_ut_mutex_initialize();
|
||||
if (ACPI_FAILURE(status)) {
|
||||
ACPI_EXCEPTION((AE_INFO, status,
|
||||
"During Global Mutex creation"));
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the namespace manager and
|
||||
* the root of the namespace tree
|
||||
*/
|
||||
status = acpi_ns_root_initialize();
|
||||
if (ACPI_FAILURE(status)) {
|
||||
ACPI_EXCEPTION((AE_INFO, status,
|
||||
"During Namespace initialization"));
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
/* Initialize the global OSI interfaces list with the static names */
|
||||
|
||||
status = acpi_ut_initialize_interfaces();
|
||||
if (ACPI_FAILURE(status)) {
|
||||
ACPI_EXCEPTION((AE_INFO, status,
|
||||
"During OSI interfaces initialization"));
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
/* If configured, initialize the AML debugger */
|
||||
|
||||
ACPI_DEBUGGER_EXEC(status = acpi_db_initialize());
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
ACPI_EXPORT_SYMBOL(acpi_initialize_subsystem)
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_enable_subsystem
|
||||
*
|
||||
* PARAMETERS: flags - Init/enable Options
|
||||
*
|
||||
* RETURN: Status
|
||||
*
|
||||
* DESCRIPTION: Completes the subsystem initialization including hardware.
|
||||
* Puts system into ACPI mode if it isn't already.
|
||||
*
|
||||
******************************************************************************/
|
||||
acpi_status acpi_enable_subsystem(u32 flags)
|
||||
{
|
||||
acpi_status status = AE_OK;
|
||||
|
||||
ACPI_FUNCTION_TRACE(acpi_enable_subsystem);
|
||||
|
||||
#if (!ACPI_REDUCED_HARDWARE)
|
||||
|
||||
/* Enable ACPI mode */
|
||||
|
||||
if (!(flags & ACPI_NO_ACPI_ENABLE)) {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
|
||||
"[Init] Going into ACPI mode\n"));
|
||||
|
||||
acpi_gbl_original_mode = acpi_hw_get_mode();
|
||||
|
||||
status = acpi_enable();
|
||||
if (ACPI_FAILURE(status)) {
|
||||
ACPI_WARNING((AE_INFO, "AcpiEnable failed"));
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Obtain a permanent mapping for the FACS. This is required for the
|
||||
* Global Lock and the Firmware Waking Vector
|
||||
*/
|
||||
status = acpi_tb_initialize_facs();
|
||||
if (ACPI_FAILURE(status)) {
|
||||
ACPI_WARNING((AE_INFO, "Could not map the FACS table"));
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
#endif /* !ACPI_REDUCED_HARDWARE */
|
||||
|
||||
/*
|
||||
* Install the default op_region handlers. These are installed unless
|
||||
* other handlers have already been installed via the
|
||||
* install_address_space_handler interface.
|
||||
*/
|
||||
if (!(flags & ACPI_NO_ADDRESS_SPACE_INIT)) {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
|
||||
"[Init] Installing default address space handlers\n"));
|
||||
|
||||
status = acpi_ev_install_region_handlers();
|
||||
if (ACPI_FAILURE(status)) {
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
}
|
||||
#if (!ACPI_REDUCED_HARDWARE)
|
||||
/*
|
||||
* Initialize ACPI Event handling (Fixed and General Purpose)
|
||||
*
|
||||
* Note1: We must have the hardware and events initialized before we can
|
||||
* execute any control methods safely. Any control method can require
|
||||
* ACPI hardware support, so the hardware must be fully initialized before
|
||||
* any method execution!
|
||||
*
|
||||
* Note2: Fixed events are initialized and enabled here. GPEs are
|
||||
* initialized, but cannot be enabled until after the hardware is
|
||||
* completely initialized (SCI and global_lock activated) and the various
|
||||
* initialization control methods are run (_REG, _STA, _INI) on the
|
||||
* entire namespace.
|
||||
*/
|
||||
if (!(flags & ACPI_NO_EVENT_INIT)) {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
|
||||
"[Init] Initializing ACPI events\n"));
|
||||
|
||||
status = acpi_ev_initialize_events();
|
||||
if (ACPI_FAILURE(status)) {
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Install the SCI handler and Global Lock handler. This completes the
|
||||
* hardware initialization.
|
||||
*/
|
||||
if (!(flags & ACPI_NO_HANDLER_INIT)) {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
|
||||
"[Init] Installing SCI/GL handlers\n"));
|
||||
|
||||
status = acpi_ev_install_xrupt_handlers();
|
||||
if (ACPI_FAILURE(status)) {
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
}
|
||||
#endif /* !ACPI_REDUCED_HARDWARE */
|
||||
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
ACPI_EXPORT_SYMBOL(acpi_enable_subsystem)
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_initialize_objects
|
||||
*
|
||||
* PARAMETERS: flags - Init/enable Options
|
||||
*
|
||||
* RETURN: Status
|
||||
*
|
||||
* DESCRIPTION: Completes namespace initialization by initializing device
|
||||
* objects and executing AML code for Regions, buffers, etc.
|
||||
*
|
||||
******************************************************************************/
|
||||
acpi_status acpi_initialize_objects(u32 flags)
|
||||
{
|
||||
acpi_status status = AE_OK;
|
||||
|
||||
ACPI_FUNCTION_TRACE(acpi_initialize_objects);
|
||||
|
||||
/*
|
||||
* Run all _REG methods
|
||||
*
|
||||
* Note: Any objects accessed by the _REG methods will be automatically
|
||||
* initialized, even if they contain executable AML (see the call to
|
||||
* acpi_ns_initialize_objects below).
|
||||
*/
|
||||
if (!(flags & ACPI_NO_ADDRESS_SPACE_INIT)) {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
|
||||
"[Init] Executing _REG OpRegion methods\n"));
|
||||
|
||||
status = acpi_ev_initialize_op_regions();
|
||||
if (ACPI_FAILURE(status)) {
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Execute any module-level code that was detected during the table load
|
||||
* phase. Although illegal since ACPI 2.0, there are many machines that
|
||||
* contain this type of code. Each block of detected executable AML code
|
||||
* outside of any control method is wrapped with a temporary control
|
||||
* method object and placed on a global list. The methods on this list
|
||||
* are executed below.
|
||||
*/
|
||||
acpi_ns_exec_module_code_list();
|
||||
|
||||
/*
|
||||
* Initialize the objects that remain uninitialized. This runs the
|
||||
* executable AML that may be part of the declaration of these objects:
|
||||
* operation_regions, buffer_fields, Buffers, and Packages.
|
||||
*/
|
||||
if (!(flags & ACPI_NO_OBJECT_INIT)) {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
|
||||
"[Init] Completing Initialization of ACPI Objects\n"));
|
||||
|
||||
status = acpi_ns_initialize_objects();
|
||||
if (ACPI_FAILURE(status)) {
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize all device objects in the namespace. This runs the device
|
||||
* _STA and _INI methods.
|
||||
*/
|
||||
if (!(flags & ACPI_NO_DEVICE_INIT)) {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
|
||||
"[Init] Initializing ACPI Devices\n"));
|
||||
|
||||
status = acpi_ns_initialize_devices();
|
||||
if (ACPI_FAILURE(status)) {
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Empty the caches (delete the cached objects) on the assumption that
|
||||
* the table load filled them up more than they will be at runtime --
|
||||
* thus wasting non-paged memory.
|
||||
*/
|
||||
status = acpi_purge_cached_objects();
|
||||
|
||||
acpi_gbl_startup_flags |= ACPI_INITIALIZED_OK;
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
ACPI_EXPORT_SYMBOL(acpi_initialize_objects)
|
|
@ -994,14 +994,18 @@ static int __init acpi_bus_init(void)
|
|||
status = acpi_ec_ecdt_probe();
|
||||
/* Ignore result. Not having an ECDT is not fatal. */
|
||||
|
||||
acpi_bus_osc_support();
|
||||
|
||||
status = acpi_initialize_objects(ACPI_FULL_INITIALIZATION);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
printk(KERN_ERR PREFIX "Unable to initialize ACPI objects\n");
|
||||
goto error1;
|
||||
}
|
||||
|
||||
/*
|
||||
* _OSC method may exist in module level code,
|
||||
* so it must be run after ACPI_FULL_INITIALIZATION
|
||||
*/
|
||||
acpi_bus_osc_support();
|
||||
|
||||
/*
|
||||
* _PDC control method may load dynamic SSDT tables,
|
||||
* and we need to install the table handler before that.
|
||||
|
|
|
@ -450,15 +450,4 @@ static int acpi_button_remove(struct acpi_device *device, int type)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int __init acpi_button_init(void)
|
||||
{
|
||||
return acpi_bus_register_driver(&acpi_button_driver);
|
||||
}
|
||||
|
||||
static void __exit acpi_button_exit(void)
|
||||
{
|
||||
acpi_bus_unregister_driver(&acpi_button_driver);
|
||||
}
|
||||
|
||||
module_init(acpi_button_init);
|
||||
module_exit(acpi_button_exit);
|
||||
module_acpi_driver(acpi_button_driver);
|
||||
|
|
|
@ -212,24 +212,4 @@ static int acpi_fan_resume(struct device *dev)
|
|||
}
|
||||
#endif
|
||||
|
||||
static int __init acpi_fan_init(void)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
result = acpi_bus_register_driver(&acpi_fan_driver);
|
||||
if (result < 0)
|
||||
return -ENODEV;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit acpi_fan_exit(void)
|
||||
{
|
||||
|
||||
acpi_bus_unregister_driver(&acpi_fan_driver);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
module_init(acpi_fan_init);
|
||||
module_exit(acpi_fan_exit);
|
||||
module_acpi_driver(acpi_fan_driver);
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
static LIST_HEAD(bus_type_list);
|
||||
static DECLARE_RWSEM(bus_type_sem);
|
||||
|
||||
#define PHYSICAL_NODE_STRING "physical_node"
|
||||
|
||||
int register_acpi_bus_type(struct acpi_bus_type *type)
|
||||
{
|
||||
if (acpi_disabled)
|
||||
|
@ -124,84 +126,119 @@ acpi_handle acpi_get_child(acpi_handle parent, u64 address)
|
|||
|
||||
EXPORT_SYMBOL(acpi_get_child);
|
||||
|
||||
/* Link ACPI devices with physical devices */
|
||||
static void acpi_glue_data_handler(acpi_handle handle,
|
||||
void *context)
|
||||
{
|
||||
/* we provide an empty handler */
|
||||
}
|
||||
|
||||
/* Note: a success call will increase reference count by one */
|
||||
struct device *acpi_get_physical_device(acpi_handle handle)
|
||||
{
|
||||
acpi_status status;
|
||||
struct device *dev;
|
||||
|
||||
status = acpi_get_data(handle, acpi_glue_data_handler, (void **)&dev);
|
||||
if (ACPI_SUCCESS(status))
|
||||
return get_device(dev);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(acpi_get_physical_device);
|
||||
|
||||
static int acpi_bind_one(struct device *dev, acpi_handle handle)
|
||||
{
|
||||
struct acpi_device *acpi_dev;
|
||||
acpi_status status;
|
||||
struct acpi_device_physical_node *physical_node;
|
||||
char physical_node_name[sizeof(PHYSICAL_NODE_STRING) + 2];
|
||||
int retval = -EINVAL;
|
||||
|
||||
if (dev->archdata.acpi_handle) {
|
||||
dev_warn(dev, "Drivers changed 'acpi_handle'\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
get_device(dev);
|
||||
status = acpi_attach_data(handle, acpi_glue_data_handler, dev);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
put_device(dev);
|
||||
return -EINVAL;
|
||||
status = acpi_bus_get_device(handle, &acpi_dev);
|
||||
if (ACPI_FAILURE(status))
|
||||
goto err;
|
||||
|
||||
physical_node = kzalloc(sizeof(struct acpi_device_physical_node),
|
||||
GFP_KERNEL);
|
||||
if (!physical_node) {
|
||||
retval = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
|
||||
mutex_lock(&acpi_dev->physical_node_lock);
|
||||
/* allocate physical node id according to physical_node_id_bitmap */
|
||||
physical_node->node_id =
|
||||
find_first_zero_bit(acpi_dev->physical_node_id_bitmap,
|
||||
ACPI_MAX_PHYSICAL_NODE);
|
||||
if (physical_node->node_id >= ACPI_MAX_PHYSICAL_NODE) {
|
||||
retval = -ENOSPC;
|
||||
mutex_unlock(&acpi_dev->physical_node_lock);
|
||||
goto err;
|
||||
}
|
||||
|
||||
set_bit(physical_node->node_id, acpi_dev->physical_node_id_bitmap);
|
||||
physical_node->dev = dev;
|
||||
list_add_tail(&physical_node->node, &acpi_dev->physical_node_list);
|
||||
acpi_dev->physical_node_count++;
|
||||
mutex_unlock(&acpi_dev->physical_node_lock);
|
||||
|
||||
dev->archdata.acpi_handle = handle;
|
||||
|
||||
status = acpi_bus_get_device(handle, &acpi_dev);
|
||||
if (!ACPI_FAILURE(status)) {
|
||||
int ret;
|
||||
if (!physical_node->node_id)
|
||||
strcpy(physical_node_name, PHYSICAL_NODE_STRING);
|
||||
else
|
||||
sprintf(physical_node_name,
|
||||
"physical_node%d", physical_node->node_id);
|
||||
retval = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj,
|
||||
physical_node_name);
|
||||
retval = sysfs_create_link(&dev->kobj, &acpi_dev->dev.kobj,
|
||||
"firmware_node");
|
||||
|
||||
ret = sysfs_create_link(&dev->kobj, &acpi_dev->dev.kobj,
|
||||
"firmware_node");
|
||||
ret = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj,
|
||||
"physical_node");
|
||||
if (acpi_dev->wakeup.flags.valid)
|
||||
device_set_wakeup_capable(dev, true);
|
||||
}
|
||||
if (acpi_dev->wakeup.flags.valid)
|
||||
device_set_wakeup_capable(dev, true);
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
put_device(dev);
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int acpi_unbind_one(struct device *dev)
|
||||
{
|
||||
struct acpi_device_physical_node *entry;
|
||||
struct acpi_device *acpi_dev;
|
||||
acpi_status status;
|
||||
struct list_head *node, *next;
|
||||
|
||||
if (!dev->archdata.acpi_handle)
|
||||
return 0;
|
||||
if (dev == acpi_get_physical_device(dev->archdata.acpi_handle)) {
|
||||
struct acpi_device *acpi_dev;
|
||||
|
||||
/* acpi_get_physical_device increase refcnt by one */
|
||||
put_device(dev);
|
||||
status = acpi_bus_get_device(dev->archdata.acpi_handle,
|
||||
&acpi_dev);
|
||||
if (ACPI_FAILURE(status))
|
||||
goto err;
|
||||
|
||||
if (!acpi_bus_get_device(dev->archdata.acpi_handle,
|
||||
&acpi_dev)) {
|
||||
sysfs_remove_link(&dev->kobj, "firmware_node");
|
||||
sysfs_remove_link(&acpi_dev->dev.kobj, "physical_node");
|
||||
}
|
||||
mutex_lock(&acpi_dev->physical_node_lock);
|
||||
list_for_each_safe(node, next, &acpi_dev->physical_node_list) {
|
||||
char physical_node_name[sizeof(PHYSICAL_NODE_STRING) + 2];
|
||||
|
||||
acpi_detach_data(dev->archdata.acpi_handle,
|
||||
acpi_glue_data_handler);
|
||||
entry = list_entry(node, struct acpi_device_physical_node,
|
||||
node);
|
||||
if (entry->dev != dev)
|
||||
continue;
|
||||
|
||||
list_del(node);
|
||||
clear_bit(entry->node_id, acpi_dev->physical_node_id_bitmap);
|
||||
|
||||
acpi_dev->physical_node_count--;
|
||||
|
||||
if (!entry->node_id)
|
||||
strcpy(physical_node_name, PHYSICAL_NODE_STRING);
|
||||
else
|
||||
sprintf(physical_node_name,
|
||||
"physical_node%d", entry->node_id);
|
||||
|
||||
sysfs_remove_link(&acpi_dev->dev.kobj, physical_node_name);
|
||||
sysfs_remove_link(&dev->kobj, "firmware_node");
|
||||
dev->archdata.acpi_handle = NULL;
|
||||
/* acpi_bind_one increase refcnt by one */
|
||||
put_device(dev);
|
||||
} else {
|
||||
dev_err(dev, "Oops, 'acpi_handle' corrupt\n");
|
||||
kfree(entry);
|
||||
}
|
||||
mutex_unlock(&acpi_dev->physical_node_lock);
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
dev_err(dev, "Oops, 'acpi_handle' corrupt\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int acpi_platform_notify(struct device *dev)
|
||||
|
|
|
@ -86,25 +86,7 @@ static struct acpi_driver acpi_hed_driver = {
|
|||
.notify = acpi_hed_notify,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init acpi_hed_init(void)
|
||||
{
|
||||
if (acpi_disabled)
|
||||
return -ENODEV;
|
||||
|
||||
if (acpi_bus_register_driver(&acpi_hed_driver) < 0)
|
||||
return -ENODEV;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit acpi_hed_exit(void)
|
||||
{
|
||||
acpi_bus_unregister_driver(&acpi_hed_driver);
|
||||
}
|
||||
|
||||
module_init(acpi_hed_init);
|
||||
module_exit(acpi_hed_exit);
|
||||
module_acpi_driver(acpi_hed_driver);
|
||||
|
||||
ACPI_MODULE_NAME("hed");
|
||||
MODULE_AUTHOR("Huang Ying");
|
||||
|
|
|
@ -302,26 +302,41 @@ acpi_system_wakeup_device_seq_show(struct seq_file *seq, void *offset)
|
|||
list_for_each_safe(node, next, &acpi_wakeup_device_list) {
|
||||
struct acpi_device *dev =
|
||||
container_of(node, struct acpi_device, wakeup_list);
|
||||
struct device *ldev;
|
||||
struct acpi_device_physical_node *entry;
|
||||
|
||||
if (!dev->wakeup.flags.valid)
|
||||
continue;
|
||||
|
||||
ldev = acpi_get_physical_device(dev->handle);
|
||||
seq_printf(seq, "%s\t S%d\t%c%-8s ",
|
||||
seq_printf(seq, "%s\t S%d\t",
|
||||
dev->pnp.bus_id,
|
||||
(u32) dev->wakeup.sleep_state,
|
||||
dev->wakeup.flags.run_wake ? '*' : ' ',
|
||||
(device_may_wakeup(&dev->dev)
|
||||
|| (ldev && device_may_wakeup(ldev))) ?
|
||||
"enabled" : "disabled");
|
||||
if (ldev)
|
||||
seq_printf(seq, "%s:%s",
|
||||
ldev->bus ? ldev->bus->name : "no-bus",
|
||||
dev_name(ldev));
|
||||
seq_printf(seq, "\n");
|
||||
put_device(ldev);
|
||||
(u32) dev->wakeup.sleep_state);
|
||||
|
||||
if (!dev->physical_node_count)
|
||||
seq_printf(seq, "%c%-8s\n",
|
||||
dev->wakeup.flags.run_wake ?
|
||||
'*' : ' ', "disabled");
|
||||
else {
|
||||
struct device *ldev;
|
||||
list_for_each_entry(entry, &dev->physical_node_list,
|
||||
node) {
|
||||
ldev = get_device(entry->dev);
|
||||
if (!ldev)
|
||||
continue;
|
||||
|
||||
if (&entry->node !=
|
||||
dev->physical_node_list.next)
|
||||
seq_printf(seq, "\t\t");
|
||||
|
||||
seq_printf(seq, "%c%-8s %s:%s\n",
|
||||
dev->wakeup.flags.run_wake ? '*' : ' ',
|
||||
(device_may_wakeup(&dev->dev) ||
|
||||
(ldev && device_may_wakeup(ldev))) ?
|
||||
"enabled" : "disabled",
|
||||
ldev->bus ? ldev->bus->name :
|
||||
"no-bus", dev_name(ldev));
|
||||
put_device(ldev);
|
||||
}
|
||||
}
|
||||
}
|
||||
mutex_unlock(&acpi_device_lock);
|
||||
return 0;
|
||||
|
@ -329,12 +344,14 @@ acpi_system_wakeup_device_seq_show(struct seq_file *seq, void *offset)
|
|||
|
||||
static void physical_device_enable_wakeup(struct acpi_device *adev)
|
||||
{
|
||||
struct device *dev = acpi_get_physical_device(adev->handle);
|
||||
struct acpi_device_physical_node *entry;
|
||||
|
||||
if (dev && device_can_wakeup(dev)) {
|
||||
bool enable = !device_may_wakeup(dev);
|
||||
device_set_wakeup_enable(dev, enable);
|
||||
}
|
||||
list_for_each_entry(entry,
|
||||
&adev->physical_node_list, node)
|
||||
if (entry->dev && device_can_wakeup(entry->dev)) {
|
||||
bool enable = !device_may_wakeup(entry->dev);
|
||||
device_set_wakeup_enable(entry->dev, enable);
|
||||
}
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
|
|
|
@ -310,23 +310,7 @@ static int acpi_smbus_hc_remove(struct acpi_device *device, int type)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int __init acpi_smb_hc_init(void)
|
||||
{
|
||||
int result;
|
||||
|
||||
result = acpi_bus_register_driver(&acpi_smb_hc_driver);
|
||||
if (result < 0)
|
||||
return -ENODEV;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit acpi_smb_hc_exit(void)
|
||||
{
|
||||
acpi_bus_unregister_driver(&acpi_smb_hc_driver);
|
||||
}
|
||||
|
||||
module_init(acpi_smb_hc_init);
|
||||
module_exit(acpi_smb_hc_exit);
|
||||
module_acpi_driver(acpi_smb_hc_driver);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Alexey Starikovskiy");
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include <linux/signal.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/dmi.h>
|
||||
#include <linux/nls.h>
|
||||
|
||||
#include <acpi/acpi_drivers.h>
|
||||
|
||||
|
@ -232,8 +233,35 @@ acpi_device_path_show(struct device *dev, struct device_attribute *attr, char *b
|
|||
}
|
||||
static DEVICE_ATTR(path, 0444, acpi_device_path_show, NULL);
|
||||
|
||||
/* sysfs file that shows description text from the ACPI _STR method */
|
||||
static ssize_t description_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf) {
|
||||
struct acpi_device *acpi_dev = to_acpi_device(dev);
|
||||
int result;
|
||||
|
||||
if (acpi_dev->pnp.str_obj == NULL)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* The _STR object contains a Unicode identifier for a device.
|
||||
* We need to convert to utf-8 so it can be displayed.
|
||||
*/
|
||||
result = utf16s_to_utf8s(
|
||||
(wchar_t *)acpi_dev->pnp.str_obj->buffer.pointer,
|
||||
acpi_dev->pnp.str_obj->buffer.length,
|
||||
UTF16_LITTLE_ENDIAN, buf,
|
||||
PAGE_SIZE);
|
||||
|
||||
buf[result++] = '\n';
|
||||
|
||||
return result;
|
||||
}
|
||||
static DEVICE_ATTR(description, 0444, description_show, NULL);
|
||||
|
||||
static int acpi_device_setup_files(struct acpi_device *dev)
|
||||
{
|
||||
struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
|
||||
acpi_status status;
|
||||
acpi_handle temp;
|
||||
int result = 0;
|
||||
|
@ -257,6 +285,21 @@ static int acpi_device_setup_files(struct acpi_device *dev)
|
|||
goto end;
|
||||
}
|
||||
|
||||
/*
|
||||
* If device has _STR, 'description' file is created
|
||||
*/
|
||||
status = acpi_get_handle(dev->handle, "_STR", &temp);
|
||||
if (ACPI_SUCCESS(status)) {
|
||||
status = acpi_evaluate_object(dev->handle, "_STR",
|
||||
NULL, &buffer);
|
||||
if (ACPI_FAILURE(status))
|
||||
buffer.pointer = NULL;
|
||||
dev->pnp.str_obj = buffer.pointer;
|
||||
result = device_create_file(&dev->dev, &dev_attr_description);
|
||||
if (result)
|
||||
goto end;
|
||||
}
|
||||
|
||||
/*
|
||||
* If device has _EJ0, 'eject' file is created that is used to trigger
|
||||
* hot-removal function from userland.
|
||||
|
@ -274,8 +317,15 @@ static void acpi_device_remove_files(struct acpi_device *dev)
|
|||
acpi_handle temp;
|
||||
|
||||
/*
|
||||
* If device has _EJ0, 'eject' file is created that is used to trigger
|
||||
* hot-removal function from userland.
|
||||
* If device has _STR, remove 'description' file
|
||||
*/
|
||||
status = acpi_get_handle(dev->handle, "_STR", &temp);
|
||||
if (ACPI_SUCCESS(status)) {
|
||||
kfree(dev->pnp.str_obj);
|
||||
device_remove_file(&dev->dev, &dev_attr_description);
|
||||
}
|
||||
/*
|
||||
* If device has _EJ0, remove 'eject' file.
|
||||
*/
|
||||
status = acpi_get_handle(dev->handle, "_EJ0", &temp);
|
||||
if (ACPI_SUCCESS(status))
|
||||
|
@ -481,6 +531,8 @@ static int acpi_device_register(struct acpi_device *device)
|
|||
INIT_LIST_HEAD(&device->children);
|
||||
INIT_LIST_HEAD(&device->node);
|
||||
INIT_LIST_HEAD(&device->wakeup_list);
|
||||
INIT_LIST_HEAD(&device->physical_node_list);
|
||||
mutex_init(&device->physical_node_lock);
|
||||
|
||||
new_bus_id = kzalloc(sizeof(struct acpi_device_bus_id), GFP_KERNEL);
|
||||
if (!new_bus_id) {
|
||||
|
|
|
@ -240,10 +240,17 @@ acpi_table_parse_entries(char *id,
|
|||
table_end) {
|
||||
if (entry->type == entry_id
|
||||
&& (!max_entries || count++ < max_entries))
|
||||
if (handler(entry, table_end)) {
|
||||
early_acpi_os_unmap_memory((char *)table_header, tbl_size);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (handler(entry, table_end))
|
||||
goto err;
|
||||
|
||||
/*
|
||||
* If entry->length is 0, break from this loop to avoid
|
||||
* infinite loop.
|
||||
*/
|
||||
if (entry->length == 0) {
|
||||
pr_err(PREFIX "[%4.4s:0x%02x] Invalid zero length\n", id, entry_id);
|
||||
goto err;
|
||||
}
|
||||
|
||||
entry = (struct acpi_subtable_header *)
|
||||
((unsigned long)entry + entry->length);
|
||||
|
@ -255,6 +262,9 @@ acpi_table_parse_entries(char *id,
|
|||
|
||||
early_acpi_os_unmap_memory((char *)table_header, tbl_size);
|
||||
return count;
|
||||
err:
|
||||
early_acpi_os_unmap_memory((char *)table_header, tbl_size);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
int __init
|
||||
|
|
|
@ -384,7 +384,7 @@ acpi_evaluate_reference(acpi_handle handle,
|
|||
EXPORT_SYMBOL(acpi_evaluate_reference);
|
||||
|
||||
acpi_status
|
||||
acpi_get_physical_device_location(acpi_handle handle, struct acpi_pld *pld)
|
||||
acpi_get_physical_device_location(acpi_handle handle, struct acpi_pld_info **pld)
|
||||
{
|
||||
acpi_status status;
|
||||
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
|
||||
|
@ -400,13 +400,16 @@ acpi_get_physical_device_location(acpi_handle handle, struct acpi_pld *pld)
|
|||
if (!output || output->type != ACPI_TYPE_PACKAGE
|
||||
|| !output->package.count
|
||||
|| output->package.elements[0].type != ACPI_TYPE_BUFFER
|
||||
|| output->package.elements[0].buffer.length > sizeof(*pld)) {
|
||||
|| output->package.elements[0].buffer.length < ACPI_PLD_REV1_BUFFER_SIZE) {
|
||||
status = AE_TYPE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
memcpy(pld, output->package.elements[0].buffer.pointer,
|
||||
output->package.elements[0].buffer.length);
|
||||
status = acpi_decode_pld_buffer(
|
||||
output->package.elements[0].buffer.pointer,
|
||||
output->package.elements[0].buffer.length,
|
||||
pld);
|
||||
|
||||
out:
|
||||
kfree(buffer.pointer);
|
||||
return status;
|
||||
|
|
|
@ -426,19 +426,7 @@ static struct acpi_driver acpi_smbus_cmi_driver = {
|
|||
.remove = acpi_smbus_cmi_remove,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init acpi_smbus_cmi_init(void)
|
||||
{
|
||||
return acpi_bus_register_driver(&acpi_smbus_cmi_driver);
|
||||
}
|
||||
|
||||
static void __exit acpi_smbus_cmi_exit(void)
|
||||
{
|
||||
acpi_bus_unregister_driver(&acpi_smbus_cmi_driver);
|
||||
}
|
||||
|
||||
module_init(acpi_smbus_cmi_init);
|
||||
module_exit(acpi_smbus_cmi_exit);
|
||||
module_acpi_driver(acpi_smbus_cmi_driver);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Crane Cai <crane.cai@amd.com>");
|
||||
|
|
|
@ -413,6 +413,7 @@ static const struct x86_cpu_id intel_idle_ids[] = {
|
|||
ICPU(0x2a, idle_cpu_snb),
|
||||
ICPU(0x2d, idle_cpu_snb),
|
||||
ICPU(0x3a, idle_cpu_ivb),
|
||||
ICPU(0x3e, idle_cpu_ivb),
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(x86cpu, intel_idle_ids);
|
||||
|
|
|
@ -151,22 +151,7 @@ static struct acpi_driver atlas_acpi_driver = {
|
|||
.remove = atlas_acpi_button_remove,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init atlas_acpi_init(void)
|
||||
{
|
||||
if (acpi_disabled)
|
||||
return -ENODEV;
|
||||
|
||||
return acpi_bus_register_driver(&atlas_acpi_driver);
|
||||
}
|
||||
|
||||
static void __exit atlas_acpi_exit(void)
|
||||
{
|
||||
acpi_bus_unregister_driver(&atlas_acpi_driver);
|
||||
}
|
||||
|
||||
module_init(atlas_acpi_init);
|
||||
module_exit(atlas_acpi_exit);
|
||||
module_acpi_driver(atlas_acpi_driver);
|
||||
|
||||
MODULE_AUTHOR("Jaya Kumar");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
@ -382,31 +382,8 @@ static struct acpi_driver lis3lv02d_driver = {
|
|||
},
|
||||
.drv.pm = HP_ACCEL_PM,
|
||||
};
|
||||
|
||||
static int __init lis3lv02d_init_module(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (acpi_disabled)
|
||||
return -ENODEV;
|
||||
|
||||
ret = acpi_bus_register_driver(&lis3lv02d_driver);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
pr_info("driver loaded\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit lis3lv02d_exit_module(void)
|
||||
{
|
||||
acpi_bus_unregister_driver(&lis3lv02d_driver);
|
||||
}
|
||||
module_acpi_driver(lis3lv02d_driver);
|
||||
|
||||
MODULE_DESCRIPTION("Glue between LIS3LV02Dx and HP ACPI BIOS and support for disk protection LED.");
|
||||
MODULE_AUTHOR("Yan Burman, Eric Piel, Pavel Machek");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
module_init(lis3lv02d_init_module);
|
||||
module_exit(lis3lv02d_exit_module);
|
||||
|
|
|
@ -917,20 +917,8 @@ static struct acpi_driver ideapad_acpi_driver = {
|
|||
.drv.pm = &ideapad_pm,
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
static int __init ideapad_acpi_module_init(void)
|
||||
{
|
||||
return acpi_bus_register_driver(&ideapad_acpi_driver);
|
||||
}
|
||||
|
||||
static void __exit ideapad_acpi_module_exit(void)
|
||||
{
|
||||
acpi_bus_unregister_driver(&ideapad_acpi_driver);
|
||||
}
|
||||
module_acpi_driver(ideapad_acpi_driver);
|
||||
|
||||
MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
|
||||
MODULE_DESCRIPTION("IdeaPad ACPI Extras");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
module_init(ideapad_acpi_module_init);
|
||||
module_exit(ideapad_acpi_module_exit);
|
||||
|
|
|
@ -186,27 +186,7 @@ static struct acpi_driver acpi_topstar_driver = {
|
|||
.notify = acpi_topstar_notify,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init topstar_laptop_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = acpi_bus_register_driver(&acpi_topstar_driver);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
pr_info("ACPI extras driver loaded\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit topstar_laptop_exit(void)
|
||||
{
|
||||
acpi_bus_unregister_driver(&acpi_topstar_driver);
|
||||
}
|
||||
|
||||
module_init(topstar_laptop_init);
|
||||
module_exit(topstar_laptop_exit);
|
||||
module_acpi_driver(acpi_topstar_driver);
|
||||
|
||||
MODULE_AUTHOR("Herton Ronaldo Krzesinski");
|
||||
MODULE_DESCRIPTION("Topstar Laptop ACPI Extras driver");
|
||||
|
|
|
@ -122,30 +122,10 @@ static int toshiba_bt_rfkill_add(struct acpi_device *device)
|
|||
return result;
|
||||
}
|
||||
|
||||
static int __init toshiba_bt_rfkill_init(void)
|
||||
{
|
||||
int result;
|
||||
|
||||
result = acpi_bus_register_driver(&toshiba_bt_rfkill_driver);
|
||||
if (result < 0) {
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
|
||||
"Error registering driver\n"));
|
||||
return result;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int toshiba_bt_rfkill_remove(struct acpi_device *device, int type)
|
||||
{
|
||||
/* clean up */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit toshiba_bt_rfkill_exit(void)
|
||||
{
|
||||
acpi_bus_unregister_driver(&toshiba_bt_rfkill_driver);
|
||||
}
|
||||
|
||||
module_init(toshiba_bt_rfkill_init);
|
||||
module_exit(toshiba_bt_rfkill_exit);
|
||||
module_acpi_driver(toshiba_bt_rfkill_driver);
|
||||
|
|
|
@ -170,16 +170,4 @@ static struct acpi_driver xo15_ebook_driver = {
|
|||
},
|
||||
.drv.pm = &ebook_switch_pm,
|
||||
};
|
||||
|
||||
static int __init xo15_ebook_init(void)
|
||||
{
|
||||
return acpi_bus_register_driver(&xo15_ebook_driver);
|
||||
}
|
||||
|
||||
static void __exit xo15_ebook_exit(void)
|
||||
{
|
||||
acpi_bus_unregister_driver(&xo15_ebook_driver);
|
||||
}
|
||||
|
||||
module_init(xo15_ebook_init);
|
||||
module_exit(xo15_ebook_exit);
|
||||
module_acpi_driver(xo15_ebook_driver);
|
||||
|
|
|
@ -321,14 +321,9 @@ static int __init acpi_pnp_match(struct device *dev, void *_pnp)
|
|||
{
|
||||
struct acpi_device *acpi = to_acpi_device(dev);
|
||||
struct pnp_dev *pnp = _pnp;
|
||||
struct device *physical_device;
|
||||
|
||||
physical_device = acpi_get_physical_device(acpi->handle);
|
||||
if (physical_device)
|
||||
put_device(physical_device);
|
||||
|
||||
/* true means it matched */
|
||||
return !physical_device
|
||||
return !acpi->physical_node_count
|
||||
&& compare_pnp_id(pnp->id, acpi_device_hid(acpi));
|
||||
}
|
||||
|
||||
|
|
|
@ -87,7 +87,7 @@ static int usb_acpi_check_port_connect_type(struct usb_device *hdev,
|
|||
acpi_status status;
|
||||
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
|
||||
union acpi_object *upc;
|
||||
struct acpi_pld pld;
|
||||
struct acpi_pld_info *pld;
|
||||
int ret = 0;
|
||||
|
||||
/*
|
||||
|
@ -111,16 +111,17 @@ static int usb_acpi_check_port_connect_type(struct usb_device *hdev,
|
|||
}
|
||||
|
||||
if (upc->package.elements[0].integer.value)
|
||||
if (pld.user_visible)
|
||||
if (pld->user_visible)
|
||||
usb_set_hub_port_connect_type(hdev, port1,
|
||||
USB_PORT_CONNECT_TYPE_HOT_PLUG);
|
||||
else
|
||||
usb_set_hub_port_connect_type(hdev, port1,
|
||||
USB_PORT_CONNECT_TYPE_HARD_WIRED);
|
||||
else if (!pld.user_visible)
|
||||
else if (!pld->user_visible)
|
||||
usb_set_hub_port_connect_type(hdev, port1, USB_PORT_NOT_USED);
|
||||
|
||||
out:
|
||||
ACPI_FREE(pld);
|
||||
kfree(upc);
|
||||
return ret;
|
||||
}
|
||||
|
|
235
include/acpi/acbuffer.h
Normal file
235
include/acpi/acbuffer.h
Normal file
|
@ -0,0 +1,235 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Name: acbuffer.h - Support for buffers returned by ACPI predefined names
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2000 - 2012, Intel Corp.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions, and the following disclaimer,
|
||||
* without modification.
|
||||
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
|
||||
* substantially similar to the "NO WARRANTY" disclaimer below
|
||||
* ("Disclaimer") and any redistribution must be conditioned upon
|
||||
* including a substantially similar Disclaimer requirement for further
|
||||
* binary redistribution.
|
||||
* 3. Neither the names of the above-listed copyright holders nor the names
|
||||
* of any contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* Alternatively, this software may be distributed under the terms of the
|
||||
* GNU General Public License ("GPL") version 2 as published by the Free
|
||||
* Software Foundation.
|
||||
*
|
||||
* NO WARRANTY
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGES.
|
||||
*/
|
||||
|
||||
#ifndef __ACBUFFER_H__
|
||||
#define __ACBUFFER_H__
|
||||
|
||||
/*
|
||||
* Contains buffer structures for these predefined names:
|
||||
* _FDE, _GRT, _GTM, _PLD, _SRT
|
||||
*/
|
||||
|
||||
/*
|
||||
* Note: C bitfields are not used for this reason:
|
||||
*
|
||||
* "Bitfields are great and easy to read, but unfortunately the C language
|
||||
* does not specify the layout of bitfields in memory, which means they are
|
||||
* essentially useless for dealing with packed data in on-disk formats or
|
||||
* binary wire protocols." (Or ACPI tables and buffers.) "If you ask me,
|
||||
* this decision was a design error in C. Ritchie could have picked an order
|
||||
* and stuck with it." Norman Ramsey.
|
||||
* See http://stackoverflow.com/a/1053662/41661
|
||||
*/
|
||||
|
||||
/* _FDE return value */
|
||||
|
||||
struct acpi_fde_info {
|
||||
u32 floppy0;
|
||||
u32 floppy1;
|
||||
u32 floppy2;
|
||||
u32 floppy3;
|
||||
u32 tape;
|
||||
};
|
||||
|
||||
/*
|
||||
* _GRT return value
|
||||
* _SRT input value
|
||||
*/
|
||||
struct acpi_grt_info {
|
||||
u16 year;
|
||||
u8 month;
|
||||
u8 day;
|
||||
u8 hour;
|
||||
u8 minute;
|
||||
u8 second;
|
||||
u8 valid;
|
||||
u16 milliseconds;
|
||||
u16 timezone;
|
||||
u8 daylight;
|
||||
u8 reserved[3];
|
||||
};
|
||||
|
||||
/* _GTM return value */
|
||||
|
||||
struct acpi_gtm_info {
|
||||
u32 pio_speed0;
|
||||
u32 dma_speed0;
|
||||
u32 pio_speed1;
|
||||
u32 dma_speed1;
|
||||
u32 flags;
|
||||
};
|
||||
|
||||
/*
|
||||
* Formatted _PLD return value. The minimum size is a package containing
|
||||
* one buffer.
|
||||
* Revision 1: Buffer is 16 bytes (128 bits)
|
||||
* Revision 2: Buffer is 20 bytes (160 bits)
|
||||
*
|
||||
* Note: This structure is returned from the acpi_decode_pld_buffer
|
||||
* interface.
|
||||
*/
|
||||
struct acpi_pld_info {
|
||||
u8 revision;
|
||||
u8 ignore_color;
|
||||
u32 color;
|
||||
u16 width;
|
||||
u16 height;
|
||||
u8 user_visible;
|
||||
u8 dock;
|
||||
u8 lid;
|
||||
u8 panel;
|
||||
u8 vertical_position;
|
||||
u8 horizontal_position;
|
||||
u8 shape;
|
||||
u8 group_orientation;
|
||||
u8 group_token;
|
||||
u8 group_position;
|
||||
u8 bay;
|
||||
u8 ejectable;
|
||||
u8 ospm_eject_required;
|
||||
u8 cabinet_number;
|
||||
u8 card_cage_number;
|
||||
u8 reference;
|
||||
u8 rotation;
|
||||
u8 order;
|
||||
u8 reserved;
|
||||
u16 vertical_offset;
|
||||
u16 horizontal_offset;
|
||||
};
|
||||
|
||||
/*
|
||||
* Macros to:
|
||||
* 1) Convert a _PLD buffer to internal struct acpi_pld_info format - ACPI_PLD_GET*
|
||||
* (Used by acpi_decode_pld_buffer)
|
||||
* 2) Construct a _PLD buffer - ACPI_PLD_SET*
|
||||
* (Intended for BIOS use only)
|
||||
*/
|
||||
#define ACPI_PLD_REV1_BUFFER_SIZE 16 /* For Revision 1 of the buffer (From ACPI spec) */
|
||||
#define ACPI_PLD_BUFFER_SIZE 20 /* For Revision 2 of the buffer (From ACPI spec) */
|
||||
|
||||
/* First 32-bit dword, bits 0:32 */
|
||||
|
||||
#define ACPI_PLD_GET_REVISION(dword) ACPI_GET_BITS (dword, 0, ACPI_7BIT_MASK)
|
||||
#define ACPI_PLD_SET_REVISION(dword,value) ACPI_SET_BITS (dword, 0, ACPI_7BIT_MASK, value) /* Offset 0, Len 7 */
|
||||
|
||||
#define ACPI_PLD_GET_IGNORE_COLOR(dword) ACPI_GET_BITS (dword, 7, ACPI_1BIT_MASK)
|
||||
#define ACPI_PLD_SET_IGNORE_COLOR(dword,value) ACPI_SET_BITS (dword, 7, ACPI_1BIT_MASK, value) /* Offset 7, Len 1 */
|
||||
|
||||
#define ACPI_PLD_GET_COLOR(dword) ACPI_GET_BITS (dword, 8, ACPI_24BIT_MASK)
|
||||
#define ACPI_PLD_SET_COLOR(dword,value) ACPI_SET_BITS (dword, 8, ACPI_24BIT_MASK, value) /* Offset 8, Len 24 */
|
||||
|
||||
/* Second 32-bit dword, bits 33:63 */
|
||||
|
||||
#define ACPI_PLD_GET_WIDTH(dword) ACPI_GET_BITS (dword, 0, ACPI_16BIT_MASK)
|
||||
#define ACPI_PLD_SET_WIDTH(dword,value) ACPI_SET_BITS (dword, 0, ACPI_16BIT_MASK, value) /* Offset 32+0=32, Len 16 */
|
||||
|
||||
#define ACPI_PLD_GET_HEIGHT(dword) ACPI_GET_BITS (dword, 16, ACPI_16BIT_MASK)
|
||||
#define ACPI_PLD_SET_HEIGHT(dword,value) ACPI_SET_BITS (dword, 16, ACPI_16BIT_MASK, value) /* Offset 32+16=48, Len 16 */
|
||||
|
||||
/* Third 32-bit dword, bits 64:95 */
|
||||
|
||||
#define ACPI_PLD_GET_USER_VISIBLE(dword) ACPI_GET_BITS (dword, 0, ACPI_1BIT_MASK)
|
||||
#define ACPI_PLD_SET_USER_VISIBLE(dword,value) ACPI_SET_BITS (dword, 0, ACPI_1BIT_MASK, value) /* Offset 64+0=64, Len 1 */
|
||||
|
||||
#define ACPI_PLD_GET_DOCK(dword) ACPI_GET_BITS (dword, 1, ACPI_1BIT_MASK)
|
||||
#define ACPI_PLD_SET_DOCK(dword,value) ACPI_SET_BITS (dword, 1, ACPI_1BIT_MASK, value) /* Offset 64+1=65, Len 1 */
|
||||
|
||||
#define ACPI_PLD_GET_LID(dword) ACPI_GET_BITS (dword, 2, ACPI_1BIT_MASK)
|
||||
#define ACPI_PLD_SET_LID(dword,value) ACPI_SET_BITS (dword, 2, ACPI_1BIT_MASK, value) /* Offset 64+2=66, Len 1 */
|
||||
|
||||
#define ACPI_PLD_GET_PANEL(dword) ACPI_GET_BITS (dword, 3, ACPI_3BIT_MASK)
|
||||
#define ACPI_PLD_SET_PANEL(dword,value) ACPI_SET_BITS (dword, 3, ACPI_3BIT_MASK, value) /* Offset 64+3=67, Len 3 */
|
||||
|
||||
#define ACPI_PLD_GET_VERTICAL(dword) ACPI_GET_BITS (dword, 6, ACPI_2BIT_MASK)
|
||||
#define ACPI_PLD_SET_VERTICAL(dword,value) ACPI_SET_BITS (dword, 6, ACPI_2BIT_MASK, value) /* Offset 64+6=70, Len 2 */
|
||||
|
||||
#define ACPI_PLD_GET_HORIZONTAL(dword) ACPI_GET_BITS (dword, 8, ACPI_2BIT_MASK)
|
||||
#define ACPI_PLD_SET_HORIZONTAL(dword,value) ACPI_SET_BITS (dword, 8, ACPI_2BIT_MASK, value) /* Offset 64+8=72, Len 2 */
|
||||
|
||||
#define ACPI_PLD_GET_SHAPE(dword) ACPI_GET_BITS (dword, 10, ACPI_4BIT_MASK)
|
||||
#define ACPI_PLD_SET_SHAPE(dword,value) ACPI_SET_BITS (dword, 10, ACPI_4BIT_MASK, value) /* Offset 64+10=74, Len 4 */
|
||||
|
||||
#define ACPI_PLD_GET_ORIENTATION(dword) ACPI_GET_BITS (dword, 14, ACPI_1BIT_MASK)
|
||||
#define ACPI_PLD_SET_ORIENTATION(dword,value) ACPI_SET_BITS (dword, 14, ACPI_1BIT_MASK, value) /* Offset 64+14=78, Len 1 */
|
||||
|
||||
#define ACPI_PLD_GET_TOKEN(dword) ACPI_GET_BITS (dword, 15, ACPI_8BIT_MASK)
|
||||
#define ACPI_PLD_SET_TOKEN(dword,value) ACPI_SET_BITS (dword, 15, ACPI_8BIT_MASK, value) /* Offset 64+15=79, Len 8 */
|
||||
|
||||
#define ACPI_PLD_GET_POSITION(dword) ACPI_GET_BITS (dword, 23, ACPI_8BIT_MASK)
|
||||
#define ACPI_PLD_SET_POSITION(dword,value) ACPI_SET_BITS (dword, 23, ACPI_8BIT_MASK, value) /* Offset 64+23=87, Len 8 */
|
||||
|
||||
#define ACPI_PLD_GET_BAY(dword) ACPI_GET_BITS (dword, 31, ACPI_1BIT_MASK)
|
||||
#define ACPI_PLD_SET_BAY(dword,value) ACPI_SET_BITS (dword, 31, ACPI_1BIT_MASK, value) /* Offset 64+31=95, Len 1 */
|
||||
|
||||
/* Fourth 32-bit dword, bits 96:127 */
|
||||
|
||||
#define ACPI_PLD_GET_EJECTABLE(dword) ACPI_GET_BITS (dword, 0, ACPI_1BIT_MASK)
|
||||
#define ACPI_PLD_SET_EJECTABLE(dword,value) ACPI_SET_BITS (dword, 0, ACPI_1BIT_MASK, value) /* Offset 96+0=96, Len 1 */
|
||||
|
||||
#define ACPI_PLD_GET_OSPM_EJECT(dword) ACPI_GET_BITS (dword, 1, ACPI_1BIT_MASK)
|
||||
#define ACPI_PLD_SET_OSPM_EJECT(dword,value) ACPI_SET_BITS (dword, 1, ACPI_1BIT_MASK, value) /* Offset 96+1=97, Len 1 */
|
||||
|
||||
#define ACPI_PLD_GET_CABINET(dword) ACPI_GET_BITS (dword, 2, ACPI_8BIT_MASK)
|
||||
#define ACPI_PLD_SET_CABINET(dword,value) ACPI_SET_BITS (dword, 2, ACPI_8BIT_MASK, value) /* Offset 96+2=98, Len 8 */
|
||||
|
||||
#define ACPI_PLD_GET_CARD_CAGE(dword) ACPI_GET_BITS (dword, 10, ACPI_8BIT_MASK)
|
||||
#define ACPI_PLD_SET_CARD_CAGE(dword,value) ACPI_SET_BITS (dword, 10, ACPI_8BIT_MASK, value) /* Offset 96+10=106, Len 8 */
|
||||
|
||||
#define ACPI_PLD_GET_REFERENCE(dword) ACPI_GET_BITS (dword, 18, ACPI_1BIT_MASK)
|
||||
#define ACPI_PLD_SET_REFERENCE(dword,value) ACPI_SET_BITS (dword, 18, ACPI_1BIT_MASK, value) /* Offset 96+18=114, Len 1 */
|
||||
|
||||
#define ACPI_PLD_GET_ROTATION(dword) ACPI_GET_BITS (dword, 19, ACPI_4BIT_MASK)
|
||||
#define ACPI_PLD_SET_ROTATION(dword,value) ACPI_SET_BITS (dword, 19, ACPI_4BIT_MASK, value) /* Offset 96+19=115, Len 4 */
|
||||
|
||||
#define ACPI_PLD_GET_ORDER(dword) ACPI_GET_BITS (dword, 23, ACPI_5BIT_MASK)
|
||||
#define ACPI_PLD_SET_ORDER(dword,value) ACPI_SET_BITS (dword, 23, ACPI_5BIT_MASK, value) /* Offset 96+23=119, Len 5 */
|
||||
|
||||
/* Fifth 32-bit dword, bits 128:159 (Revision 2 of _PLD only) */
|
||||
|
||||
#define ACPI_PLD_GET_VERT_OFFSET(dword) ACPI_GET_BITS (dword, 0, ACPI_16BIT_MASK)
|
||||
#define ACPI_PLD_SET_VERT_OFFSET(dword,value) ACPI_SET_BITS (dword, 0, ACPI_16BIT_MASK, value) /* Offset 128+0=128, Len 16 */
|
||||
|
||||
#define ACPI_PLD_GET_HORIZ_OFFSET(dword) ACPI_GET_BITS (dword, 16, ACPI_16BIT_MASK)
|
||||
#define ACPI_PLD_SET_HORIZ_OFFSET(dword,value) ACPI_SET_BITS (dword, 16, ACPI_16BIT_MASK, value) /* Offset 128+16=144, Len 16 */
|
||||
|
||||
#endif /* ACBUFFER_H */
|
|
@ -63,11 +63,10 @@
|
|||
#define METHOD_NAME__PRW "_PRW"
|
||||
#define METHOD_NAME__SRS "_SRS"
|
||||
#define METHOD_NAME__CBA "_CBA"
|
||||
#define METHOD_NAME__PLD "_PLD"
|
||||
|
||||
/* Method names - these methods must appear at the namespace root */
|
||||
|
||||
#define METHOD_PATHNAME__BFS "\\_BFS"
|
||||
#define METHOD_PATHNAME__GTS "\\_GTS"
|
||||
#define METHOD_PATHNAME__PTS "\\_PTS"
|
||||
#define METHOD_PATHNAME__SST "\\_SI._SST"
|
||||
#define METHOD_PATHNAME__WAK "\\_WAK"
|
||||
|
|
|
@ -54,37 +54,8 @@ acpi_status
|
|||
acpi_evaluate_hotplug_ost(acpi_handle handle, u32 source_event,
|
||||
u32 status_code, struct acpi_buffer *status_buf);
|
||||
|
||||
struct acpi_pld {
|
||||
unsigned int revision:7; /* 0 */
|
||||
unsigned int ignore_colour:1; /* 7 */
|
||||
unsigned int colour:24; /* 8 */
|
||||
unsigned int width:16; /* 32 */
|
||||
unsigned int height:16; /* 48 */
|
||||
unsigned int user_visible:1; /* 64 */
|
||||
unsigned int dock:1; /* 65 */
|
||||
unsigned int lid:1; /* 66 */
|
||||
unsigned int panel:3; /* 67 */
|
||||
unsigned int vertical_pos:2; /* 70 */
|
||||
unsigned int horizontal_pos:2; /* 72 */
|
||||
unsigned int shape:4; /* 74 */
|
||||
unsigned int group_orientation:1; /* 78 */
|
||||
unsigned int group_token:8; /* 79 */
|
||||
unsigned int group_position:8; /* 87 */
|
||||
unsigned int bay:1; /* 95 */
|
||||
unsigned int ejectable:1; /* 96 */
|
||||
unsigned int ospm_eject_required:1; /* 97 */
|
||||
unsigned int cabinet_number:8; /* 98 */
|
||||
unsigned int card_cage_number:8; /* 106 */
|
||||
unsigned int reference:1; /* 114 */
|
||||
unsigned int rotation:4; /* 115 */
|
||||
unsigned int order:5; /* 119 */
|
||||
unsigned int reserved:4; /* 124 */
|
||||
unsigned int vertical_offset:16; /* 128 */
|
||||
unsigned int horizontal_offset:16; /* 144 */
|
||||
} __attribute__((__packed__));
|
||||
|
||||
acpi_status
|
||||
acpi_get_physical_device_location(acpi_handle handle, struct acpi_pld *pld);
|
||||
acpi_get_physical_device_location(acpi_handle handle, struct acpi_pld_info **pld);
|
||||
#ifdef CONFIG_ACPI
|
||||
|
||||
#include <linux/proc_fs.h>
|
||||
|
@ -208,6 +179,7 @@ struct acpi_device_pnp {
|
|||
struct list_head ids; /* _HID and _CIDs */
|
||||
acpi_device_name device_name; /* Driver-determined */
|
||||
acpi_device_class device_class; /* " */
|
||||
union acpi_object *str_obj; /* unicode string for _STR method */
|
||||
};
|
||||
|
||||
#define acpi_device_bid(d) ((d)->pnp.bus_id)
|
||||
|
@ -282,8 +254,16 @@ struct acpi_device_wakeup {
|
|||
int prepare_count;
|
||||
};
|
||||
|
||||
/* Device */
|
||||
struct acpi_device_physical_node {
|
||||
u8 node_id;
|
||||
struct list_head node;
|
||||
struct device *dev;
|
||||
};
|
||||
|
||||
/* set maximum of physical nodes to 32 for expansibility */
|
||||
#define ACPI_MAX_PHYSICAL_NODE 32
|
||||
|
||||
/* Device */
|
||||
struct acpi_device {
|
||||
int device_type;
|
||||
acpi_handle handle; /* no handle for fixed hardware */
|
||||
|
@ -304,6 +284,10 @@ struct acpi_device {
|
|||
struct device dev;
|
||||
struct acpi_bus_ops bus_ops; /* workaround for different code path for hotplug */
|
||||
enum acpi_bus_removal_type removal_type; /* indicate for different removal type */
|
||||
u8 physical_node_count;
|
||||
struct list_head physical_node_list;
|
||||
struct mutex physical_node_lock;
|
||||
DECLARE_BITMAP(physical_node_id_bitmap, ACPI_MAX_PHYSICAL_NODE);
|
||||
};
|
||||
|
||||
static inline void *acpi_driver_data(struct acpi_device *d)
|
||||
|
@ -381,6 +365,19 @@ int acpi_match_device_ids(struct acpi_device *device,
|
|||
int acpi_create_dir(struct acpi_device *);
|
||||
void acpi_remove_dir(struct acpi_device *);
|
||||
|
||||
|
||||
/**
|
||||
* module_acpi_driver(acpi_driver) - Helper macro for registering an ACPI driver
|
||||
* @__acpi_driver: acpi_driver struct
|
||||
*
|
||||
* Helper macro for ACPI drivers which do not do anything special in module
|
||||
* init/exit. This eliminates a lot of boilerplate. Each module may only
|
||||
* use this macro once, and calling it replaces module_init() and module_exit()
|
||||
*/
|
||||
#define module_acpi_driver(__acpi_driver) \
|
||||
module_driver(__acpi_driver, acpi_bus_register_driver, \
|
||||
acpi_bus_unregister_driver)
|
||||
|
||||
/*
|
||||
* Bind physical devices with ACPI devices
|
||||
*/
|
||||
|
@ -394,7 +391,6 @@ struct acpi_bus_type {
|
|||
};
|
||||
int register_acpi_bus_type(struct acpi_bus_type *);
|
||||
int unregister_acpi_bus_type(struct acpi_bus_type *);
|
||||
struct device *acpi_get_physical_device(acpi_handle);
|
||||
|
||||
struct acpi_pci_root {
|
||||
struct list_head node;
|
||||
|
|
|
@ -47,11 +47,12 @@
|
|||
|
||||
/* Current ACPICA subsystem version in YYYYMMDD format */
|
||||
|
||||
#define ACPI_CA_VERSION 0x20120711
|
||||
#define ACPI_CA_VERSION 0x20120913
|
||||
|
||||
#include <acpi/acconfig.h>
|
||||
#include <acpi/actypes.h>
|
||||
#include <acpi/actbl.h>
|
||||
#include <acpi/acbuffer.h>
|
||||
|
||||
extern u8 acpi_gbl_permanent_mmap;
|
||||
|
||||
|
@ -144,6 +145,10 @@ acpi_check_address_range(acpi_adr_space_type space_id,
|
|||
acpi_physical_address address,
|
||||
acpi_size length, u8 warn);
|
||||
|
||||
acpi_status
|
||||
acpi_decode_pld_buffer(u8 *in_buffer,
|
||||
acpi_size length, struct acpi_pld_info **return_buffer);
|
||||
|
||||
/*
|
||||
* ACPI Memory management
|
||||
*/
|
||||
|
|
|
@ -79,9 +79,15 @@
|
|||
#pragma pack(1)
|
||||
|
||||
/*
|
||||
* Note about bitfields: The u8 type is used for bitfields in ACPI tables.
|
||||
* This is the only type that is even remotely portable. Anything else is not
|
||||
* portable, so do not use any other bitfield types.
|
||||
* Note: C bitfields are not used for this reason:
|
||||
*
|
||||
* "Bitfields are great and easy to read, but unfortunately the C language
|
||||
* does not specify the layout of bitfields in memory, which means they are
|
||||
* essentially useless for dealing with packed data in on-disk formats or
|
||||
* binary wire protocols." (Or ACPI tables and buffers.) "If you ask me,
|
||||
* this decision was a design error in C. Ritchie could have picked an order
|
||||
* and stuck with it." Norman Ramsey.
|
||||
* See http://stackoverflow.com/a/1053662/41661
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
|
@ -94,7 +100,7 @@
|
|||
struct acpi_table_header {
|
||||
char signature[ACPI_NAME_SIZE]; /* ASCII table signature */
|
||||
u32 length; /* Length of table in bytes, including this header */
|
||||
u8 revision; /* ACPI Specification minor version # */
|
||||
u8 revision; /* ACPI Specification minor version number */
|
||||
u8 checksum; /* To make sum of entire table == 0 */
|
||||
char oem_id[ACPI_OEM_ID_SIZE]; /* ASCII OEM identification */
|
||||
char oem_table_id[ACPI_OEM_TABLE_ID_SIZE]; /* ASCII OEM table identification */
|
||||
|
@ -108,7 +114,7 @@ struct acpi_table_header {
|
|||
* GAS - Generic Address Structure (ACPI 2.0+)
|
||||
*
|
||||
* Note: Since this structure is used in the ACPI tables, it is byte aligned.
|
||||
* If misaliged access is not supported by the hardware, accesses to the
|
||||
* If misaligned access is not supported by the hardware, accesses to the
|
||||
* 64-bit Address field must be performed with care.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
@ -210,18 +216,18 @@ struct acpi_table_fadt {
|
|||
u8 preferred_profile; /* Conveys preferred power management profile to OSPM. */
|
||||
u16 sci_interrupt; /* System vector of SCI interrupt */
|
||||
u32 smi_command; /* 32-bit Port address of SMI command port */
|
||||
u8 acpi_enable; /* Value to write to smi_cmd to enable ACPI */
|
||||
u8 acpi_disable; /* Value to write to smi_cmd to disable ACPI */
|
||||
u8 s4_bios_request; /* Value to write to SMI CMD to enter S4BIOS state */
|
||||
u8 acpi_enable; /* Value to write to SMI_CMD to enable ACPI */
|
||||
u8 acpi_disable; /* Value to write to SMI_CMD to disable ACPI */
|
||||
u8 s4_bios_request; /* Value to write to SMI_CMD to enter S4BIOS state */
|
||||
u8 pstate_control; /* Processor performance state control */
|
||||
u32 pm1a_event_block; /* 32-bit Port address of Power Mgt 1a Event Reg Blk */
|
||||
u32 pm1b_event_block; /* 32-bit Port address of Power Mgt 1b Event Reg Blk */
|
||||
u32 pm1a_control_block; /* 32-bit Port address of Power Mgt 1a Control Reg Blk */
|
||||
u32 pm1b_control_block; /* 32-bit Port address of Power Mgt 1b Control Reg Blk */
|
||||
u32 pm2_control_block; /* 32-bit Port address of Power Mgt 2 Control Reg Blk */
|
||||
u32 pm_timer_block; /* 32-bit Port address of Power Mgt Timer Ctrl Reg Blk */
|
||||
u32 gpe0_block; /* 32-bit Port address of General Purpose Event 0 Reg Blk */
|
||||
u32 gpe1_block; /* 32-bit Port address of General Purpose Event 1 Reg Blk */
|
||||
u32 pm1a_event_block; /* 32-bit port address of Power Mgt 1a Event Reg Blk */
|
||||
u32 pm1b_event_block; /* 32-bit port address of Power Mgt 1b Event Reg Blk */
|
||||
u32 pm1a_control_block; /* 32-bit port address of Power Mgt 1a Control Reg Blk */
|
||||
u32 pm1b_control_block; /* 32-bit port address of Power Mgt 1b Control Reg Blk */
|
||||
u32 pm2_control_block; /* 32-bit port address of Power Mgt 2 Control Reg Blk */
|
||||
u32 pm_timer_block; /* 32-bit port address of Power Mgt Timer Ctrl Reg Blk */
|
||||
u32 gpe0_block; /* 32-bit port address of General Purpose Event 0 Reg Blk */
|
||||
u32 gpe1_block; /* 32-bit port address of General Purpose Event 1 Reg Blk */
|
||||
u8 pm1_event_length; /* Byte Length of ports at pm1x_event_block */
|
||||
u8 pm1_control_length; /* Byte Length of ports at pm1x_control_block */
|
||||
u8 pm2_control_length; /* Byte Length of ports at pm2_control_block */
|
||||
|
@ -229,12 +235,12 @@ struct acpi_table_fadt {
|
|||
u8 gpe0_block_length; /* Byte Length of ports at gpe0_block */
|
||||
u8 gpe1_block_length; /* Byte Length of ports at gpe1_block */
|
||||
u8 gpe1_base; /* Offset in GPE number space where GPE1 events start */
|
||||
u8 cst_control; /* Support for the _CST object and C States change notification */
|
||||
u8 cst_control; /* Support for the _CST object and C-States change notification */
|
||||
u16 c2_latency; /* Worst case HW latency to enter/exit C2 state */
|
||||
u16 c3_latency; /* Worst case HW latency to enter/exit C3 state */
|
||||
u16 flush_size; /* Processor's memory cache line width, in bytes */
|
||||
u16 flush_size; /* Processor memory cache line width, in bytes */
|
||||
u16 flush_stride; /* Number of flush strides that need to be read */
|
||||
u8 duty_offset; /* Processor duty cycle index in processor's P_CNT reg */
|
||||
u8 duty_offset; /* Processor duty cycle index in processor P_CNT reg */
|
||||
u8 duty_width; /* Processor duty cycle value bit width in P_CNT register */
|
||||
u8 day_alarm; /* Index to day-of-month alarm in RTC CMOS RAM */
|
||||
u8 month_alarm; /* Index to month-of-year alarm in RTC CMOS RAM */
|
||||
|
@ -255,11 +261,11 @@ struct acpi_table_fadt {
|
|||
struct acpi_generic_address xpm_timer_block; /* 64-bit Extended Power Mgt Timer Ctrl Reg Blk address */
|
||||
struct acpi_generic_address xgpe0_block; /* 64-bit Extended General Purpose Event 0 Reg Blk address */
|
||||
struct acpi_generic_address xgpe1_block; /* 64-bit Extended General Purpose Event 1 Reg Blk address */
|
||||
struct acpi_generic_address sleep_control; /* 64-bit Sleep Control register */
|
||||
struct acpi_generic_address sleep_status; /* 64-bit Sleep Status register */
|
||||
struct acpi_generic_address sleep_control; /* 64-bit Sleep Control register (ACPI 5.0) */
|
||||
struct acpi_generic_address sleep_status; /* 64-bit Sleep Status register (ACPI 5.0) */
|
||||
};
|
||||
|
||||
/* Masks for FADT Boot Architecture Flags (boot_flags) */
|
||||
/* Masks for FADT Boot Architecture Flags (boot_flags) [Vx]=Introduced in this FADT revision */
|
||||
|
||||
#define ACPI_FADT_LEGACY_DEVICES (1) /* 00: [V2] System has LPC or ISA bus devices */
|
||||
#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 {
|
|||
|
||||
/* Masks for FADT flags */
|
||||
|
||||
#define ACPI_FADT_WBINVD (1) /* 00: [V1] The wbinvd instruction works properly */
|
||||
#define ACPI_FADT_WBINVD_FLUSH (1<<1) /* 01: [V1] wbinvd flushes but does not invalidate caches */
|
||||
#define ACPI_FADT_WBINVD (1) /* 00: [V1] The WBINVD instruction works properly */
|
||||
#define ACPI_FADT_WBINVD_FLUSH (1<<1) /* 01: [V1] WBINVD flushes but does not invalidate caches */
|
||||
#define ACPI_FADT_C1_SUPPORTED (1<<2) /* 02: [V1] All processors support C1 state */
|
||||
#define ACPI_FADT_C2_MP_SUPPORTED (1<<3) /* 03: [V1] C2 state works on MP system */
|
||||
#define ACPI_FADT_POWER_BUTTON (1<<4) /* 04: [V1] Power button is handled as a control method device */
|
||||
#define ACPI_FADT_SLEEP_BUTTON (1<<5) /* 05: [V1] Sleep button is handled as a control method device */
|
||||
#define ACPI_FADT_FIXED_RTC (1<<6) /* 06: [V1] RTC wakeup status not in fixed register space */
|
||||
#define ACPI_FADT_FIXED_RTC (1<<6) /* 06: [V1] RTC wakeup status is not in fixed register space */
|
||||
#define ACPI_FADT_S4_RTC_WAKE (1<<7) /* 07: [V1] RTC alarm can wake system from S4 */
|
||||
#define ACPI_FADT_32BIT_TIMER (1<<8) /* 08: [V1] ACPI timer width is 32-bit (0=24-bit) */
|
||||
#define ACPI_FADT_DOCKING_SUPPORTED (1<<9) /* 09: [V1] Docking supported */
|
||||
|
@ -297,7 +303,7 @@ struct acpi_table_fadt {
|
|||
|
||||
/* Values for preferred_profile (Preferred Power Management Profiles) */
|
||||
|
||||
enum acpi_prefered_pm_profiles {
|
||||
enum acpi_preferred_pm_profiles {
|
||||
PM_UNSPECIFIED = 0,
|
||||
PM_DESKTOP = 1,
|
||||
PM_MOBILE = 2,
|
||||
|
@ -335,7 +341,7 @@ union acpi_name_union {
|
|||
struct acpi_table_desc {
|
||||
acpi_physical_address address;
|
||||
struct acpi_table_header *pointer;
|
||||
u32 length; /* Length fixed at 32 bits */
|
||||
u32 length; /* Length fixed at 32 bits (fixed in table header) */
|
||||
union acpi_name_union signature;
|
||||
acpi_owner_id owner_id;
|
||||
u8 flags;
|
||||
|
|
|
@ -79,9 +79,15 @@
|
|||
#pragma pack(1)
|
||||
|
||||
/*
|
||||
* Note about bitfields: The u8 type is used for bitfields in ACPI tables.
|
||||
* This is the only type that is even remotely portable. Anything else is not
|
||||
* portable, so do not use any other bitfield types.
|
||||
* Note: C bitfields are not used for this reason:
|
||||
*
|
||||
* "Bitfields are great and easy to read, but unfortunately the C language
|
||||
* does not specify the layout of bitfields in memory, which means they are
|
||||
* essentially useless for dealing with packed data in on-disk formats or
|
||||
* binary wire protocols." (Or ACPI tables and buffers.) "If you ask me,
|
||||
* this decision was a design error in C. Ritchie could have picked an order
|
||||
* and stuck with it." Norman Ramsey.
|
||||
* See http://stackoverflow.com/a/1053662/41661
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
|
@ -489,7 +495,9 @@ enum acpi_hest_notify_types {
|
|||
ACPI_HEST_NOTIFY_LOCAL = 2,
|
||||
ACPI_HEST_NOTIFY_SCI = 3,
|
||||
ACPI_HEST_NOTIFY_NMI = 4,
|
||||
ACPI_HEST_NOTIFY_RESERVED = 5 /* 5 and greater are reserved */
|
||||
ACPI_HEST_NOTIFY_CMCI = 5, /* ACPI 5.0 */
|
||||
ACPI_HEST_NOTIFY_MCE = 6, /* ACPI 5.0 */
|
||||
ACPI_HEST_NOTIFY_RESERVED = 7 /* 7 and greater are reserved */
|
||||
};
|
||||
|
||||
/* Values for config_write_enable bitfield above */
|
||||
|
|
|
@ -63,6 +63,8 @@
|
|||
*/
|
||||
#define ACPI_SIG_ASF "ASF!" /* Alert Standard Format table */
|
||||
#define ACPI_SIG_BOOT "BOOT" /* Simple Boot Flag Table */
|
||||
#define ACPI_SIG_CSRT "CSRT" /* Core System Resource Table */
|
||||
#define ACPI_SIG_DBG2 "DBG2" /* Debug Port table type 2 */
|
||||
#define ACPI_SIG_DBGP "DBGP" /* Debug Port table */
|
||||
#define ACPI_SIG_DMAR "DMAR" /* DMA Remapping table */
|
||||
#define ACPI_SIG_HPET "HPET" /* High Precision Event Timer table */
|
||||
|
@ -96,9 +98,15 @@
|
|||
#pragma pack(1)
|
||||
|
||||
/*
|
||||
* Note about bitfields: The u8 type is used for bitfields in ACPI tables.
|
||||
* This is the only type that is even remotely portable. Anything else is not
|
||||
* portable, so do not use any other bitfield types.
|
||||
* Note: C bitfields are not used for this reason:
|
||||
*
|
||||
* "Bitfields are great and easy to read, but unfortunately the C language
|
||||
* does not specify the layout of bitfields in memory, which means they are
|
||||
* essentially useless for dealing with packed data in on-disk formats or
|
||||
* binary wire protocols." (Or ACPI tables and buffers.) "If you ask me,
|
||||
* this decision was a design error in C. Ritchie could have picked an order
|
||||
* and stuck with it." Norman Ramsey.
|
||||
* See http://stackoverflow.com/a/1053662/41661
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
|
@ -230,6 +238,115 @@ struct acpi_table_boot {
|
|||
u8 reserved[3];
|
||||
};
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* CSRT - Core System Resource Table
|
||||
* Version 0
|
||||
*
|
||||
* Conforms to the "Core System Resource Table (CSRT)", November 14, 2011
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
struct acpi_table_csrt {
|
||||
struct acpi_table_header header; /* Common ACPI table header */
|
||||
};
|
||||
|
||||
/* Resource Group subtable */
|
||||
|
||||
struct acpi_csrt_group {
|
||||
u32 length;
|
||||
u32 vendor_id;
|
||||
u32 subvendor_id;
|
||||
u16 device_id;
|
||||
u16 subdevice_id;
|
||||
u16 revision;
|
||||
u16 reserved;
|
||||
u32 info_length;
|
||||
|
||||
/* Shared data (length = info_length) immediately follows */
|
||||
};
|
||||
|
||||
/* Resource Descriptor subtable */
|
||||
|
||||
struct acpi_csrt_descriptor {
|
||||
u32 length;
|
||||
u16 type;
|
||||
u16 subtype;
|
||||
u32 uid;
|
||||
|
||||
/* Resource-specific information immediately follows */
|
||||
};
|
||||
|
||||
/* Resource Types */
|
||||
|
||||
#define ACPI_CSRT_TYPE_INTERRUPT 0x0001
|
||||
#define ACPI_CSRT_TYPE_TIMER 0x0002
|
||||
#define ACPI_CSRT_TYPE_DMA 0x0003
|
||||
|
||||
/* Resource Subtypes */
|
||||
|
||||
#define ACPI_CSRT_XRUPT_LINE 0x0000
|
||||
#define ACPI_CSRT_XRUPT_CONTROLLER 0x0001
|
||||
#define ACPI_CSRT_TIMER 0x0000
|
||||
#define ACPI_CSRT_DMA_CHANNEL 0x0000
|
||||
#define ACPI_CSRT_DMA_CONTROLLER 0x0001
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* DBG2 - Debug Port Table 2
|
||||
* Version 0 (Both main table and subtables)
|
||||
*
|
||||
* Conforms to "Microsoft Debug Port Table 2 (DBG2)", May 22 2012.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
struct acpi_table_dbg2 {
|
||||
struct acpi_table_header header; /* Common ACPI table header */
|
||||
u32 info_offset;
|
||||
u32 info_count;
|
||||
};
|
||||
|
||||
/* Debug Device Information Subtable */
|
||||
|
||||
struct acpi_dbg2_device {
|
||||
u8 revision;
|
||||
u16 length;
|
||||
u8 register_count; /* Number of base_address registers */
|
||||
u16 namepath_length;
|
||||
u16 namepath_offset;
|
||||
u16 oem_data_length;
|
||||
u16 oem_data_offset;
|
||||
u16 port_type;
|
||||
u16 port_subtype;
|
||||
u16 reserved;
|
||||
u16 base_address_offset;
|
||||
u16 address_size_offset;
|
||||
/*
|
||||
* Data that follows:
|
||||
* base_address (required) - Each in 12-byte Generic Address Structure format.
|
||||
* address_size (required) - Array of u32 sizes corresponding to each base_address register.
|
||||
* Namepath (required) - Null terminated string. Single dot if not supported.
|
||||
* oem_data (optional) - Length is oem_data_length.
|
||||
*/
|
||||
};
|
||||
|
||||
/* Types for port_type field above */
|
||||
|
||||
#define ACPI_DBG2_SERIAL_PORT 0x8000
|
||||
#define ACPI_DBG2_1394_PORT 0x8001
|
||||
#define ACPI_DBG2_USB_PORT 0x8002
|
||||
#define ACPI_DBG2_NET_PORT 0x8003
|
||||
|
||||
/* Subtypes for port_subtype field above */
|
||||
|
||||
#define ACPI_DBG2_16550_COMPATIBLE 0x0000
|
||||
#define ACPI_DBG2_16550_SUBSET 0x0001
|
||||
|
||||
#define ACPI_DBG2_1394_STANDARD 0x0000
|
||||
|
||||
#define ACPI_DBG2_USB_XHCI 0x0000
|
||||
#define ACPI_DBG2_USB_EHCI 0x0001
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* DBGP - Debug Port table
|
||||
|
|
|
@ -75,7 +75,6 @@
|
|||
/* Reserved table signatures */
|
||||
|
||||
#define ACPI_SIG_CSRT "CSRT" /* Core System Resources Table */
|
||||
#define ACPI_SIG_DBG2 "DBG2" /* Debug Port table 2 */
|
||||
#define ACPI_SIG_MATR "MATR" /* Memory Address Translation Table */
|
||||
#define ACPI_SIG_MSDM "MSDM" /* Microsoft Data Management Table */
|
||||
#define ACPI_SIG_WPBT "WPBT" /* Windows Platform Binary Table */
|
||||
|
@ -87,9 +86,15 @@
|
|||
#pragma pack(1)
|
||||
|
||||
/*
|
||||
* Note about bitfields: The u8 type is used for bitfields in ACPI tables.
|
||||
* This is the only type that is even remotely portable. Anything else is not
|
||||
* portable, so do not use any other bitfield types.
|
||||
* Note: C bitfields are not used for this reason:
|
||||
*
|
||||
* "Bitfields are great and easy to read, but unfortunately the C language
|
||||
* does not specify the layout of bitfields in memory, which means they are
|
||||
* essentially useless for dealing with packed data in on-disk formats or
|
||||
* binary wire protocols." (Or ACPI tables and buffers.) "If you ask me,
|
||||
* this decision was a design error in C. Ritchie could have picked an order
|
||||
* and stuck with it." Norman Ramsey.
|
||||
* See http://stackoverflow.com/a/1053662/41661
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
|
|
|
@ -518,13 +518,6 @@ typedef u64 acpi_integer;
|
|||
#define ACPI_SLEEP_TYPE_MAX 0x7
|
||||
#define ACPI_SLEEP_TYPE_INVALID 0xFF
|
||||
|
||||
/*
|
||||
* Sleep/Wake flags
|
||||
*/
|
||||
#define ACPI_NO_OPTIONAL_METHODS 0x00 /* Do not execute any optional methods */
|
||||
#define ACPI_EXECUTE_GTS 0x01 /* For enter sleep interface */
|
||||
#define ACPI_EXECUTE_BFS 0x02 /* For leave sleep prep interface */
|
||||
|
||||
/*
|
||||
* Standard notify values
|
||||
*/
|
||||
|
|
18
tools/power/acpi/Makefile
Normal file
18
tools/power/acpi/Makefile
Normal file
|
@ -0,0 +1,18 @@
|
|||
PROG= acpidump
|
||||
SRCS= acpidump.c
|
||||
KERNEL_INCLUDE := ../../../include
|
||||
CFLAGS += -Wall -Wstrict-prototypes -Wdeclaration-after-statement -Os -s -D_LINUX -DDEFINE_ALTERNATE_TYPES -I$(KERNEL_INCLUDE)
|
||||
|
||||
all: acpidump
|
||||
$(PROG) : $(SRCS)
|
||||
$(CC) $(CFLAGS) $(SRCS) -o $(PROG)
|
||||
|
||||
CLEANFILES= $(PROG)
|
||||
|
||||
clean :
|
||||
rm -f $(CLEANFILES) $(patsubst %.c,%.o, $(SRCS)) *~
|
||||
|
||||
install :
|
||||
install acpidump /usr/bin/acpidump
|
||||
install acpidump.8 /usr/share/man/man8
|
||||
|
59
tools/power/acpi/acpidump.8
Normal file
59
tools/power/acpi/acpidump.8
Normal file
|
@ -0,0 +1,59 @@
|
|||
.TH ACPIDUMP 8
|
||||
.SH NAME
|
||||
acpidump \- Dump system's ACPI tables to an ASCII file.
|
||||
.SH SYNOPSIS
|
||||
.ft B
|
||||
.B acpidump > acpidump.out
|
||||
.SH DESCRIPTION
|
||||
\fBacpidump \fP dumps the systems ACPI tables to an ASCII file
|
||||
appropriate for attaching to a bug report.
|
||||
|
||||
Subsequently, they can be processed by utilities in the ACPICA package.
|
||||
.SS Options
|
||||
no options worth worrying about.
|
||||
.PP
|
||||
.SH EXAMPLE
|
||||
|
||||
.nf
|
||||
# acpidump > acpidump.out
|
||||
|
||||
$ acpixtract -a acpidump.out
|
||||
Acpi table [DSDT] - 15974 bytes written to DSDT.dat
|
||||
Acpi table [FACS] - 64 bytes written to FACS.dat
|
||||
Acpi table [FACP] - 116 bytes written to FACP.dat
|
||||
Acpi table [APIC] - 120 bytes written to APIC.dat
|
||||
Acpi table [MCFG] - 60 bytes written to MCFG.dat
|
||||
Acpi table [SSDT] - 444 bytes written to SSDT1.dat
|
||||
Acpi table [SSDT] - 439 bytes written to SSDT2.dat
|
||||
Acpi table [SSDT] - 439 bytes written to SSDT3.dat
|
||||
Acpi table [SSDT] - 439 bytes written to SSDT4.dat
|
||||
Acpi table [SSDT] - 439 bytes written to SSDT5.dat
|
||||
Acpi table [RSDT] - 76 bytes written to RSDT.dat
|
||||
Acpi table [RSDP] - 20 bytes written to RSDP.dat
|
||||
|
||||
$ iasl -d *.dat
|
||||
...
|
||||
.fi
|
||||
creates *.dsl, a human readable form which can be edited
|
||||
and compiled using iasl.
|
||||
|
||||
|
||||
.SH NOTES
|
||||
|
||||
.B "acpidump "
|
||||
must be run as root.
|
||||
|
||||
.SH REFERENCES
|
||||
ACPICA: https://acpica.org/
|
||||
|
||||
.SH FILES
|
||||
.ta
|
||||
.nf
|
||||
/dev/mem
|
||||
/sys/firmware/acpi/tables/dynamic/*
|
||||
.fi
|
||||
|
||||
.PP
|
||||
.SH AUTHOR
|
||||
.nf
|
||||
Written by Len Brown <len.brown@intel.com>
|
560
tools/power/acpi/acpidump.c
Normal file
560
tools/power/acpi/acpidump.c
Normal file
|
@ -0,0 +1,560 @@
|
|||
/*
|
||||
* (c) Alexey Starikovskiy, Intel, 2005-2006.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions, and the following disclaimer,
|
||||
* without modification.
|
||||
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
|
||||
* substantially similar to the "NO WARRANTY" disclaimer below
|
||||
* ("Disclaimer") and any redistribution must be conditioned upon
|
||||
* including a substantially similar Disclaimer requirement for further
|
||||
* binary redistribution.
|
||||
* 3. Neither the names of the above-listed copyright holders nor the names
|
||||
* of any contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* Alternatively, this software may be distributed under the terms of the
|
||||
* GNU General Public License ("GPL") version 2 as published by the Free
|
||||
* Software Foundation.
|
||||
*
|
||||
* NO WARRANTY
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGES.
|
||||
*/
|
||||
|
||||
#ifdef DEFINE_ALTERNATE_TYPES
|
||||
/* hack to enable building old application with new headers -lenb */
|
||||
#define acpi_fadt_descriptor acpi_table_fadt
|
||||
#define acpi_rsdp_descriptor acpi_table_rsdp
|
||||
#define DSDT_SIG ACPI_SIG_DSDT
|
||||
#define FACS_SIG ACPI_SIG_FACS
|
||||
#define FADT_SIG ACPI_SIG_FADT
|
||||
#define xfirmware_ctrl Xfacs
|
||||
#define firmware_ctrl facs
|
||||
|
||||
typedef int s32;
|
||||
typedef unsigned char u8;
|
||||
typedef unsigned short u16;
|
||||
typedef unsigned int u32;
|
||||
typedef unsigned long long u64;
|
||||
typedef long long s64;
|
||||
#endif
|
||||
|
||||
#include <sys/mman.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <getopt.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
|
||||
#include <acpi/acconfig.h>
|
||||
#include <acpi/platform/acenv.h>
|
||||
#include <acpi/actypes.h>
|
||||
#include <acpi/actbl.h>
|
||||
|
||||
static inline u8 checksum(u8 * buffer, u32 length)
|
||||
{
|
||||
u8 sum = 0, *i = buffer;
|
||||
buffer += length;
|
||||
for (; i < buffer; sum += *(i++));
|
||||
return sum;
|
||||
}
|
||||
|
||||
static unsigned long psz, addr, length;
|
||||
static int print, connect, skip;
|
||||
static u8 select_sig[4];
|
||||
|
||||
static unsigned long read_efi_systab( void )
|
||||
{
|
||||
char buffer[80];
|
||||
unsigned long addr;
|
||||
FILE *f = fopen("/sys/firmware/efi/systab", "r");
|
||||
if (f) {
|
||||
while (fgets(buffer, 80, f)) {
|
||||
if (sscanf(buffer, "ACPI20=0x%lx", &addr) == 1)
|
||||
return addr;
|
||||
}
|
||||
fclose(f);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u8 *acpi_map_memory(unsigned long where, unsigned length)
|
||||
{
|
||||
unsigned long offset;
|
||||
u8 *there;
|
||||
int fd = open("/dev/mem", O_RDONLY);
|
||||
if (fd < 0) {
|
||||
fprintf(stderr, "acpi_os_map_memory: cannot open /dev/mem\n");
|
||||
exit(1);
|
||||
}
|
||||
offset = where % psz;
|
||||
there = mmap(NULL, length + offset, PROT_READ, MAP_PRIVATE,
|
||||
fd, where - offset);
|
||||
close(fd);
|
||||
if (there == MAP_FAILED) return 0;
|
||||
return (there + offset);
|
||||
}
|
||||
|
||||
static void acpi_unmap_memory(u8 * there, unsigned length)
|
||||
{
|
||||
unsigned long offset = (unsigned long)there % psz;
|
||||
munmap(there - offset, length + offset);
|
||||
}
|
||||
|
||||
static struct acpi_table_header *acpi_map_table(unsigned long where, char *sig)
|
||||
{
|
||||
unsigned size;
|
||||
struct acpi_table_header *tbl = (struct acpi_table_header *)
|
||||
acpi_map_memory(where, sizeof(struct acpi_table_header));
|
||||
if (!tbl || (sig && memcmp(sig, tbl->signature, 4))) return 0;
|
||||
size = tbl->length;
|
||||
acpi_unmap_memory((u8 *) tbl, sizeof(struct acpi_table_header));
|
||||
return (struct acpi_table_header *)acpi_map_memory(where, size);
|
||||
}
|
||||
|
||||
static void acpi_unmap_table(struct acpi_table_header *tbl)
|
||||
{
|
||||
acpi_unmap_memory((u8 *)tbl, tbl->length);
|
||||
}
|
||||
|
||||
static struct acpi_rsdp_descriptor *acpi_scan_for_rsdp(u8 *begin, u32 length)
|
||||
{
|
||||
struct acpi_rsdp_descriptor *rsdp;
|
||||
u8 *i, *end = begin + length;
|
||||
/* Search from given start address for the requested length */
|
||||
for (i = begin; i < end; i += ACPI_RSDP_SCAN_STEP) {
|
||||
/* The signature and checksum must both be correct */
|
||||
if (memcmp((char *)i, "RSD PTR ", 8)) continue;
|
||||
rsdp = (struct acpi_rsdp_descriptor *)i;
|
||||
/* Signature matches, check the appropriate checksum */
|
||||
if (!checksum((u8 *) rsdp, (rsdp->revision < 2) ?
|
||||
ACPI_RSDP_CHECKSUM_LENGTH :
|
||||
ACPI_RSDP_XCHECKSUM_LENGTH))
|
||||
/* Checksum valid, we have found a valid RSDP */
|
||||
return rsdp;
|
||||
}
|
||||
/* Searched entire block, no RSDP was found */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Output data
|
||||
*/
|
||||
static void acpi_show_data(int fd, u8 * data, int size)
|
||||
{
|
||||
char buffer[256];
|
||||
int len;
|
||||
int i, remain = size;
|
||||
while (remain > 0) {
|
||||
len = snprintf(buffer, 256, " %04x:", size - remain);
|
||||
for (i = 0; i < 16 && i < remain; i++) {
|
||||
len +=
|
||||
snprintf(&buffer[len], 256 - len, " %02x", data[i]);
|
||||
}
|
||||
for (; i < 16; i++) {
|
||||
len += snprintf(&buffer[len], 256 - len, " ");
|
||||
}
|
||||
len += snprintf(&buffer[len], 256 - len, " ");
|
||||
for (i = 0; i < 16 && i < remain; i++) {
|
||||
buffer[len++] = (isprint(data[i])) ? data[i] : '.';
|
||||
}
|
||||
buffer[len++] = '\n';
|
||||
write(fd, buffer, len);
|
||||
data += 16;
|
||||
remain -= 16;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Output ACPI table
|
||||
*/
|
||||
static void acpi_show_table(int fd, struct acpi_table_header *table, unsigned long addr)
|
||||
{
|
||||
char buff[80];
|
||||
int len = snprintf(buff, 80, "%.4s @ %p\n", table->signature, (void *)addr);
|
||||
write(fd, buff, len);
|
||||
acpi_show_data(fd, (u8 *) table, table->length);
|
||||
buff[0] = '\n';
|
||||
write(fd, buff, 1);
|
||||
}
|
||||
|
||||
static void write_table(int fd, struct acpi_table_header *tbl, unsigned long addr)
|
||||
{
|
||||
static int select_done = 0;
|
||||
if (!select_sig[0]) {
|
||||
if (print) {
|
||||
acpi_show_table(fd, tbl, addr);
|
||||
} else {
|
||||
write(fd, tbl, tbl->length);
|
||||
}
|
||||
} else if (!select_done && !memcmp(select_sig, tbl->signature, 4)) {
|
||||
if (skip > 0) {
|
||||
--skip;
|
||||
return;
|
||||
}
|
||||
if (print) {
|
||||
acpi_show_table(fd, tbl, addr);
|
||||
} else {
|
||||
write(fd, tbl, tbl->length);
|
||||
}
|
||||
select_done = 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void acpi_dump_FADT(int fd, struct acpi_table_header *tbl, unsigned long xaddr) {
|
||||
struct acpi_fadt_descriptor x;
|
||||
unsigned long addr;
|
||||
size_t len = sizeof(struct acpi_fadt_descriptor);
|
||||
if (len > tbl->length) len = tbl->length;
|
||||
memcpy(&x, tbl, len);
|
||||
x.header.length = len;
|
||||
if (checksum((u8 *)tbl, len)) {
|
||||
fprintf(stderr, "Wrong checksum for FADT!\n");
|
||||
}
|
||||
if (x.header.length >= 148 && x.Xdsdt) {
|
||||
addr = (unsigned long)x.Xdsdt;
|
||||
if (connect) {
|
||||
x.Xdsdt = lseek(fd, 0, SEEK_CUR);
|
||||
}
|
||||
} else if (x.header.length >= 44 && x.dsdt) {
|
||||
addr = (unsigned long)x.dsdt;
|
||||
if (connect) {
|
||||
x.dsdt = lseek(fd, 0, SEEK_CUR);
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "No DSDT in FADT!\n");
|
||||
goto no_dsdt;
|
||||
}
|
||||
tbl = acpi_map_table(addr, DSDT_SIG);
|
||||
if (!tbl) goto no_dsdt;
|
||||
if (checksum((u8 *)tbl, tbl->length))
|
||||
fprintf(stderr, "Wrong checksum for DSDT!\n");
|
||||
write_table(fd, tbl, addr);
|
||||
acpi_unmap_table(tbl);
|
||||
no_dsdt:
|
||||
if (x.header.length >= 140 && x.xfirmware_ctrl) {
|
||||
addr = (unsigned long)x.xfirmware_ctrl;
|
||||
if (connect) {
|
||||
x.xfirmware_ctrl = lseek(fd, 0, SEEK_CUR);
|
||||
}
|
||||
} else if (x.header.length >= 40 && x.firmware_ctrl) {
|
||||
addr = (unsigned long)x.firmware_ctrl;
|
||||
if (connect) {
|
||||
x.firmware_ctrl = lseek(fd, 0, SEEK_CUR);
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "No FACS in FADT!\n");
|
||||
goto no_facs;
|
||||
}
|
||||
tbl = acpi_map_table(addr, FACS_SIG);
|
||||
if (!tbl) goto no_facs;
|
||||
/* do not checksum FACS */
|
||||
write_table(fd, tbl, addr);
|
||||
acpi_unmap_table(tbl);
|
||||
no_facs:
|
||||
write_table(fd, (struct acpi_table_header *)&x, xaddr);
|
||||
}
|
||||
|
||||
static int acpi_dump_SDT(int fd, struct acpi_rsdp_descriptor *rsdp)
|
||||
{
|
||||
struct acpi_table_header *sdt, *tbl = 0;
|
||||
int xsdt = 1, i, num;
|
||||
char *offset;
|
||||
unsigned long addr;
|
||||
if (rsdp->revision > 1 && rsdp->xsdt_physical_address) {
|
||||
tbl = acpi_map_table(rsdp->xsdt_physical_address, "XSDT");
|
||||
}
|
||||
if (!tbl && rsdp->rsdt_physical_address) {
|
||||
xsdt = 0;
|
||||
tbl = acpi_map_table(rsdp->rsdt_physical_address, "RSDT");
|
||||
}
|
||||
if (!tbl) return 0;
|
||||
sdt = malloc(tbl->length);
|
||||
memcpy(sdt, tbl, tbl->length);
|
||||
acpi_unmap_table(tbl);
|
||||
if (checksum((u8 *)sdt, sdt->length))
|
||||
fprintf(stderr, "Wrong checksum for %s!\n", (xsdt)?"XSDT":"RSDT");
|
||||
num = (sdt->length - sizeof(struct acpi_table_header))/((xsdt)?sizeof(u64):sizeof(u32));
|
||||
offset = (char *)sdt + sizeof(struct acpi_table_header);
|
||||
for (i = 0; i < num; ++i, offset += ((xsdt) ? sizeof(u64) : sizeof(u32))) {
|
||||
addr = (xsdt) ? (unsigned long)(*(u64 *)offset):
|
||||
(unsigned long)(*(u32 *)offset);
|
||||
if (!addr) continue;
|
||||
tbl = acpi_map_table(addr, 0);
|
||||
if (!tbl) continue;
|
||||
if (!memcmp(tbl->signature, FADT_SIG, 4)) {
|
||||
acpi_dump_FADT(fd, tbl, addr);
|
||||
} else {
|
||||
if (checksum((u8 *)tbl, tbl->length))
|
||||
fprintf(stderr, "Wrong checksum for generic table!\n");
|
||||
write_table(fd, tbl, addr);
|
||||
}
|
||||
acpi_unmap_table(tbl);
|
||||
if (connect) {
|
||||
if (xsdt)
|
||||
(*(u64*)offset) = lseek(fd, 0, SEEK_CUR);
|
||||
else
|
||||
(*(u32*)offset) = lseek(fd, 0, SEEK_CUR);
|
||||
}
|
||||
}
|
||||
if (xsdt) {
|
||||
addr = (unsigned long)rsdp->xsdt_physical_address;
|
||||
if (connect) {
|
||||
rsdp->xsdt_physical_address = lseek(fd, 0, SEEK_CUR);
|
||||
}
|
||||
} else {
|
||||
addr = (unsigned long)rsdp->rsdt_physical_address;
|
||||
if (connect) {
|
||||
rsdp->rsdt_physical_address = lseek(fd, 0, SEEK_CUR);
|
||||
}
|
||||
}
|
||||
write_table(fd, sdt, addr);
|
||||
free (sdt);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define DYNAMIC_SSDT "/sys/firmware/acpi/tables/dynamic"
|
||||
|
||||
static void acpi_dump_dynamic_SSDT(int fd)
|
||||
{
|
||||
struct stat file_stat;
|
||||
char filename[256], *ptr;
|
||||
DIR *tabledir;
|
||||
struct dirent *entry;
|
||||
FILE *fp;
|
||||
int count, readcount, length;
|
||||
struct acpi_table_header table_header, *ptable;
|
||||
|
||||
if (stat(DYNAMIC_SSDT, &file_stat) == -1) {
|
||||
/* The directory doesn't exist */
|
||||
return;
|
||||
}
|
||||
tabledir = opendir(DYNAMIC_SSDT);
|
||||
if(!tabledir){
|
||||
/*can't open the directory */
|
||||
return;
|
||||
}
|
||||
|
||||
while ((entry = readdir(tabledir)) != 0){
|
||||
/* skip the file of . /.. */
|
||||
if (entry->d_name[0] == '.')
|
||||
continue;
|
||||
|
||||
sprintf(filename, "%s/%s", DYNAMIC_SSDT, entry->d_name);
|
||||
fp = fopen(filename, "r");
|
||||
if (fp == NULL) {
|
||||
fprintf(stderr, "Can't open the file of %s\n",
|
||||
filename);
|
||||
continue;
|
||||
}
|
||||
/* Read the Table header to parse the table length */
|
||||
count = fread(&table_header, 1, sizeof(struct acpi_table_header), fp);
|
||||
if (count < sizeof(table_header)) {
|
||||
/* the length is lessn than ACPI table header. skip it */
|
||||
fclose(fp);
|
||||
continue;
|
||||
}
|
||||
length = table_header.length;
|
||||
ptr = malloc(table_header.length);
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
readcount = 0;
|
||||
while(!feof(fp) && readcount < length) {
|
||||
count = fread(ptr + readcount, 1, 256, fp);
|
||||
readcount += count;
|
||||
}
|
||||
fclose(fp);
|
||||
ptable = (struct acpi_table_header *) ptr;
|
||||
if (checksum((u8 *) ptable, ptable->length))
|
||||
fprintf(stderr, "Wrong checksum "
|
||||
"for dynamic SSDT table!\n");
|
||||
write_table(fd, ptable, 0);
|
||||
free(ptr);
|
||||
}
|
||||
closedir(tabledir);
|
||||
return;
|
||||
}
|
||||
|
||||
static void usage(const char *progname)
|
||||
{
|
||||
puts("Usage:");
|
||||
printf("%s [--addr 0x1234][--table DSDT][--output filename]"
|
||||
"[--binary][--length 0x456][--help]\n", progname);
|
||||
puts("\t--addr 0x1234 or -a 0x1234 -- look for tables at this physical address");
|
||||
puts("\t--table DSDT or -t DSDT -- only dump table with DSDT signature");
|
||||
puts("\t--output filename or -o filename -- redirect output from stdin to filename");
|
||||
puts("\t--binary or -b -- dump data in binary form rather than in hex-dump format");
|
||||
puts("\t--length 0x456 or -l 0x456 -- works only with --addr, dump physical memory"
|
||||
"\n\t\tregion without trying to understand it's contents");
|
||||
puts("\t--skip 2 or -s 2 -- skip 2 tables of the given name and output only 3rd one");
|
||||
puts("\t--help or -h -- this help message");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
static struct option long_options[] = {
|
||||
{"addr", 1, 0, 0},
|
||||
{"table", 1, 0, 0},
|
||||
{"output", 1, 0, 0},
|
||||
{"binary", 0, 0, 0},
|
||||
{"length", 1, 0, 0},
|
||||
{"skip", 1, 0, 0},
|
||||
{"help", 0, 0, 0},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int option_index, c, fd;
|
||||
u8 *raw;
|
||||
struct acpi_rsdp_descriptor rsdpx, *x = 0;
|
||||
char *filename = 0;
|
||||
char buff[80];
|
||||
memset(select_sig, 0, 4);
|
||||
print = 1;
|
||||
connect = 0;
|
||||
addr = length = 0;
|
||||
skip = 0;
|
||||
while (1) {
|
||||
option_index = 0;
|
||||
c = getopt_long(argc, argv, "a:t:o:bl:s:h",
|
||||
long_options, &option_index);
|
||||
if (c == -1)
|
||||
break;
|
||||
|
||||
switch (c) {
|
||||
case 0:
|
||||
switch (option_index) {
|
||||
case 0:
|
||||
addr = strtoul(optarg, (char **)NULL, 16);
|
||||
break;
|
||||
case 1:
|
||||
memcpy(select_sig, optarg, 4);
|
||||
break;
|
||||
case 2:
|
||||
filename = optarg;
|
||||
break;
|
||||
case 3:
|
||||
print = 0;
|
||||
break;
|
||||
case 4:
|
||||
length = strtoul(optarg, (char **)NULL, 16);
|
||||
break;
|
||||
case 5:
|
||||
skip = strtoul(optarg, (char **)NULL, 10);
|
||||
break;
|
||||
case 6:
|
||||
usage(argv[0]);
|
||||
exit(0);
|
||||
}
|
||||
break;
|
||||
case 'a':
|
||||
addr = strtoul(optarg, (char **)NULL, 16);
|
||||
break;
|
||||
case 't':
|
||||
memcpy(select_sig, optarg, 4);
|
||||
break;
|
||||
case 'o':
|
||||
filename = optarg;
|
||||
break;
|
||||
case 'b':
|
||||
print = 0;
|
||||
break;
|
||||
case 'l':
|
||||
length = strtoul(optarg, (char **)NULL, 16);
|
||||
break;
|
||||
case 's':
|
||||
skip = strtoul(optarg, (char **)NULL, 10);
|
||||
break;
|
||||
case 'h':
|
||||
usage(argv[0]);
|
||||
exit(0);
|
||||
default:
|
||||
printf("Unknown option!\n");
|
||||
usage(argv[0]);
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
fd = STDOUT_FILENO;
|
||||
if (filename) {
|
||||
fd = creat(filename, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
|
||||
if (fd < 0)
|
||||
return fd;
|
||||
}
|
||||
|
||||
if (!select_sig[0] && !print) {
|
||||
connect = 1;
|
||||
}
|
||||
|
||||
psz = sysconf(_SC_PAGESIZE);
|
||||
if (length && addr) {
|
||||
/* We know length and address, it means we just want a memory dump */
|
||||
if (!(raw = acpi_map_memory(addr, length)))
|
||||
goto not_found;
|
||||
write(fd, raw, length);
|
||||
acpi_unmap_memory(raw, length);
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
length = sizeof(struct acpi_rsdp_descriptor);
|
||||
if (!addr) {
|
||||
addr = read_efi_systab();
|
||||
if (!addr) {
|
||||
addr = ACPI_HI_RSDP_WINDOW_BASE;
|
||||
length = ACPI_HI_RSDP_WINDOW_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(raw = acpi_map_memory(addr, length)) ||
|
||||
!(x = acpi_scan_for_rsdp(raw, length)))
|
||||
goto not_found;
|
||||
|
||||
/* Find RSDP and print all found tables */
|
||||
memcpy(&rsdpx, x, sizeof(struct acpi_rsdp_descriptor));
|
||||
acpi_unmap_memory(raw, length);
|
||||
if (connect) {
|
||||
lseek(fd, sizeof(struct acpi_rsdp_descriptor), SEEK_SET);
|
||||
}
|
||||
if (!acpi_dump_SDT(fd, &rsdpx))
|
||||
goto not_found;
|
||||
if (connect) {
|
||||
lseek(fd, 0, SEEK_SET);
|
||||
write(fd, x, (rsdpx.revision < 2) ?
|
||||
ACPI_RSDP_CHECKSUM_LENGTH : ACPI_RSDP_XCHECKSUM_LENGTH);
|
||||
} else if (!select_sig[0] || !memcmp("RSD PTR ", select_sig, 4)) {
|
||||
addr += (long)x - (long)raw;
|
||||
length = snprintf(buff, 80, "RSD PTR @ %p\n", (void *)addr);
|
||||
write(fd, buff, length);
|
||||
acpi_show_data(fd, (u8 *) & rsdpx, (rsdpx.revision < 2) ?
|
||||
ACPI_RSDP_CHECKSUM_LENGTH : ACPI_RSDP_XCHECKSUM_LENGTH);
|
||||
buff[0] = '\n';
|
||||
write(fd, buff, 1);
|
||||
}
|
||||
acpi_dump_dynamic_SSDT(fd);
|
||||
close(fd);
|
||||
return 0;
|
||||
not_found:
|
||||
close(fd);
|
||||
fprintf(stderr, "ACPI tables were not found. If you know location "
|
||||
"of RSD PTR table (from dmesg, etc), "
|
||||
"supply it with either --addr or -a option\n");
|
||||
return 1;
|
||||
}
|
|
@ -4,15 +4,11 @@ turbostat \- Report processor frequency and idle statistics
|
|||
.SH SYNOPSIS
|
||||
.ft B
|
||||
.B turbostat
|
||||
.RB [ "\-s" ]
|
||||
.RB [ "\-v" ]
|
||||
.RB [ "\-M MSR#" ]
|
||||
.RB [ Options ]
|
||||
.RB command
|
||||
.br
|
||||
.B turbostat
|
||||
.RB [ "\-s" ]
|
||||
.RB [ "\-v" ]
|
||||
.RB [ "\-M MSR#" ]
|
||||
.RB [ Options ]
|
||||
.RB [ "\-i interval_sec" ]
|
||||
.SH DESCRIPTION
|
||||
\fBturbostat \fP reports processor topology, frequency
|
||||
|
@ -27,16 +23,23 @@ supports an "invariant" TSC, plus the APERF and MPERF MSRs.
|
|||
on processors that additionally support C-state residency counters.
|
||||
|
||||
.SS Options
|
||||
The \fB-s\fP option limits output to a 1-line system summary for each interval.
|
||||
The \fB-p\fP option limits output to the 1st thread in 1st core of each package.
|
||||
.PP
|
||||
The \fB-c\fP option limits output to the 1st thread in each core.
|
||||
The \fB-P\fP option limits output to the 1st thread in each Package.
|
||||
.PP
|
||||
The \fB-p\fP option limits output to the 1st thread in each package.
|
||||
The \fB-S\fP option limits output to a 1-line System Summary for each interval.
|
||||
.PP
|
||||
The \fB-v\fP option increases verbosity.
|
||||
.PP
|
||||
The \fB-M MSR#\fP option dumps the specified MSR,
|
||||
in addition to the usual frequency and idle statistics.
|
||||
The \fB-s\fP option prints the SMI counter, equivalent to "-c 0x34"
|
||||
.PP
|
||||
The \fB-c MSR#\fP option includes the delta of the specified 32-bit MSR counter.
|
||||
.PP
|
||||
The \fB-C MSR#\fP option includes the delta of the specified 64-bit MSR counter.
|
||||
.PP
|
||||
The \fB-m MSR#\fP option includes the the specified 32-bit MSR value.
|
||||
.PP
|
||||
The \fB-M MSR#\fP option includes the the specified 64-bit MSR value.
|
||||
.PP
|
||||
The \fB-i interval_sec\fP option prints statistics every \fiinterval_sec\fP seconds.
|
||||
The default is 5 seconds.
|
||||
|
@ -150,6 +153,29 @@ Note that turbostat reports average GHz of 3.63, while
|
|||
the arithmetic average of the GHz column above is lower.
|
||||
This is a weighted average, where the weight is %c0. ie. it is the total number of
|
||||
un-halted cycles elapsed per time divided by the number of CPUs.
|
||||
.SH SMI COUNTING EXAMPLE
|
||||
On Intel Nehalem and newer processors, MSR 0x34 is a System Management Mode Interrupt (SMI) counter.
|
||||
Using the -m option, you can display how many SMIs have fired since reset, or if there
|
||||
are SMIs during the measurement interval, you can display the delta using the -d option.
|
||||
.nf
|
||||
[root@x980 ~]# turbostat -m 0x34
|
||||
cor CPU %c0 GHz TSC MSR 0x034 %c1 %c3 %c6 %pc3 %pc6
|
||||
1.41 1.82 3.38 0x00000000 8.92 37.82 51.85 17.37 0.55
|
||||
0 0 3.73 2.03 3.38 0x00000055 1.72 48.25 46.31 17.38 0.55
|
||||
0 6 0.14 1.63 3.38 0x00000056 5.30
|
||||
1 2 2.51 1.80 3.38 0x00000056 15.65 29.33 52.52
|
||||
1 8 0.10 1.65 3.38 0x00000056 18.05
|
||||
2 4 1.16 1.68 3.38 0x00000056 5.87 24.47 68.50
|
||||
2 10 0.10 1.63 3.38 0x00000056 6.93
|
||||
8 1 3.84 1.91 3.38 0x00000056 1.36 50.65 44.16
|
||||
8 7 0.08 1.64 3.38 0x00000056 5.12
|
||||
9 3 1.82 1.73 3.38 0x00000056 7.59 24.21 66.38
|
||||
9 9 0.09 1.68 3.38 0x00000056 9.32
|
||||
10 5 1.66 1.65 3.38 0x00000056 15.10 50.00 33.23
|
||||
10 11 1.72 1.65 3.38 0x00000056 15.05
|
||||
^C
|
||||
[root@x980 ~]#
|
||||
.fi
|
||||
.SH NOTES
|
||||
|
||||
.B "turbostat "
|
||||
|
@ -165,6 +191,13 @@ may work poorly on Linux-2.6.20 through 2.6.29,
|
|||
as \fBacpi-cpufreq \fPperiodically cleared the APERF and MPERF
|
||||
in those kernels.
|
||||
|
||||
If the TSC column does not make sense, then
|
||||
the other numbers will also make no sense.
|
||||
Turbostat is lightweight, and its data collection is not atomic.
|
||||
These issues are usually caused by an extremely short measurement
|
||||
interval (much less than 1 second), or system activity that prevents
|
||||
turbostat from being able to run on all CPUS to quickly collect data.
|
||||
|
||||
The APERF, MPERF MSRs are defined to count non-halted cycles.
|
||||
Although it is not guaranteed by the architecture, turbostat assumes
|
||||
that they count at TSC rate, which is true on all processors tested to date.
|
||||
|
|
|
@ -35,9 +35,9 @@
|
|||
#include <ctype.h>
|
||||
#include <sched.h>
|
||||
|
||||
#define MSR_TSC 0x10
|
||||
#define MSR_NEHALEM_PLATFORM_INFO 0xCE
|
||||
#define MSR_NEHALEM_TURBO_RATIO_LIMIT 0x1AD
|
||||
#define MSR_IVT_TURBO_RATIO_LIMIT 0x1AE
|
||||
#define MSR_APERF 0xE8
|
||||
#define MSR_MPERF 0xE7
|
||||
#define MSR_PKG_C2_RESIDENCY 0x60D /* SNB only */
|
||||
|
@ -62,7 +62,11 @@ unsigned int genuine_intel;
|
|||
unsigned int has_invariant_tsc;
|
||||
unsigned int do_nehalem_platform_info;
|
||||
unsigned int do_nehalem_turbo_ratio_limit;
|
||||
unsigned int extra_msr_offset;
|
||||
unsigned int do_ivt_turbo_ratio_limit;
|
||||
unsigned int extra_msr_offset32;
|
||||
unsigned int extra_msr_offset64;
|
||||
unsigned int extra_delta_offset32;
|
||||
unsigned int extra_delta_offset64;
|
||||
double bclk;
|
||||
unsigned int show_pkg;
|
||||
unsigned int show_core;
|
||||
|
@ -83,7 +87,10 @@ struct thread_data {
|
|||
unsigned long long aperf;
|
||||
unsigned long long mperf;
|
||||
unsigned long long c1; /* derived */
|
||||
unsigned long long extra_msr;
|
||||
unsigned long long extra_msr64;
|
||||
unsigned long long extra_delta64;
|
||||
unsigned long long extra_msr32;
|
||||
unsigned long long extra_delta32;
|
||||
unsigned int cpu_id;
|
||||
unsigned int flags;
|
||||
#define CPU_IS_FIRST_THREAD_IN_CORE 0x2
|
||||
|
@ -222,6 +229,14 @@ void print_header(void)
|
|||
if (has_aperf)
|
||||
outp += sprintf(outp, " GHz");
|
||||
outp += sprintf(outp, " TSC");
|
||||
if (extra_delta_offset32)
|
||||
outp += sprintf(outp, " count 0x%03X", extra_delta_offset32);
|
||||
if (extra_delta_offset64)
|
||||
outp += sprintf(outp, " COUNT 0x%03X", extra_delta_offset64);
|
||||
if (extra_msr_offset32)
|
||||
outp += sprintf(outp, " MSR 0x%03X", extra_msr_offset32);
|
||||
if (extra_msr_offset64)
|
||||
outp += sprintf(outp, " MSR 0x%03X", extra_msr_offset64);
|
||||
if (do_nhm_cstates)
|
||||
outp += sprintf(outp, " %%c1");
|
||||
if (do_nhm_cstates)
|
||||
|
@ -238,8 +253,6 @@ void print_header(void)
|
|||
outp += sprintf(outp, " %%pc6");
|
||||
if (do_snb_cstates)
|
||||
outp += sprintf(outp, " %%pc7");
|
||||
if (extra_msr_offset)
|
||||
outp += sprintf(outp, " MSR 0x%x ", extra_msr_offset);
|
||||
|
||||
outp += sprintf(outp, "\n");
|
||||
}
|
||||
|
@ -255,8 +268,14 @@ int dump_counters(struct thread_data *t, struct core_data *c,
|
|||
fprintf(stderr, "aperf: %016llX\n", t->aperf);
|
||||
fprintf(stderr, "mperf: %016llX\n", t->mperf);
|
||||
fprintf(stderr, "c1: %016llX\n", t->c1);
|
||||
fprintf(stderr, "msr0x%x: %08llX\n",
|
||||
extra_delta_offset32, t->extra_delta32);
|
||||
fprintf(stderr, "msr0x%x: %016llX\n",
|
||||
extra_msr_offset, t->extra_msr);
|
||||
extra_delta_offset64, t->extra_delta64);
|
||||
fprintf(stderr, "msr0x%x: %08llX\n",
|
||||
extra_msr_offset32, t->extra_msr32);
|
||||
fprintf(stderr, "msr0x%x: %016llX\n",
|
||||
extra_msr_offset64, t->extra_msr64);
|
||||
}
|
||||
|
||||
if (c) {
|
||||
|
@ -360,6 +379,21 @@ int format_counters(struct thread_data *t, struct core_data *c,
|
|||
/* TSC */
|
||||
outp += sprintf(outp, "%5.2f", 1.0 * t->tsc/units/interval_float);
|
||||
|
||||
/* delta */
|
||||
if (extra_delta_offset32)
|
||||
outp += sprintf(outp, " %11llu", t->extra_delta32);
|
||||
|
||||
/* DELTA */
|
||||
if (extra_delta_offset64)
|
||||
outp += sprintf(outp, " %11llu", t->extra_delta64);
|
||||
/* msr */
|
||||
if (extra_msr_offset32)
|
||||
outp += sprintf(outp, " 0x%08llx", t->extra_msr32);
|
||||
|
||||
/* MSR */
|
||||
if (extra_msr_offset64)
|
||||
outp += sprintf(outp, " 0x%016llx", t->extra_msr64);
|
||||
|
||||
if (do_nhm_cstates) {
|
||||
if (!skip_c1)
|
||||
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,
|
|||
if (do_snb_cstates)
|
||||
outp += sprintf(outp, " %6.2f", 100.0 * p->pc7/t->tsc);
|
||||
done:
|
||||
if (extra_msr_offset)
|
||||
outp += sprintf(outp, " 0x%016llx", t->extra_msr);
|
||||
outp += sprintf(outp, "\n");
|
||||
|
||||
return 0;
|
||||
|
@ -502,10 +534,16 @@ delta_thread(struct thread_data *new, struct thread_data *old,
|
|||
old->mperf = 1; /* divide by 0 protection */
|
||||
}
|
||||
|
||||
old->extra_delta32 = new->extra_delta32 - old->extra_delta32;
|
||||
old->extra_delta32 &= 0xFFFFFFFF;
|
||||
|
||||
old->extra_delta64 = new->extra_delta64 - old->extra_delta64;
|
||||
|
||||
/*
|
||||
* for "extra msr", just copy the latest w/o subtracting
|
||||
* Extra MSR is just a snapshot, simply copy latest w/o subtracting
|
||||
*/
|
||||
old->extra_msr = new->extra_msr;
|
||||
old->extra_msr32 = new->extra_msr32;
|
||||
old->extra_msr64 = new->extra_msr64;
|
||||
}
|
||||
|
||||
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
|
|||
t->mperf = 0;
|
||||
t->c1 = 0;
|
||||
|
||||
t->extra_delta32 = 0;
|
||||
t->extra_delta64 = 0;
|
||||
|
||||
/* tells format_counters to dump all fields from this set */
|
||||
t->flags = CPU_IS_FIRST_THREAD_IN_CORE | CPU_IS_FIRST_CORE_IN_PACKAGE;
|
||||
|
||||
|
@ -553,6 +594,9 @@ int sum_counters(struct thread_data *t, struct core_data *c,
|
|||
average.threads.mperf += t->mperf;
|
||||
average.threads.c1 += t->c1;
|
||||
|
||||
average.threads.extra_delta32 += t->extra_delta32;
|
||||
average.threads.extra_delta64 += t->extra_delta64;
|
||||
|
||||
/* sum per-core values only for 1st thread in core */
|
||||
if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE))
|
||||
return 0;
|
||||
|
@ -588,6 +632,11 @@ void compute_average(struct thread_data *t, struct core_data *c,
|
|||
average.threads.mperf /= topo.num_cpus;
|
||||
average.threads.c1 /= topo.num_cpus;
|
||||
|
||||
average.threads.extra_delta32 /= topo.num_cpus;
|
||||
average.threads.extra_delta32 &= 0xFFFFFFFF;
|
||||
|
||||
average.threads.extra_delta64 /= topo.num_cpus;
|
||||
|
||||
average.cores.c3 /= topo.num_cores;
|
||||
average.cores.c6 /= topo.num_cores;
|
||||
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)
|
|||
return -4;
|
||||
}
|
||||
|
||||
if (extra_msr_offset)
|
||||
if (get_msr(cpu, extra_msr_offset, &t->extra_msr))
|
||||
if (extra_delta_offset32) {
|
||||
if (get_msr(cpu, extra_delta_offset32, &t->extra_delta32))
|
||||
return -5;
|
||||
t->extra_delta32 &= 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
if (extra_delta_offset64)
|
||||
if (get_msr(cpu, extra_delta_offset64, &t->extra_delta64))
|
||||
return -5;
|
||||
|
||||
if (extra_msr_offset32) {
|
||||
if (get_msr(cpu, extra_msr_offset32, &t->extra_msr32))
|
||||
return -5;
|
||||
t->extra_msr32 &= 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
if (extra_msr_offset64)
|
||||
if (get_msr(cpu, extra_msr_offset64, &t->extra_msr64))
|
||||
return -5;
|
||||
|
||||
/* collect core counters only for 1st thread in core */
|
||||
|
@ -677,6 +742,9 @@ void print_verbose_header(void)
|
|||
|
||||
get_msr(0, MSR_NEHALEM_PLATFORM_INFO, &msr);
|
||||
|
||||
if (verbose > 1)
|
||||
fprintf(stderr, "MSR_NEHALEM_PLATFORM_INFO: 0x%llx\n", msr);
|
||||
|
||||
ratio = (msr >> 40) & 0xFF;
|
||||
fprintf(stderr, "%d * %.0f = %.0f MHz max efficiency\n",
|
||||
ratio, bclk, ratio * bclk);
|
||||
|
@ -685,14 +753,84 @@ void print_verbose_header(void)
|
|||
fprintf(stderr, "%d * %.0f = %.0f MHz TSC frequency\n",
|
||||
ratio, bclk, ratio * bclk);
|
||||
|
||||
if (!do_ivt_turbo_ratio_limit)
|
||||
goto print_nhm_turbo_ratio_limits;
|
||||
|
||||
get_msr(0, MSR_IVT_TURBO_RATIO_LIMIT, &msr);
|
||||
|
||||
if (verbose > 1)
|
||||
fprintf(stderr, "MSR_NEHALEM_PLATFORM_INFO: 0x%llx\n", msr);
|
||||
fprintf(stderr, "MSR_IVT_TURBO_RATIO_LIMIT: 0x%llx\n", msr);
|
||||
|
||||
ratio = (msr >> 56) & 0xFF;
|
||||
if (ratio)
|
||||
fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 16 active cores\n",
|
||||
ratio, bclk, ratio * bclk);
|
||||
|
||||
ratio = (msr >> 48) & 0xFF;
|
||||
if (ratio)
|
||||
fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 15 active cores\n",
|
||||
ratio, bclk, ratio * bclk);
|
||||
|
||||
ratio = (msr >> 40) & 0xFF;
|
||||
if (ratio)
|
||||
fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 14 active cores\n",
|
||||
ratio, bclk, ratio * bclk);
|
||||
|
||||
ratio = (msr >> 32) & 0xFF;
|
||||
if (ratio)
|
||||
fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 13 active cores\n",
|
||||
ratio, bclk, ratio * bclk);
|
||||
|
||||
ratio = (msr >> 24) & 0xFF;
|
||||
if (ratio)
|
||||
fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 12 active cores\n",
|
||||
ratio, bclk, ratio * bclk);
|
||||
|
||||
ratio = (msr >> 16) & 0xFF;
|
||||
if (ratio)
|
||||
fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 11 active cores\n",
|
||||
ratio, bclk, ratio * bclk);
|
||||
|
||||
ratio = (msr >> 8) & 0xFF;
|
||||
if (ratio)
|
||||
fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 10 active cores\n",
|
||||
ratio, bclk, ratio * bclk);
|
||||
|
||||
ratio = (msr >> 0) & 0xFF;
|
||||
if (ratio)
|
||||
fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 9 active cores\n",
|
||||
ratio, bclk, ratio * bclk);
|
||||
|
||||
print_nhm_turbo_ratio_limits:
|
||||
|
||||
if (!do_nehalem_turbo_ratio_limit)
|
||||
return;
|
||||
|
||||
get_msr(0, MSR_NEHALEM_TURBO_RATIO_LIMIT, &msr);
|
||||
|
||||
if (verbose > 1)
|
||||
fprintf(stderr, "MSR_NEHALEM_TURBO_RATIO_LIMIT: 0x%llx\n", msr);
|
||||
|
||||
ratio = (msr >> 56) & 0xFF;
|
||||
if (ratio)
|
||||
fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 8 active cores\n",
|
||||
ratio, bclk, ratio * bclk);
|
||||
|
||||
ratio = (msr >> 48) & 0xFF;
|
||||
if (ratio)
|
||||
fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 7 active cores\n",
|
||||
ratio, bclk, ratio * bclk);
|
||||
|
||||
ratio = (msr >> 40) & 0xFF;
|
||||
if (ratio)
|
||||
fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 6 active cores\n",
|
||||
ratio, bclk, ratio * bclk);
|
||||
|
||||
ratio = (msr >> 32) & 0xFF;
|
||||
if (ratio)
|
||||
fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 5 active cores\n",
|
||||
ratio, bclk, ratio * bclk);
|
||||
|
||||
ratio = (msr >> 24) & 0xFF;
|
||||
if (ratio)
|
||||
fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 4 active cores\n",
|
||||
|
@ -712,7 +850,6 @@ void print_verbose_header(void)
|
|||
if (ratio)
|
||||
fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 1 active cores\n",
|
||||
ratio, bclk, ratio * bclk);
|
||||
|
||||
}
|
||||
|
||||
void free_all_buffers(void)
|
||||
|
@ -1038,7 +1175,7 @@ int has_nehalem_turbo_ratio_limit(unsigned int family, unsigned int model)
|
|||
case 0x2A: /* SNB */
|
||||
case 0x2D: /* SNB Xeon */
|
||||
case 0x3A: /* IVB */
|
||||
case 0x3D: /* IVB Xeon */
|
||||
case 0x3E: /* IVB Xeon */
|
||||
return 1;
|
||||
case 0x2E: /* Nehalem-EX Xeon - Beckton */
|
||||
case 0x2F: /* Westmere-EX Xeon - Eagleton */
|
||||
|
@ -1046,6 +1183,22 @@ int has_nehalem_turbo_ratio_limit(unsigned int family, unsigned int model)
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
int has_ivt_turbo_ratio_limit(unsigned int family, unsigned int model)
|
||||
{
|
||||
if (!genuine_intel)
|
||||
return 0;
|
||||
|
||||
if (family != 6)
|
||||
return 0;
|
||||
|
||||
switch (model) {
|
||||
case 0x3E: /* IVB Xeon */
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int is_snb(unsigned int family, unsigned int model)
|
||||
{
|
||||
|
@ -1056,7 +1209,7 @@ int is_snb(unsigned int family, unsigned int model)
|
|||
case 0x2A:
|
||||
case 0x2D:
|
||||
case 0x3A: /* IVB */
|
||||
case 0x3D: /* IVB Xeon */
|
||||
case 0x3E: /* IVB Xeon */
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
@ -1145,12 +1298,13 @@ void check_cpuid()
|
|||
bclk = discover_bclk(family, model);
|
||||
|
||||
do_nehalem_turbo_ratio_limit = has_nehalem_turbo_ratio_limit(family, model);
|
||||
do_ivt_turbo_ratio_limit = has_ivt_turbo_ratio_limit(family, model);
|
||||
}
|
||||
|
||||
|
||||
void usage()
|
||||
{
|
||||
fprintf(stderr, "%s: [-v] [-M MSR#] [-i interval_sec | command ...]\n",
|
||||
fprintf(stderr, "%s: [-v][-p|-P|-S][-c MSR# | -s]][-C MSR#][-m MSR#][-M MSR#][-i interval_sec | command ...]\n",
|
||||
progname);
|
||||
exit(1);
|
||||
}
|
||||
|
@ -1440,15 +1594,15 @@ void cmdline(int argc, char **argv)
|
|||
|
||||
progname = argv[0];
|
||||
|
||||
while ((opt = getopt(argc, argv, "+cpsvi:M:")) != -1) {
|
||||
while ((opt = getopt(argc, argv, "+pPSvisc:sC:m:M:")) != -1) {
|
||||
switch (opt) {
|
||||
case 'c':
|
||||
case 'p':
|
||||
show_core_only++;
|
||||
break;
|
||||
case 'p':
|
||||
case 'P':
|
||||
show_pkg_only++;
|
||||
break;
|
||||
case 's':
|
||||
case 'S':
|
||||
summary_only++;
|
||||
break;
|
||||
case 'v':
|
||||
|
@ -1457,10 +1611,20 @@ void cmdline(int argc, char **argv)
|
|||
case 'i':
|
||||
interval_sec = atoi(optarg);
|
||||
break;
|
||||
case 'c':
|
||||
sscanf(optarg, "%x", &extra_delta_offset32);
|
||||
break;
|
||||
case 's':
|
||||
extra_delta_offset32 = 0x34; /* SMI counter */
|
||||
break;
|
||||
case 'C':
|
||||
sscanf(optarg, "%x", &extra_delta_offset64);
|
||||
break;
|
||||
case 'm':
|
||||
sscanf(optarg, "%x", &extra_msr_offset32);
|
||||
break;
|
||||
case 'M':
|
||||
sscanf(optarg, "%x", &extra_msr_offset);
|
||||
if (verbose > 1)
|
||||
fprintf(stderr, "MSR 0x%X\n", extra_msr_offset);
|
||||
sscanf(optarg, "%x", &extra_msr_offset64);
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
|
@ -1473,7 +1637,7 @@ int main(int argc, char **argv)
|
|||
cmdline(argc, argv);
|
||||
|
||||
if (verbose > 1)
|
||||
fprintf(stderr, "turbostat v2.0 May 16, 2012"
|
||||
fprintf(stderr, "turbostat v2.1 October 6, 2012"
|
||||
" - Len Brown <lenb@kernel.org>\n");
|
||||
|
||||
turbostat_init();
|
||||
|
|
Loading…
Reference in a new issue