Commit d8dc91b7 authored by Linus Torvalds's avatar Linus Torvalds

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()
  ...
parents 7035cdf3 3f44ea0d
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);
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_gbl_root_table_list.flags |= ACPI_ROOT_ALLOW_RESIZE;
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 */
......
This diff is collapsed.
This diff is collapsed.
......@@ -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;
}
dev->archdata.acpi_handle = handle;
status = acpi_bus_get_device(handle, &acpi_dev);
if (!ACPI_FAILURE(status)) {
int ret;
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);
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;
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");
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];
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_detach_data(dev->archdata.acpi_handle,
acpi_glue_data_handler);
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;
}
......
This diff is collapsed.
......@@ -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
*/
......
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
.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>
This diff is collapsed.
......@@ -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.
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment