Commit 47b6ac1d authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://linux-acpi.bkbits.net/linux-acpi-release-2.6.5

into ppc970.osdl.org:/home/torvalds/v2.5/linux
parents 180cc17d 1e102760
......@@ -116,6 +116,10 @@ running once the system is up.
acpi_irq_isa= [HW,ACPI] If irq_balance, Mark listed IRQs used by ISA
Format: <irq>,<irq>...
acpi_osi= [HW,ACPI] empty param disables _OSI
acpi_serialize [HW,ACPI] force serialization of AML methods
ad1816= [HW,OSS]
Format: <io>,<irq>,<dma>,<dma2>
See also Documentation/sound/oss/AD1816.
......
......@@ -128,7 +128,9 @@ static int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size)
return 0;
}
#endif /* CONFIG_PCI_MMCONFIG */
#else
#define acpi_parse_mcfg NULL
#endif /* !CONFIG_PCI_MMCONFIG */
#ifdef CONFIG_X86_LOCAL_APIC
static int __init
......@@ -424,6 +426,8 @@ static int __init acpi_parse_hpet(unsigned long phys, unsigned long size)
hpet_address);
return 0;
}
#else
#define acpi_parse_hpet NULL
#endif
/* detect the location of the ACPI PM Timer */
......@@ -454,6 +458,8 @@ static int __init acpi_parse_fadt(unsigned long phys, unsigned long size)
printk(KERN_INFO PREFIX "PM-Timer IO Port: %#x\n", pmtmr_ioport);
return 0;
}
#else
#define acpi_parse_fadt NULL
#endif
......@@ -666,7 +672,7 @@ acpi_boot_init (void)
return error;
}
(void) acpi_table_parse(ACPI_BOOT, acpi_parse_sbf);
acpi_table_parse(ACPI_BOOT, acpi_parse_sbf);
/*
* blacklist may disable ACPI entirely
......@@ -683,19 +689,9 @@ acpi_boot_init (void)
*/
acpi_process_madt();
#ifdef CONFIG_X86_PM_TIMER
acpi_table_parse(ACPI_FADT, acpi_parse_fadt);
#endif
#ifdef CONFIG_HPET_TIMER
(void) acpi_table_parse(ACPI_HPET, acpi_parse_hpet);
#endif
#ifdef CONFIG_PCI_MMCONFIG
error = acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg);
if (error)
printk(KERN_ERR PREFIX "Error %d parsing MCFG\n", error);
#endif
acpi_table_parse(ACPI_HPET, acpi_parse_hpet);
acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg);
return 0;
}
......
......@@ -48,7 +48,7 @@ static void __init sbf_write(u8 v)
if(!parity(v))
v|=SBF_PARITY;
printk(KERN_INFO "Simple Boot Flag 0x%x\n", v);
printk(KERN_INFO "Simple Boot Flag at 0x%x set to 0x%x\n", sbf_port, v);
spin_lock_irqsave(&rtc_lock, flags);
CMOS_WRITE(v, sbf_port);
......
......@@ -106,7 +106,7 @@ acpi_ds_parse_method (
/* Create a mutex for the method if there is a concurrency limit */
if ((obj_desc->method.concurrency != INFINITE_CONCURRENCY) &&
if ((obj_desc->method.concurrency != ACPI_INFINITE_CONCURRENCY) &&
(!obj_desc->method.semaphore)) {
status = acpi_os_create_semaphore (obj_desc->method.concurrency,
obj_desc->method.concurrency,
......@@ -300,34 +300,37 @@ acpi_ds_call_control_method (
return_ACPI_STATUS (status);
}
/* 1) Parse: Create a new walk state for the preempting walk */
if (!(obj_desc->method.method_flags & AML_METHOD_INTERNAL_ONLY)) {
/* 1) Parse: Create a new walk state for the preempting walk */
next_walk_state = acpi_ds_create_walk_state (obj_desc->method.owning_id,
op, obj_desc, NULL);
if (!next_walk_state) {
return_ACPI_STATUS (AE_NO_MEMORY);
}
next_walk_state = acpi_ds_create_walk_state (obj_desc->method.owning_id,
op, obj_desc, NULL);
if (!next_walk_state) {
return_ACPI_STATUS (AE_NO_MEMORY);
}
/* Create and init a Root Node */
op = acpi_ps_create_scope_op ();
if (!op) {
status = AE_NO_MEMORY;
goto cleanup;
}
/* Create and init a Root Node */
status = acpi_ds_init_aml_walk (next_walk_state, op, method_node,
obj_desc->method.aml_start, obj_desc->method.aml_length,
NULL, NULL, 1);
if (ACPI_FAILURE (status)) {
acpi_ds_delete_walk_state (next_walk_state);
goto cleanup;
}
op = acpi_ps_create_scope_op ();
if (!op) {
status = AE_NO_MEMORY;
goto cleanup;
}
status = acpi_ds_init_aml_walk (next_walk_state, op, method_node,
obj_desc->method.aml_start, obj_desc->method.aml_length,
NULL, NULL, 1);
if (ACPI_FAILURE (status)) {
acpi_ds_delete_walk_state (next_walk_state);
goto cleanup;
}
/* Begin AML parse */
/* Begin AML parse */
status = acpi_ps_parse_aml (next_walk_state);
acpi_ps_delete_parse_tree (op);
status = acpi_ps_parse_aml (next_walk_state);
acpi_ps_delete_parse_tree (op);
}
/* 2) Execute: Create a new state for the preempting walk */
......@@ -337,7 +340,6 @@ acpi_ds_call_control_method (
status = AE_NO_MEMORY;
goto cleanup;
}
/*
* The resolved arguments were put on the previous walk state's operand
* stack. Operands on the previous walk state stack always
......@@ -369,16 +371,25 @@ acpi_ds_call_control_method (
ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
"Starting nested execution, newstate=%p\n", next_walk_state));
if (obj_desc->method.method_flags & AML_METHOD_INTERNAL_ONLY) {
status = obj_desc->method.implementation (next_walk_state);
return_ACPI_STATUS (status);
}
return_ACPI_STATUS (AE_OK);
/* On error, we must delete the new walk state */
cleanup:
if (next_walk_state->method_desc) {
/* Decrement the thread count on the method parse tree */
next_walk_state->method_desc->method.thread_count--;
}
(void) acpi_ds_terminate_control_method (next_walk_state);
acpi_ds_delete_walk_state (next_walk_state);
return_ACPI_STATUS (status);
}
......@@ -500,10 +511,30 @@ acpi_ds_terminate_control_method (
}
}
/* Decrement the thread count on the method parse tree */
if (walk_state->method_desc->method.thread_count) {
ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
"*** Not deleting method namespace, there are still %d threads\n",
walk_state->method_desc->method.thread_count));
}
walk_state->method_desc->method.thread_count--;
if (!walk_state->method_desc->method.thread_count) {
/*
* Support to dynamically change a method from not_serialized to
* Serialized if it appears that the method is written foolishly and
* does not support multiple thread execution. The best example of this
* is if such a method creates namespace objects and blocks. A second
* thread will fail with an AE_ALREADY_EXISTS exception
*
* This code is here because we must wait until the last thread exits
* before creating the synchronization semaphore.
*/
if ((walk_state->method_desc->method.concurrency == 1) &&
(!walk_state->method_desc->method.semaphore)) {
status = acpi_os_create_semaphore (1,
1,
&walk_state->method_desc->method.semaphore);
}
/*
* There are no more threads executing this method. Perform
* additional cleanup.
......
......@@ -149,6 +149,11 @@ acpi_ev_gpe_detect (
ACPI_FUNCTION_NAME ("ev_gpe_detect");
/* Check for the case where there are no GPEs */
if (!gpe_xrupt_list) {
return (int_status);
}
/* Examine all GPE blocks attached to this interrupt level */
......
......@@ -587,27 +587,33 @@ acpi_ex_create_method (
obj_desc->method.aml_start = aml_start;
obj_desc->method.aml_length = aml_length;
/* disassemble the method flags */
/*
* Disassemble the method flags. Split off the Arg Count
* for efficiency
*/
method_flags = (u8) operand[1]->integer.value;
obj_desc->method.method_flags = method_flags;
obj_desc->method.param_count = (u8) (method_flags & METHOD_FLAGS_ARG_COUNT);
obj_desc->method.method_flags = (u8) (method_flags & ~AML_METHOD_ARG_COUNT);
obj_desc->method.param_count = (u8) (method_flags & AML_METHOD_ARG_COUNT);
/*
* Get the concurrency count. If required, a semaphore will be
* created for this method when it is parsed.
*/
if (method_flags & METHOD_FLAGS_SERIALIZED) {
if (acpi_gbl_all_methods_serialized) {
obj_desc->method.concurrency = 1;
obj_desc->method.method_flags |= AML_METHOD_SERIALIZED;
}
else if (method_flags & AML_METHOD_SERIALIZED) {
/*
* ACPI 1.0: Concurrency = 1
* ACPI 2.0: Concurrency = (sync_level (in method declaration) + 1)
*/
obj_desc->method.concurrency = (u8)
(((method_flags & METHOD_FLAGS_SYNCH_LEVEL) >> 4) + 1);
(((method_flags & AML_METHOD_SYNCH_LEVEL) >> 4) + 1);
}
else {
obj_desc->method.concurrency = INFINITE_CONCURRENCY;
obj_desc->method.concurrency = ACPI_INFINITE_CONCURRENCY;
}
/* Attach the new object to the method Node */
......
......@@ -176,15 +176,18 @@ acpi_ex_acquire_mutex (
/*
* Support for multiple acquires by the owning thread
*/
if ((obj_desc->mutex.owner_thread) &&
(obj_desc->mutex.owner_thread->thread_id == walk_state->thread->thread_id)) {
/*
* The mutex is already owned by this thread,
* just increment the acquisition depth
*/
obj_desc->mutex.acquisition_depth++;
return_ACPI_STATUS (AE_OK);
if (obj_desc->mutex.owner_thread) {
/* Special case for Global Lock, allow all threads */
if ((obj_desc->mutex.owner_thread->thread_id == walk_state->thread->thread_id) ||
(obj_desc->mutex.semaphore == acpi_gbl_global_lock_semaphore)) {
/*
* The mutex is already owned by this thread,
* just increment the acquisition depth
*/
obj_desc->mutex.acquisition_depth++;
return_ACPI_STATUS (AE_OK);
}
}
/* Acquire the mutex, wait if necessary */
......@@ -254,9 +257,12 @@ acpi_ex_release_mutex (
return_ACPI_STATUS (AE_AML_INTERNAL);
}
/* The Mutex is owned, but this thread must be the owner */
if (obj_desc->mutex.owner_thread->thread_id != walk_state->thread->thread_id) {
/*
* The Mutex is owned, but this thread must be the owner.
* Special case for Global Lock, any thread can release
*/
if ((obj_desc->mutex.owner_thread->thread_id != walk_state->thread->thread_id) &&
(obj_desc->mutex.semaphore != acpi_gbl_global_lock_semaphore)) {
ACPI_REPORT_ERROR ((
"Thread %X cannot release Mutex [%4.4s] acquired by thread %X\n",
walk_state->thread->thread_id,
......
......@@ -394,7 +394,7 @@ acpi_enter_sleep_state (
*
******************************************************************************/
acpi_status
acpi_status asmlinkage
acpi_enter_sleep_state_s4bios (
void)
{
......
......@@ -105,8 +105,15 @@ acpi_ns_root_initialize (void)
"Entering predefined entries into namespace\n"));
for (init_val = acpi_gbl_pre_defined_names; init_val->name; init_val++) {
/* _OSI is optional for now, will be permanent later */
if (!ACPI_STRCMP (init_val->name, "_OSI") && !acpi_gbl_create_osi_method) {
continue;
}
status = acpi_ns_lookup (NULL, init_val->name, init_val->type,
ACPI_IMODE_LOAD_PASS2, ACPI_NS_NO_UPSEARCH, NULL, &new_node);
ACPI_IMODE_LOAD_PASS2, ACPI_NS_NO_UPSEARCH,
NULL, &new_node);
if (ACPI_FAILURE (status) || (!new_node)) /* Must be on same line for code converter */ {
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
......@@ -122,7 +129,8 @@ acpi_ns_root_initialize (void)
if (init_val->val) {
status = acpi_os_predefined_override (init_val, &val);
if (ACPI_FAILURE (status)) {
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not override predefined %s\n",
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
"Could not override predefined %s\n",
init_val->name));
}
......@@ -147,15 +155,20 @@ acpi_ns_root_initialize (void)
*/
switch (init_val->type) {
case ACPI_TYPE_METHOD:
obj_desc->method.param_count =
(u8) ACPI_STRTOUL (val, NULL, 10);
obj_desc->method.param_count = (u8) ACPI_STRTOUL
(val, NULL, 10);
obj_desc->common.flags |= AOPOBJ_DATA_VALID;
#if defined (ACPI_NO_METHOD_EXECUTION) || defined (ACPI_CONSTANT_EVAL_ONLY)
#if defined (_ACPI_ASL_COMPILER) || defined (_ACPI_DUMP_App)
/* Compiler cheats by putting parameter count in the owner_iD */
/* i_aSL Compiler cheats by putting parameter count in the owner_iD */
new_node->owner_id = obj_desc->method.param_count;
#else
/* Mark this as a very SPECIAL method */
obj_desc->method.method_flags = AML_METHOD_INTERNAL_ONLY;
obj_desc->method.implementation = acpi_ut_osi_implementation;
#endif
break;
......@@ -180,8 +193,8 @@ acpi_ns_root_initialize (void)
case ACPI_TYPE_MUTEX:
obj_desc->mutex.node = new_node;
obj_desc->mutex.sync_level =
(u16) ACPI_STRTOUL (val, NULL, 10);
obj_desc->mutex.sync_level = (u16) ACPI_STRTOUL
(val, NULL, 10);
if (ACPI_STRCMP (init_val->name, "_GL_") == 0) {
/*
......@@ -213,6 +226,7 @@ acpi_ns_root_initialize (void)
default:
ACPI_REPORT_ERROR (("Unsupported initial type value %X\n",
init_val->type));
acpi_ut_remove_reference (obj_desc);
......
......@@ -334,10 +334,11 @@ acpi_ns_install_node (
node->owner_id = owner_id;
node->type = (u8) type;
ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "%4.4s (%s) added to %4.4s (%s) %p at %p\n",
acpi_ut_get_node_name (node), acpi_ut_get_type_name (node->type),
ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
"%4.4s (%s) [Node %p Owner %X] added to %4.4s (%s) [Node %p]\n",
acpi_ut_get_node_name (node), acpi_ut_get_type_name (node->type), node, owner_id,
acpi_ut_get_node_name (parent_node), acpi_ut_get_type_name (parent_node->type),
parent_node, node));
parent_node));
/*
* Increment the reference count(s) of all parents up to
......
......@@ -82,11 +82,11 @@ acpi_ns_evaluate_relative (
union acpi_operand_object **params,
union acpi_operand_object **return_object)
{
struct acpi_namespace_node *prefix_node;
acpi_status status;
struct acpi_namespace_node *prefix_node;
struct acpi_namespace_node *node = NULL;
union acpi_generic_state *scope_info;
char *internal_path = NULL;
union acpi_generic_state scope_info;
ACPI_FUNCTION_TRACE ("ns_evaluate_relative");
......@@ -106,6 +106,11 @@ acpi_ns_evaluate_relative (
return_ACPI_STATUS (status);
}
scope_info = acpi_ut_create_generic_state ();
if (!scope_info) {
goto cleanup1;
}
/* Get the prefix handle and Node */
status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
......@@ -122,8 +127,8 @@ acpi_ns_evaluate_relative (
/* Lookup the name in the namespace */
scope_info.scope.node = prefix_node;
status = acpi_ns_lookup (&scope_info, internal_path, ACPI_TYPE_ANY,
scope_info->scope.node = prefix_node;
status = acpi_ns_lookup (scope_info, internal_path, ACPI_TYPE_ANY,
ACPI_IMODE_EXECUTE, ACPI_NS_NO_UPSEARCH, NULL,
&node);
......@@ -148,7 +153,9 @@ acpi_ns_evaluate_relative (
pathname));
cleanup:
acpi_ut_delete_generic_state (scope_info);
cleanup1:
ACPI_MEM_FREE (internal_path);
return_ACPI_STATUS (status);
}
......
......@@ -1012,3 +1012,39 @@ acpi_os_name_setup(char *str)
}
__setup("acpi_os_name=", acpi_os_name_setup);
/*
* _OSI control
* empty string disables _OSI
* TBD additional string adds to _OSI
*/
int __init
acpi_osi_setup(char *str)
{
if (str == NULL || *str == '\0') {
printk(KERN_INFO PREFIX "_OSI method disabled\n");
acpi_gbl_create_osi_method = FALSE;
} else
{
/* TBD */
printk(KERN_ERR PREFIX "_OSI additional string ignored -- %s\n", str);
}
return 1;
}
__setup("acpi_osi=", acpi_osi_setup);
/* enable serialization to combat AE_ALREADY_EXISTS errors */
int __init
acpi_serialize_setup(char *str)
{
printk(KERN_INFO PREFIX "serialize enabled\n");
acpi_gbl_all_methods_serialized = TRUE;
return 1;
}
__setup("acpi_serialize", acpi_serialize_setup);
......@@ -426,7 +426,7 @@ acpi_ps_parse_loop (
acpi_status status = AE_OK;
union acpi_parse_object *op = NULL; /* current op */
union acpi_parse_object *arg = NULL;
union acpi_parse_object pre_op;
union acpi_parse_object *pre_op = NULL;
struct acpi_parse_state *parser_state;
u8 *aml_op_start = NULL;
......@@ -547,8 +547,17 @@ acpi_ps_parse_loop (
/* Create Op structure and append to parent's argument list */
if (walk_state->op_info->flags & AML_NAMED) {
pre_op.common.value.arg = NULL;
pre_op.common.aml_opcode = walk_state->opcode;
/* Allocate a new pre_op if necessary */
if (!pre_op) {
pre_op = acpi_ps_alloc_op (walk_state->opcode);
if (!pre_op) {
return_ACPI_STATUS (AE_NO_MEMORY);
}
}
pre_op->common.value.arg = NULL;
pre_op->common.aml_opcode = walk_state->opcode;
/*
* Get and append arguments until we find the node that contains
......@@ -562,7 +571,7 @@ acpi_ps_parse_loop (
goto close_this_op;
}
acpi_ps_append_arg (&pre_op, arg);
acpi_ps_append_arg (pre_op, arg);
INCREMENT_ARG_LIST (walk_state->arg_types);
}
......@@ -603,7 +612,7 @@ acpi_ps_parse_loop (
goto close_this_op;
}
acpi_ps_append_arg (op, pre_op.common.value.arg);
acpi_ps_append_arg (op, pre_op->common.value.arg);
acpi_gbl_depth++;
if (op->common.aml_opcode == AML_REGION_OP) {
......@@ -854,6 +863,10 @@ acpi_ps_parse_loop (
acpi_ps_complete_this_op (walk_state, op);
op = NULL;
if (pre_op) {
acpi_ps_free_op (pre_op);
pre_op = NULL;
}
switch (status) {
case AE_OK:
......@@ -1118,6 +1131,27 @@ acpi_ps_parse_aml (
else if (status != AE_OK) {
ACPI_REPORT_METHOD_ERROR ("Method execution failed",
walk_state->method_node, NULL, status);
/* Check for possible multi-thread reentrancy problem */
if ((status == AE_ALREADY_EXISTS) &&
(!walk_state->method_desc->method.semaphore)) {
/*
* This method is marked not_serialized, but it tried to create a named
* object, causing the second thread entrance to fail. We will workaround
* this by marking the method permanently as Serialized.
*/
walk_state->method_desc->method.method_flags |= AML_METHOD_SERIALIZED;
walk_state->method_desc->method.concurrency = 1;
}
}
if (walk_state->method_desc) {
/* Decrement the thread count on the method parse tree */
if (walk_state->method_desc->method.thread_count) {
walk_state->method_desc->method.thread_count--;
}
}
/* We are done with this walk, move on to the parent if any */
......
......@@ -167,7 +167,6 @@ acpi_ps_push_scope (
return_ACPI_STATUS (AE_NO_MEMORY);
}
scope->common.data_type = ACPI_DESC_TYPE_STATE_PSCOPE;
scope->parse_scope.op = op;
scope->parse_scope.arg_list = remaining_args;
......@@ -178,13 +177,11 @@ acpi_ps_push_scope (
acpi_ut_push_generic_state (&parser_state->scope, scope);
if (arg_count == ACPI_VAR_ARGS) {
/* multiple arguments */
scope->parse_scope.arg_end = parser_state->pkg_end;
}
else {
/* single argument */
......@@ -241,7 +238,6 @@ acpi_ps_pop_scope (
acpi_ut_delete_generic_state (scope);
}
else {
/* empty parse stack, prepare to fetch next opcode */
......@@ -250,7 +246,6 @@ acpi_ps_pop_scope (
*arg_count = 0;
}
ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Popped Op %p Args %X\n", *op, *arg_count));
return_VOID;
}
......@@ -275,14 +270,14 @@ acpi_ps_cleanup_scope (
{
union acpi_generic_state *scope;
ACPI_FUNCTION_TRACE_PTR ("ps_cleanup_scope", parser_state);
if (!parser_state) {
return;
return_VOID;
}
/* Delete anything on the scope stack */
while (parser_state->scope) {
......
......@@ -23,6 +23,18 @@
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
/*
* ACPI power-managed devices may be controlled in two ways:
* 1. via "Device Specific (D-State) Control"
* 2. via "Power Resource Control".
* This module is used to manage devices relying on Power Resource Control.
*
* An ACPI "power resource object" describes a software controllable power
* plane, clock plane, or other resource used by a power managed device.
* A device may rely on multiple power resources, and a power resource
* may be shared by multiple devices.
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
......
......@@ -8,11 +8,14 @@
#include <linux/pm.h>
#include <linux/init.h>
#include <acpi/acpi_bus.h>
#include <linux/sched.h>
static void
acpi_power_off (void)
{
printk("%s called\n",__FUNCTION__);
/* Some SMP machines only can poweroff in boot CPU */
set_cpus_allowed(current, cpumask_of_cpu(0));
acpi_enter_sleep_state_prep(ACPI_STATE_S5);
ACPI_DISABLE_IRQS();
acpi_enter_sleep_state(ACPI_STATE_S5);
......
......@@ -386,8 +386,13 @@ acpi_table_parse (
for (i = 0; i < sdt_count; i++) {
if (sdt_entry[i].id != id)
continue;
handler(sdt_entry[i].pa, sdt_entry[i].size);
count++;
if (count == 1)
handler(sdt_entry[i].pa, sdt_entry[i].size);
else
printk(KERN_WARNING PREFIX "%d duplicate %s table ignored.\n",
count, acpi_table_signatures[id]);
}
return count;
......
......@@ -51,6 +51,62 @@
ACPI_MODULE_NAME ("uteval")
/*******************************************************************************
*
* FUNCTION: acpi_ut_osi_implementation
*
* PARAMETERS: walk_state - Current walk state
*
* RETURN: Status
*
* DESCRIPTION: Implementation of _OSI predefined control method
* Supported = _OSI (String)
*
******************************************************************************/
acpi_status
acpi_ut_osi_implementation (
struct acpi_walk_state *walk_state)
{
union acpi_operand_object *string_desc;
union acpi_operand_object *return_desc;
acpi_native_uint i;
ACPI_FUNCTION_TRACE ("ut_osi_implementation");
/* Validate the string input argument */
string_desc = walk_state->arguments[0].object;
if (!string_desc || (string_desc->common.type != ACPI_TYPE_STRING)) {
return_ACPI_STATUS (AE_TYPE);
}
/* Create a return object (Default value = 0) */
return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
if (!return_desc) {
return_ACPI_STATUS (AE_NO_MEMORY);
}
/* Compare input string to table of supported strings */
for (i = 0; i < ACPI_NUM_OSI_STRINGS; i++) {
if (!ACPI_STRCMP (string_desc->string.pointer,
(char *) acpi_gbl_valid_osi_strings[i])) {
/* This string is supported */
return_desc->integer.value = 0xFFFFFFFF;
break;
}
}
walk_state->return_desc = return_desc;
return_ACPI_STATUS (AE_CTRL_TERMINATE);
}
/*******************************************************************************
*
* FUNCTION: acpi_ut_evaluate_object
......
......@@ -185,6 +185,15 @@ const char *acpi_gbl_highest_dstate_names[4] = {
"_S3D",
"_S4D"};
/* Strings supported by the _OSI predefined (internal) method */
const char *acpi_gbl_valid_osi_strings[ACPI_NUM_OSI_STRINGS] = {
"Linux",
"Windows 2000",
"Windows 2001",
"Windows 2001.1"};
/******************************************************************************
*
* Namespace globals
......@@ -195,14 +204,10 @@ const char *acpi_gbl_highest_dstate_names[4] = {
/*
* Predefined ACPI Names (Built-in to the Interpreter)
*
* Initial values are currently supported only for types String and Number.
* Both are specified as strings in this table.
*
* NOTES:
* 1) _SB_ is defined to be a device to allow _SB_/_INI to be run
* 1) _SB_ is defined to be a device to allow \_SB_._INI to be run
* during the initialization sequence.
*/
const struct acpi_predefined_names acpi_gbl_pre_defined_names[] =
{ {"_GPE", ACPI_TYPE_LOCAL_SCOPE, NULL},
{"_PR_", ACPI_TYPE_LOCAL_SCOPE, NULL},
......@@ -213,7 +218,7 @@ const struct acpi_predefined_names acpi_gbl_pre_defined_names[] =
{"_OS_", ACPI_TYPE_STRING, ACPI_OS_NAME},
{"_GL_", ACPI_TYPE_MUTEX, "0"},
#if defined (ACPI_NO_METHOD_EXECUTION) || defined (ACPI_CONSTANT_EVAL_ONLY)
#if !defined (ACPI_NO_METHOD_EXECUTION) || defined (ACPI_CONSTANT_EVAL_ONLY)
{"_OSI", ACPI_TYPE_METHOD, "1"},
#endif
{NULL, ACPI_TYPE_ANY, NULL} /* Table terminator */
......@@ -224,7 +229,6 @@ const struct acpi_predefined_names acpi_gbl_pre_defined_names[] =
* Properties of the ACPI Object Types, both internal and external.
* The table is indexed by values of acpi_object_type
*/
const u8 acpi_gbl_ns_properties[] =
{
ACPI_NS_NORMAL, /* 00 Any */
......@@ -303,10 +307,8 @@ acpi_ut_hex_to_ascii_char (
*
******************************************************************************/
struct acpi_table_list acpi_gbl_table_lists[NUM_ACPI_TABLE_TYPES];
struct acpi_table_support acpi_gbl_table_data[NUM_ACPI_TABLE_TYPES] =
{
/*********** Name, Signature, Global typed pointer Signature size, Type How many allowed?, Contains valid AML? */
......@@ -470,9 +472,8 @@ acpi_ut_get_event_name (
*
* The type ACPI_TYPE_ANY (Untyped) is used as a "don't care" when searching; when
* stored in a table it really means that we have thus far seen no evidence to
* indicatewhat type is actually going to be stored for this entry.
* indicate what type is actually going to be stored for this entry.
*/
static const char acpi_gbl_bad_type[] = "UNDEFINED";
#define TYPE_NAME_LENGTH 12 /* Maximum length of each string */
......@@ -777,6 +778,11 @@ acpi_ut_init_globals (
ACPI_FUNCTION_TRACE ("ut_init_globals");
/* Runtime configuration */
acpi_gbl_create_osi_method = TRUE;
acpi_gbl_all_methods_serialized = FALSE;
/* Memory allocation and cache lists */
ACPI_MEMSET (acpi_gbl_memory_lists, 0, sizeof (struct acpi_memory_list) * ACPI_NUM_MEM_LISTS);
......
......@@ -64,7 +64,7 @@
/* Version string */
#define ACPI_CA_VERSION 0x20040220
#define ACPI_CA_VERSION 0x20040311
/* Maximum objects in the various object caches */
......@@ -185,6 +185,10 @@
#define ACPI_SMBUS_BUFFER_SIZE 34
/* Number of strings associated with the _OSI reserved method */
#define ACPI_NUM_OSI_STRINGS 4
/******************************************************************************
*
......
......@@ -79,6 +79,14 @@ extern u32 acpi_dbg_layer;
extern u32 acpi_gbl_nesting_level;
/*****************************************************************************
*
* Runtime configuration
*
****************************************************************************/
ACPI_EXTERN u8 acpi_gbl_create_osi_method;
ACPI_EXTERN u8 acpi_gbl_all_methods_serialized;
/*****************************************************************************
*
......@@ -169,6 +177,7 @@ extern const char *acpi_gbl_sleep_state_names[ACPI_
extern const char *acpi_gbl_highest_dstate_names[4];
extern const struct acpi_opcode_info acpi_gbl_aml_op_info[AML_NUM_OPCODES];
extern const char *acpi_gbl_region_types[ACPI_NUM_PREDEFINED_REGIONS];
extern const char *acpi_gbl_valid_osi_strings[ACPI_NUM_OSI_STRINGS];
/*****************************************************************************
......@@ -179,7 +188,7 @@ extern const char *acpi_gbl_region_types[ACPI_NUM_P
#define NUM_NS_TYPES ACPI_TYPE_INVALID+1
#if defined (ACPI_NO_METHOD_EXECUTION) || defined (ACPI_CONSTANT_EVAL_ONLY)
#if !defined (ACPI_NO_METHOD_EXECUTION) || defined (ACPI_CONSTANT_EVAL_ONLY)
#define NUM_PREDEFINED_NAMES 10
#else
#define NUM_PREDEFINED_NAMES 9
......
......@@ -681,7 +681,4 @@
#endif /* ACPI_DBG_TRACK_ALLOCATIONS */
#define ACPI_GET_STACK_POINTER _asm {mov eax, ebx}
#endif /* ACMACROS_H */
......@@ -180,7 +180,11 @@ struct acpi_object_event
};
#define INFINITE_CONCURRENCY 0xFF
#define ACPI_INFINITE_CONCURRENCY 0xFF
typedef
acpi_status (*ACPI_INTERNAL_METHOD) (
struct acpi_walk_state *walk_state);
struct acpi_object_method
{
......@@ -190,6 +194,7 @@ struct acpi_object_method
u32 aml_length;
void *semaphore;
u8 *aml_start;
ACPI_INTERNAL_METHOD implementation;
u8 concurrency;
u8 thread_count;
acpi_owner_id owning_id;
......
......@@ -450,7 +450,7 @@ acpi_status asmlinkage
acpi_enter_sleep_state (
u8 sleep_state);
acpi_status
acpi_status asmlinkage
acpi_enter_sleep_state_s4bios (
void);
......
......@@ -349,7 +349,6 @@ typedef u64 acpi_integer;
/*
* Power state values
*/
#define ACPI_STATE_UNKNOWN (u8) 0xFF
#define ACPI_STATE_S0 (u8) 0
......@@ -393,7 +392,6 @@ typedef u64 acpi_integer;
#define ACPI_NOTIFY_BUS_MODE_MISMATCH (u8) 6
#define ACPI_NOTIFY_POWER_FAULT (u8) 7
/*
* Table types. These values are passed to the table related APIs
*/
......@@ -409,7 +407,6 @@ typedef u32 acpi_table_type;
#define ACPI_TABLE_MAX 6
#define NUM_ACPI_TABLE_TYPES (ACPI_TABLE_MAX+1)
/*
* Types associated with ACPI names and objects. The first group of
* values (up to ACPI_TYPE_EXTERNAL_MAX) correspond to the definition
......@@ -794,7 +791,7 @@ acpi_status (*acpi_init_handler) (
#define ACPI_INIT_DEVICE_INI 1
/* Address Spaces (Operation Regions */
/* Address Spaces (For Operation Regions) */
typedef
acpi_status (*acpi_adr_space_handler) (
......
......@@ -52,7 +52,6 @@ acpi_status (*acpi_pkg_callback) (
union acpi_generic_state *state,
void *context);
acpi_status
acpi_ut_walk_package_tree (
union acpi_operand_object *source_object,
......@@ -60,7 +59,6 @@ acpi_ut_walk_package_tree (
acpi_pkg_callback walk_callback,
void *context);
struct acpi_pkg_info
{
u8 *free_space;
......@@ -475,6 +473,10 @@ acpi_ut_delete_internal_object_list (
#define METHOD_NAME__PRS "_PRS"
acpi_status
acpi_ut_osi_implementation (
struct acpi_walk_state *walk_state);
acpi_status
acpi_ut_evaluate_object (
struct acpi_namespace_node *prefix_node,
......
......@@ -496,11 +496,17 @@ typedef enum
} AML_ACCESS_ATTRIBUTE;
/* bit fields in method_flags byte */
/* Bit fields in method_flags byte */
#define METHOD_FLAGS_ARG_COUNT 0x07
#define METHOD_FLAGS_SERIALIZED 0x08
#define METHOD_FLAGS_SYNCH_LEVEL 0xF0
#define AML_METHOD_ARG_COUNT 0x07
#define AML_METHOD_SERIALIZED 0x08
#define AML_METHOD_SYNCH_LEVEL 0xF0
/* METHOD_FLAGS_ARG_COUNT is not used internally, define additional flags */
#define AML_METHOD_INTERNAL_ONLY 0x01
#define AML_METHOD_RESERVED1 0x02
#define AML_METHOD_RESERVED2 0x04
#endif /* __AMLCODE_H__ */
......@@ -28,6 +28,8 @@
#ifdef __KERNEL__
#include <asm/system.h> /* defines cmpxchg */
#define COMPILER_DEPENDENT_INT64 long long
#define COMPILER_DEPENDENT_UINT64 unsigned long long
......@@ -61,33 +63,36 @@
* Immediate values in the assembly are preceded by "$" as in "$0x1"
* The final asm parameter are the operation altered non-output registers.
*/
static inline int
__acpi_acquire_global_lock (unsigned int *lock)
{
unsigned int old, new, val;
do {
old = *lock;
new = (((old & ~0x3) + 2) + ((old >> 1) & 0x1));
val = cmpxchg(lock, old, new);
} while (unlikely (val != old));
return (new < 3) ? -1 : 0;
}
static inline int
__acpi_release_global_lock (unsigned int *lock)
{
unsigned int old, new, val;
do {
old = *lock;
new = old & ~0x3;
val = cmpxchg(lock, old, new);
} while (unlikely (val != old));
return old & 0x1;
}
#define ACPI_ACQUIRE_GLOBAL_LOCK(GLptr, Acq) \
do { \
int dummy; \
asm("1: movl (%1),%%eax;" \
"movl %%eax,%%edx;" \
"andl %2,%%edx;" \
"btsl $0x1,%%edx;" \
"adcl $0x0,%%edx;" \
"lock; cmpxchgl %%edx,(%1);" \
"jnz 1b;" \
"cmpb $0x3,%%dl;" \
"sbbl %%eax,%%eax" \
:"=a"(Acq),"=c"(dummy):"c"(GLptr),"i"(~1L):"dx"); \
} while(0)
((Acq) = __acpi_acquire_global_lock((unsigned int *) GLptr))
#define ACPI_RELEASE_GLOBAL_LOCK(GLptr, Acq) \
do { \
int dummy; \
asm("1: movl (%1),%%eax;" \
"movl %%eax,%%edx;" \
"andl %2,%%edx;" \
"lock; cmpxchgl %%edx,(%1);" \
"jnz 1b;" \
"andl $0x1,%%eax" \
:"=a"(Acq),"=c"(dummy):"c"(GLptr),"i"(~3L):"dx"); \
} while(0)
((Acq) = __acpi_release_global_lock((unsigned int *) GLptr))
/*
* Math helper asm macros
......
......@@ -60,7 +60,7 @@ __acpi_acquire_global_lock (unsigned int *lock)
do {
old = *lock;
new = (((old & ~0x3) + 2) + ((old >> 1) & 0x1));
val = cmpxchg4_locked(lock, new, old);
val = cmpxchg(lock, old, new);
} while (unlikely (val != old));
return (new < 3) ? -1 : 0;
}
......@@ -72,7 +72,7 @@ __acpi_release_global_lock (unsigned int *lock)
do {
old = *lock;
new = old & ~0x3;
val = cmpxchg4_locked(lock, new, old);
val = cmpxchg(lock, old, new);
} while (unlikely (val != old));
return old & 0x1;
}
......
......@@ -276,13 +276,6 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),\
(unsigned long)(n),sizeof(*(ptr))))
static inline __u32 cmpxchg4_locked(__u32 *ptr, __u32 old, __u32 new)
{
asm volatile("lock ; cmpxchgl %k1,%2" :
"=r" (new) : "0" (old), "m" (*(__u32 *)ptr) : "memory");
return new;
}
#ifdef CONFIG_SMP
#define smp_mb() mb()
#define smp_rmb() rmb()
......
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