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. ...@@ -116,6 +116,10 @@ running once the system is up.
acpi_irq_isa= [HW,ACPI] If irq_balance, Mark listed IRQs used by ISA acpi_irq_isa= [HW,ACPI] If irq_balance, Mark listed IRQs used by ISA
Format: <irq>,<irq>... Format: <irq>,<irq>...
acpi_osi= [HW,ACPI] empty param disables _OSI
acpi_serialize [HW,ACPI] force serialization of AML methods
ad1816= [HW,OSS] ad1816= [HW,OSS]
Format: <io>,<irq>,<dma>,<dma2> Format: <io>,<irq>,<dma>,<dma2>
See also Documentation/sound/oss/AD1816. See also Documentation/sound/oss/AD1816.
......
...@@ -128,7 +128,9 @@ static int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size) ...@@ -128,7 +128,9 @@ static int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size)
return 0; return 0;
} }
#endif /* CONFIG_PCI_MMCONFIG */ #else
#define acpi_parse_mcfg NULL
#endif /* !CONFIG_PCI_MMCONFIG */
#ifdef CONFIG_X86_LOCAL_APIC #ifdef CONFIG_X86_LOCAL_APIC
static int __init static int __init
...@@ -424,6 +426,8 @@ static int __init acpi_parse_hpet(unsigned long phys, unsigned long size) ...@@ -424,6 +426,8 @@ static int __init acpi_parse_hpet(unsigned long phys, unsigned long size)
hpet_address); hpet_address);
return 0; return 0;
} }
#else
#define acpi_parse_hpet NULL
#endif #endif
/* detect the location of the ACPI PM Timer */ /* detect the location of the ACPI PM Timer */
...@@ -454,6 +458,8 @@ static int __init acpi_parse_fadt(unsigned long phys, unsigned long size) ...@@ -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); printk(KERN_INFO PREFIX "PM-Timer IO Port: %#x\n", pmtmr_ioport);
return 0; return 0;
} }
#else
#define acpi_parse_fadt NULL
#endif #endif
...@@ -666,7 +672,7 @@ acpi_boot_init (void) ...@@ -666,7 +672,7 @@ acpi_boot_init (void)
return error; return error;
} }
(void) acpi_table_parse(ACPI_BOOT, acpi_parse_sbf); acpi_table_parse(ACPI_BOOT, acpi_parse_sbf);
/* /*
* blacklist may disable ACPI entirely * blacklist may disable ACPI entirely
...@@ -683,19 +689,9 @@ acpi_boot_init (void) ...@@ -683,19 +689,9 @@ acpi_boot_init (void)
*/ */
acpi_process_madt(); acpi_process_madt();
#ifdef CONFIG_X86_PM_TIMER
acpi_table_parse(ACPI_FADT, acpi_parse_fadt); acpi_table_parse(ACPI_FADT, acpi_parse_fadt);
#endif acpi_table_parse(ACPI_HPET, acpi_parse_hpet);
acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg);
#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
return 0; return 0;
} }
......
...@@ -48,7 +48,7 @@ static void __init sbf_write(u8 v) ...@@ -48,7 +48,7 @@ static void __init sbf_write(u8 v)
if(!parity(v)) if(!parity(v))
v|=SBF_PARITY; 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); spin_lock_irqsave(&rtc_lock, flags);
CMOS_WRITE(v, sbf_port); CMOS_WRITE(v, sbf_port);
......
...@@ -106,7 +106,7 @@ acpi_ds_parse_method ( ...@@ -106,7 +106,7 @@ acpi_ds_parse_method (
/* Create a mutex for the method if there is a concurrency limit */ /* 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)) { (!obj_desc->method.semaphore)) {
status = acpi_os_create_semaphore (obj_desc->method.concurrency, status = acpi_os_create_semaphore (obj_desc->method.concurrency,
obj_desc->method.concurrency, obj_desc->method.concurrency,
...@@ -300,6 +300,7 @@ acpi_ds_call_control_method ( ...@@ -300,6 +300,7 @@ acpi_ds_call_control_method (
return_ACPI_STATUS (status); return_ACPI_STATUS (status);
} }
if (!(obj_desc->method.method_flags & AML_METHOD_INTERNAL_ONLY)) {
/* 1) Parse: Create a new walk state for the preempting walk */ /* 1) Parse: Create a new walk state for the preempting walk */
next_walk_state = acpi_ds_create_walk_state (obj_desc->method.owning_id, next_walk_state = acpi_ds_create_walk_state (obj_desc->method.owning_id,
...@@ -308,6 +309,7 @@ acpi_ds_call_control_method ( ...@@ -308,6 +309,7 @@ acpi_ds_call_control_method (
return_ACPI_STATUS (AE_NO_MEMORY); return_ACPI_STATUS (AE_NO_MEMORY);
} }
/* Create and init a Root Node */ /* Create and init a Root Node */
op = acpi_ps_create_scope_op (); op = acpi_ps_create_scope_op ();
...@@ -328,6 +330,7 @@ acpi_ds_call_control_method ( ...@@ -328,6 +330,7 @@ acpi_ds_call_control_method (
status = acpi_ps_parse_aml (next_walk_state); status = acpi_ps_parse_aml (next_walk_state);
acpi_ps_delete_parse_tree (op); acpi_ps_delete_parse_tree (op);
}
/* 2) Execute: Create a new state for the preempting walk */ /* 2) Execute: Create a new state for the preempting walk */
...@@ -337,7 +340,6 @@ acpi_ds_call_control_method ( ...@@ -337,7 +340,6 @@ acpi_ds_call_control_method (
status = AE_NO_MEMORY; status = AE_NO_MEMORY;
goto cleanup; goto cleanup;
} }
/* /*
* The resolved arguments were put on the previous walk state's operand * The resolved arguments were put on the previous walk state's operand
* stack. Operands on the previous walk state stack always * stack. Operands on the previous walk state stack always
...@@ -369,16 +371,25 @@ acpi_ds_call_control_method ( ...@@ -369,16 +371,25 @@ acpi_ds_call_control_method (
ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
"Starting nested execution, newstate=%p\n", next_walk_state)); "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); return_ACPI_STATUS (AE_OK);
/* On error, we must delete the new walk state */ /* On error, we must delete the new walk state */
cleanup: 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); (void) acpi_ds_terminate_control_method (next_walk_state);
acpi_ds_delete_walk_state (next_walk_state); acpi_ds_delete_walk_state (next_walk_state);
return_ACPI_STATUS (status); return_ACPI_STATUS (status);
} }
...@@ -500,10 +511,30 @@ acpi_ds_terminate_control_method ( ...@@ -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) { 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 * There are no more threads executing this method. Perform
* additional cleanup. * additional cleanup.
......
...@@ -149,6 +149,11 @@ acpi_ev_gpe_detect ( ...@@ -149,6 +149,11 @@ acpi_ev_gpe_detect (
ACPI_FUNCTION_NAME ("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 */ /* Examine all GPE blocks attached to this interrupt level */
......
...@@ -587,27 +587,33 @@ acpi_ex_create_method ( ...@@ -587,27 +587,33 @@ acpi_ex_create_method (
obj_desc->method.aml_start = aml_start; obj_desc->method.aml_start = aml_start;
obj_desc->method.aml_length = aml_length; 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; method_flags = (u8) operand[1]->integer.value;
obj_desc->method.method_flags = method_flags; obj_desc->method.method_flags = (u8) (method_flags & ~AML_METHOD_ARG_COUNT);
obj_desc->method.param_count = (u8) (method_flags & METHOD_FLAGS_ARG_COUNT); obj_desc->method.param_count = (u8) (method_flags & AML_METHOD_ARG_COUNT);
/* /*
* Get the concurrency count. If required, a semaphore will be * Get the concurrency count. If required, a semaphore will be
* created for this method when it is parsed. * 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 1.0: Concurrency = 1
* ACPI 2.0: Concurrency = (sync_level (in method declaration) + 1) * ACPI 2.0: Concurrency = (sync_level (in method declaration) + 1)
*/ */
obj_desc->method.concurrency = (u8) obj_desc->method.concurrency = (u8)
(((method_flags & METHOD_FLAGS_SYNCH_LEVEL) >> 4) + 1); (((method_flags & AML_METHOD_SYNCH_LEVEL) >> 4) + 1);
} }
else { else {
obj_desc->method.concurrency = INFINITE_CONCURRENCY; obj_desc->method.concurrency = ACPI_INFINITE_CONCURRENCY;
} }
/* Attach the new object to the method Node */ /* Attach the new object to the method Node */
......
...@@ -176,9 +176,11 @@ acpi_ex_acquire_mutex ( ...@@ -176,9 +176,11 @@ acpi_ex_acquire_mutex (
/* /*
* Support for multiple acquires by the owning thread * Support for multiple acquires by the owning thread
*/ */
if (obj_desc->mutex.owner_thread) {
/* Special case for Global Lock, allow all threads */
if ((obj_desc->mutex.owner_thread) && if ((obj_desc->mutex.owner_thread->thread_id == walk_state->thread->thread_id) ||
(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, * The mutex is already owned by this thread,
* just increment the acquisition depth * just increment the acquisition depth
...@@ -186,6 +188,7 @@ acpi_ex_acquire_mutex ( ...@@ -186,6 +188,7 @@ acpi_ex_acquire_mutex (
obj_desc->mutex.acquisition_depth++; obj_desc->mutex.acquisition_depth++;
return_ACPI_STATUS (AE_OK); return_ACPI_STATUS (AE_OK);
} }
}
/* Acquire the mutex, wait if necessary */ /* Acquire the mutex, wait if necessary */
...@@ -254,9 +257,12 @@ acpi_ex_release_mutex ( ...@@ -254,9 +257,12 @@ acpi_ex_release_mutex (
return_ACPI_STATUS (AE_AML_INTERNAL); return_ACPI_STATUS (AE_AML_INTERNAL);
} }
/* The Mutex is owned, but this thread must be the owner */ /*
* The Mutex is owned, but this thread must be the owner.
if (obj_desc->mutex.owner_thread->thread_id != walk_state->thread->thread_id) { * 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 (( ACPI_REPORT_ERROR ((
"Thread %X cannot release Mutex [%4.4s] acquired by thread %X\n", "Thread %X cannot release Mutex [%4.4s] acquired by thread %X\n",
walk_state->thread->thread_id, walk_state->thread->thread_id,
......
...@@ -394,7 +394,7 @@ acpi_enter_sleep_state ( ...@@ -394,7 +394,7 @@ acpi_enter_sleep_state (
* *
******************************************************************************/ ******************************************************************************/
acpi_status acpi_status asmlinkage
acpi_enter_sleep_state_s4bios ( acpi_enter_sleep_state_s4bios (
void) void)
{ {
......
...@@ -105,8 +105,15 @@ acpi_ns_root_initialize (void) ...@@ -105,8 +105,15 @@ acpi_ns_root_initialize (void)
"Entering predefined entries into namespace\n")); "Entering predefined entries into namespace\n"));
for (init_val = acpi_gbl_pre_defined_names; init_val->name; init_val++) { 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, 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 */ { if (ACPI_FAILURE (status) || (!new_node)) /* Must be on same line for code converter */ {
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
...@@ -122,7 +129,8 @@ acpi_ns_root_initialize (void) ...@@ -122,7 +129,8 @@ acpi_ns_root_initialize (void)
if (init_val->val) { if (init_val->val) {
status = acpi_os_predefined_override (init_val, &val); status = acpi_os_predefined_override (init_val, &val);
if (ACPI_FAILURE (status)) { 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)); init_val->name));
} }
...@@ -147,15 +155,20 @@ acpi_ns_root_initialize (void) ...@@ -147,15 +155,20 @@ acpi_ns_root_initialize (void)
*/ */
switch (init_val->type) { switch (init_val->type) {
case ACPI_TYPE_METHOD: case ACPI_TYPE_METHOD:
obj_desc->method.param_count = obj_desc->method.param_count = (u8) ACPI_STRTOUL
(u8) ACPI_STRTOUL (val, NULL, 10); (val, NULL, 10);
obj_desc->common.flags |= AOPOBJ_DATA_VALID; 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; 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 #endif
break; break;
...@@ -180,8 +193,8 @@ acpi_ns_root_initialize (void) ...@@ -180,8 +193,8 @@ acpi_ns_root_initialize (void)
case ACPI_TYPE_MUTEX: case ACPI_TYPE_MUTEX:
obj_desc->mutex.node = new_node; obj_desc->mutex.node = new_node;
obj_desc->mutex.sync_level = obj_desc->mutex.sync_level = (u16) ACPI_STRTOUL
(u16) ACPI_STRTOUL (val, NULL, 10); (val, NULL, 10);
if (ACPI_STRCMP (init_val->name, "_GL_") == 0) { if (ACPI_STRCMP (init_val->name, "_GL_") == 0) {
/* /*
...@@ -213,6 +226,7 @@ acpi_ns_root_initialize (void) ...@@ -213,6 +226,7 @@ acpi_ns_root_initialize (void)
default: default:
ACPI_REPORT_ERROR (("Unsupported initial type value %X\n", ACPI_REPORT_ERROR (("Unsupported initial type value %X\n",
init_val->type)); init_val->type));
acpi_ut_remove_reference (obj_desc); acpi_ut_remove_reference (obj_desc);
......
...@@ -334,10 +334,11 @@ acpi_ns_install_node ( ...@@ -334,10 +334,11 @@ acpi_ns_install_node (
node->owner_id = owner_id; node->owner_id = owner_id;
node->type = (u8) type; node->type = (u8) type;
ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "%4.4s (%s) added to %4.4s (%s) %p at %p\n", ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
acpi_ut_get_node_name (node), acpi_ut_get_type_name (node->type), "%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), 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 * Increment the reference count(s) of all parents up to
......
...@@ -82,11 +82,11 @@ acpi_ns_evaluate_relative ( ...@@ -82,11 +82,11 @@ acpi_ns_evaluate_relative (
union acpi_operand_object **params, union acpi_operand_object **params,
union acpi_operand_object **return_object) union acpi_operand_object **return_object)
{ {
struct acpi_namespace_node *prefix_node;
acpi_status status; acpi_status status;
struct acpi_namespace_node *prefix_node;
struct acpi_namespace_node *node = NULL; struct acpi_namespace_node *node = NULL;
union acpi_generic_state *scope_info;
char *internal_path = NULL; char *internal_path = NULL;
union acpi_generic_state scope_info;
ACPI_FUNCTION_TRACE ("ns_evaluate_relative"); ACPI_FUNCTION_TRACE ("ns_evaluate_relative");
...@@ -106,6 +106,11 @@ acpi_ns_evaluate_relative ( ...@@ -106,6 +106,11 @@ acpi_ns_evaluate_relative (
return_ACPI_STATUS (status); return_ACPI_STATUS (status);
} }
scope_info = acpi_ut_create_generic_state ();
if (!scope_info) {
goto cleanup1;
}
/* Get the prefix handle and Node */ /* Get the prefix handle and Node */
status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
...@@ -122,8 +127,8 @@ acpi_ns_evaluate_relative ( ...@@ -122,8 +127,8 @@ acpi_ns_evaluate_relative (
/* Lookup the name in the namespace */ /* Lookup the name in the namespace */
scope_info.scope.node = prefix_node; scope_info->scope.node = prefix_node;
status = acpi_ns_lookup (&scope_info, internal_path, ACPI_TYPE_ANY, status = acpi_ns_lookup (scope_info, internal_path, ACPI_TYPE_ANY,
ACPI_IMODE_EXECUTE, ACPI_NS_NO_UPSEARCH, NULL, ACPI_IMODE_EXECUTE, ACPI_NS_NO_UPSEARCH, NULL,
&node); &node);
...@@ -148,7 +153,9 @@ acpi_ns_evaluate_relative ( ...@@ -148,7 +153,9 @@ acpi_ns_evaluate_relative (
pathname)); pathname));
cleanup: cleanup:
acpi_ut_delete_generic_state (scope_info);
cleanup1:
ACPI_MEM_FREE (internal_path); ACPI_MEM_FREE (internal_path);
return_ACPI_STATUS (status); return_ACPI_STATUS (status);
} }
......
...@@ -1012,3 +1012,39 @@ acpi_os_name_setup(char *str) ...@@ -1012,3 +1012,39 @@ acpi_os_name_setup(char *str)
} }
__setup("acpi_os_name=", acpi_os_name_setup); __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 ( ...@@ -426,7 +426,7 @@ acpi_ps_parse_loop (
acpi_status status = AE_OK; acpi_status status = AE_OK;
union acpi_parse_object *op = NULL; /* current op */ union acpi_parse_object *op = NULL; /* current op */
union acpi_parse_object *arg = NULL; 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; struct acpi_parse_state *parser_state;
u8 *aml_op_start = NULL; u8 *aml_op_start = NULL;
...@@ -547,8 +547,17 @@ acpi_ps_parse_loop ( ...@@ -547,8 +547,17 @@ acpi_ps_parse_loop (
/* Create Op structure and append to parent's argument list */ /* Create Op structure and append to parent's argument list */
if (walk_state->op_info->flags & AML_NAMED) { if (walk_state->op_info->flags & AML_NAMED) {
pre_op.common.value.arg = NULL; /* Allocate a new pre_op if necessary */
pre_op.common.aml_opcode = walk_state->opcode;
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 * Get and append arguments until we find the node that contains
...@@ -562,7 +571,7 @@ acpi_ps_parse_loop ( ...@@ -562,7 +571,7 @@ acpi_ps_parse_loop (
goto close_this_op; 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); INCREMENT_ARG_LIST (walk_state->arg_types);
} }
...@@ -603,7 +612,7 @@ acpi_ps_parse_loop ( ...@@ -603,7 +612,7 @@ acpi_ps_parse_loop (
goto close_this_op; 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++; acpi_gbl_depth++;
if (op->common.aml_opcode == AML_REGION_OP) { if (op->common.aml_opcode == AML_REGION_OP) {
...@@ -854,6 +863,10 @@ acpi_ps_parse_loop ( ...@@ -854,6 +863,10 @@ acpi_ps_parse_loop (
acpi_ps_complete_this_op (walk_state, op); acpi_ps_complete_this_op (walk_state, op);
op = NULL; op = NULL;
if (pre_op) {
acpi_ps_free_op (pre_op);
pre_op = NULL;
}
switch (status) { switch (status) {
case AE_OK: case AE_OK:
...@@ -1118,6 +1131,27 @@ acpi_ps_parse_aml ( ...@@ -1118,6 +1131,27 @@ acpi_ps_parse_aml (
else if (status != AE_OK) { else if (status != AE_OK) {
ACPI_REPORT_METHOD_ERROR ("Method execution failed", ACPI_REPORT_METHOD_ERROR ("Method execution failed",
walk_state->method_node, NULL, status); 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 */ /* We are done with this walk, move on to the parent if any */
......
...@@ -167,7 +167,6 @@ acpi_ps_push_scope ( ...@@ -167,7 +167,6 @@ acpi_ps_push_scope (
return_ACPI_STATUS (AE_NO_MEMORY); return_ACPI_STATUS (AE_NO_MEMORY);
} }
scope->common.data_type = ACPI_DESC_TYPE_STATE_PSCOPE; scope->common.data_type = ACPI_DESC_TYPE_STATE_PSCOPE;
scope->parse_scope.op = op; scope->parse_scope.op = op;
scope->parse_scope.arg_list = remaining_args; scope->parse_scope.arg_list = remaining_args;
...@@ -178,13 +177,11 @@ acpi_ps_push_scope ( ...@@ -178,13 +177,11 @@ acpi_ps_push_scope (
acpi_ut_push_generic_state (&parser_state->scope, scope); acpi_ut_push_generic_state (&parser_state->scope, scope);
if (arg_count == ACPI_VAR_ARGS) { if (arg_count == ACPI_VAR_ARGS) {
/* multiple arguments */ /* multiple arguments */
scope->parse_scope.arg_end = parser_state->pkg_end; scope->parse_scope.arg_end = parser_state->pkg_end;
} }
else { else {
/* single argument */ /* single argument */
...@@ -241,7 +238,6 @@ acpi_ps_pop_scope ( ...@@ -241,7 +238,6 @@ acpi_ps_pop_scope (
acpi_ut_delete_generic_state (scope); acpi_ut_delete_generic_state (scope);
} }
else { else {
/* empty parse stack, prepare to fetch next opcode */ /* empty parse stack, prepare to fetch next opcode */
...@@ -250,7 +246,6 @@ acpi_ps_pop_scope ( ...@@ -250,7 +246,6 @@ acpi_ps_pop_scope (
*arg_count = 0; *arg_count = 0;
} }
ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Popped Op %p Args %X\n", *op, *arg_count)); ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Popped Op %p Args %X\n", *op, *arg_count));
return_VOID; return_VOID;
} }
...@@ -275,14 +270,14 @@ acpi_ps_cleanup_scope ( ...@@ -275,14 +270,14 @@ acpi_ps_cleanup_scope (
{ {
union acpi_generic_state *scope; union acpi_generic_state *scope;
ACPI_FUNCTION_TRACE_PTR ("ps_cleanup_scope", parser_state); ACPI_FUNCTION_TRACE_PTR ("ps_cleanup_scope", parser_state);
if (!parser_state) { if (!parser_state) {
return; return_VOID;
} }
/* Delete anything on the scope stack */ /* Delete anything on the scope stack */
while (parser_state->scope) { while (parser_state->scope) {
......
...@@ -23,6 +23,18 @@ ...@@ -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/kernel.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/init.h> #include <linux/init.h>
......
...@@ -8,11 +8,14 @@ ...@@ -8,11 +8,14 @@
#include <linux/pm.h> #include <linux/pm.h>
#include <linux/init.h> #include <linux/init.h>
#include <acpi/acpi_bus.h> #include <acpi/acpi_bus.h>
#include <linux/sched.h>
static void static void
acpi_power_off (void) acpi_power_off (void)
{ {
printk("%s called\n",__FUNCTION__); 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_enter_sleep_state_prep(ACPI_STATE_S5);
ACPI_DISABLE_IRQS(); ACPI_DISABLE_IRQS();
acpi_enter_sleep_state(ACPI_STATE_S5); acpi_enter_sleep_state(ACPI_STATE_S5);
......
...@@ -386,8 +386,13 @@ acpi_table_parse ( ...@@ -386,8 +386,13 @@ acpi_table_parse (
for (i = 0; i < sdt_count; i++) { for (i = 0; i < sdt_count; i++) {
if (sdt_entry[i].id != id) if (sdt_entry[i].id != id)
continue; continue;
handler(sdt_entry[i].pa, sdt_entry[i].size);
count++; 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; return count;
......
...@@ -51,6 +51,62 @@ ...@@ -51,6 +51,62 @@
ACPI_MODULE_NAME ("uteval") 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 * FUNCTION: acpi_ut_evaluate_object
......
...@@ -185,6 +185,15 @@ const char *acpi_gbl_highest_dstate_names[4] = { ...@@ -185,6 +185,15 @@ const char *acpi_gbl_highest_dstate_names[4] = {
"_S3D", "_S3D",
"_S4D"}; "_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 * Namespace globals
...@@ -195,14 +204,10 @@ const char *acpi_gbl_highest_dstate_names[4] = { ...@@ -195,14 +204,10 @@ const char *acpi_gbl_highest_dstate_names[4] = {
/* /*
* Predefined ACPI Names (Built-in to the Interpreter) * 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: * 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. * during the initialization sequence.
*/ */
const struct acpi_predefined_names acpi_gbl_pre_defined_names[] = const struct acpi_predefined_names acpi_gbl_pre_defined_names[] =
{ {"_GPE", ACPI_TYPE_LOCAL_SCOPE, NULL}, { {"_GPE", ACPI_TYPE_LOCAL_SCOPE, NULL},
{"_PR_", 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[] = ...@@ -213,7 +218,7 @@ const struct acpi_predefined_names acpi_gbl_pre_defined_names[] =
{"_OS_", ACPI_TYPE_STRING, ACPI_OS_NAME}, {"_OS_", ACPI_TYPE_STRING, ACPI_OS_NAME},
{"_GL_", ACPI_TYPE_MUTEX, "0"}, {"_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"}, {"_OSI", ACPI_TYPE_METHOD, "1"},
#endif #endif
{NULL, ACPI_TYPE_ANY, NULL} /* Table terminator */ {NULL, ACPI_TYPE_ANY, NULL} /* Table terminator */
...@@ -224,7 +229,6 @@ const struct acpi_predefined_names acpi_gbl_pre_defined_names[] = ...@@ -224,7 +229,6 @@ const struct acpi_predefined_names acpi_gbl_pre_defined_names[] =
* Properties of the ACPI Object Types, both internal and external. * Properties of the ACPI Object Types, both internal and external.
* The table is indexed by values of acpi_object_type * The table is indexed by values of acpi_object_type
*/ */
const u8 acpi_gbl_ns_properties[] = const u8 acpi_gbl_ns_properties[] =
{ {
ACPI_NS_NORMAL, /* 00 Any */ ACPI_NS_NORMAL, /* 00 Any */
...@@ -303,10 +307,8 @@ acpi_ut_hex_to_ascii_char ( ...@@ -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_list acpi_gbl_table_lists[NUM_ACPI_TABLE_TYPES];
struct acpi_table_support acpi_gbl_table_data[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? */ /*********** Name, Signature, Global typed pointer Signature size, Type How many allowed?, Contains valid AML? */
...@@ -470,9 +472,8 @@ acpi_ut_get_event_name ( ...@@ -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 * 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 * 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"; static const char acpi_gbl_bad_type[] = "UNDEFINED";
#define TYPE_NAME_LENGTH 12 /* Maximum length of each string */ #define TYPE_NAME_LENGTH 12 /* Maximum length of each string */
...@@ -777,6 +778,11 @@ acpi_ut_init_globals ( ...@@ -777,6 +778,11 @@ acpi_ut_init_globals (
ACPI_FUNCTION_TRACE ("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 */ /* Memory allocation and cache lists */
ACPI_MEMSET (acpi_gbl_memory_lists, 0, sizeof (struct acpi_memory_list) * ACPI_NUM_MEM_LISTS); ACPI_MEMSET (acpi_gbl_memory_lists, 0, sizeof (struct acpi_memory_list) * ACPI_NUM_MEM_LISTS);
......
...@@ -64,7 +64,7 @@ ...@@ -64,7 +64,7 @@
/* Version string */ /* Version string */
#define ACPI_CA_VERSION 0x20040220 #define ACPI_CA_VERSION 0x20040311
/* Maximum objects in the various object caches */ /* Maximum objects in the various object caches */
...@@ -185,6 +185,10 @@ ...@@ -185,6 +185,10 @@
#define ACPI_SMBUS_BUFFER_SIZE 34 #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; ...@@ -79,6 +79,14 @@ extern u32 acpi_dbg_layer;
extern u32 acpi_gbl_nesting_level; 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_ ...@@ -169,6 +177,7 @@ extern const char *acpi_gbl_sleep_state_names[ACPI_
extern const char *acpi_gbl_highest_dstate_names[4]; 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 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_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 ...@@ -179,7 +188,7 @@ extern const char *acpi_gbl_region_types[ACPI_NUM_P
#define NUM_NS_TYPES ACPI_TYPE_INVALID+1 #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 #define NUM_PREDEFINED_NAMES 10
#else #else
#define NUM_PREDEFINED_NAMES 9 #define NUM_PREDEFINED_NAMES 9
......
...@@ -681,7 +681,4 @@ ...@@ -681,7 +681,4 @@
#endif /* ACPI_DBG_TRACK_ALLOCATIONS */ #endif /* ACPI_DBG_TRACK_ALLOCATIONS */
#define ACPI_GET_STACK_POINTER _asm {mov eax, ebx}
#endif /* ACMACROS_H */ #endif /* ACMACROS_H */
...@@ -180,7 +180,11 @@ struct acpi_object_event ...@@ -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 struct acpi_object_method
{ {
...@@ -190,6 +194,7 @@ struct acpi_object_method ...@@ -190,6 +194,7 @@ struct acpi_object_method
u32 aml_length; u32 aml_length;
void *semaphore; void *semaphore;
u8 *aml_start; u8 *aml_start;
ACPI_INTERNAL_METHOD implementation;
u8 concurrency; u8 concurrency;
u8 thread_count; u8 thread_count;
acpi_owner_id owning_id; acpi_owner_id owning_id;
......
...@@ -450,7 +450,7 @@ acpi_status asmlinkage ...@@ -450,7 +450,7 @@ acpi_status asmlinkage
acpi_enter_sleep_state ( acpi_enter_sleep_state (
u8 sleep_state); u8 sleep_state);
acpi_status acpi_status asmlinkage
acpi_enter_sleep_state_s4bios ( acpi_enter_sleep_state_s4bios (
void); void);
......
...@@ -349,7 +349,6 @@ typedef u64 acpi_integer; ...@@ -349,7 +349,6 @@ typedef u64 acpi_integer;
/* /*
* Power state values * Power state values
*/ */
#define ACPI_STATE_UNKNOWN (u8) 0xFF #define ACPI_STATE_UNKNOWN (u8) 0xFF
#define ACPI_STATE_S0 (u8) 0 #define ACPI_STATE_S0 (u8) 0
...@@ -393,7 +392,6 @@ typedef u64 acpi_integer; ...@@ -393,7 +392,6 @@ typedef u64 acpi_integer;
#define ACPI_NOTIFY_BUS_MODE_MISMATCH (u8) 6 #define ACPI_NOTIFY_BUS_MODE_MISMATCH (u8) 6
#define ACPI_NOTIFY_POWER_FAULT (u8) 7 #define ACPI_NOTIFY_POWER_FAULT (u8) 7
/* /*
* Table types. These values are passed to the table related APIs * Table types. These values are passed to the table related APIs
*/ */
...@@ -409,7 +407,6 @@ typedef u32 acpi_table_type; ...@@ -409,7 +407,6 @@ typedef u32 acpi_table_type;
#define ACPI_TABLE_MAX 6 #define ACPI_TABLE_MAX 6
#define NUM_ACPI_TABLE_TYPES (ACPI_TABLE_MAX+1) #define NUM_ACPI_TABLE_TYPES (ACPI_TABLE_MAX+1)
/* /*
* Types associated with ACPI names and objects. The first group of * Types associated with ACPI names and objects. The first group of
* values (up to ACPI_TYPE_EXTERNAL_MAX) correspond to the definition * values (up to ACPI_TYPE_EXTERNAL_MAX) correspond to the definition
...@@ -794,7 +791,7 @@ acpi_status (*acpi_init_handler) ( ...@@ -794,7 +791,7 @@ acpi_status (*acpi_init_handler) (
#define ACPI_INIT_DEVICE_INI 1 #define ACPI_INIT_DEVICE_INI 1
/* Address Spaces (Operation Regions */ /* Address Spaces (For Operation Regions) */
typedef typedef
acpi_status (*acpi_adr_space_handler) ( acpi_status (*acpi_adr_space_handler) (
......
...@@ -52,7 +52,6 @@ acpi_status (*acpi_pkg_callback) ( ...@@ -52,7 +52,6 @@ acpi_status (*acpi_pkg_callback) (
union acpi_generic_state *state, union acpi_generic_state *state,
void *context); void *context);
acpi_status acpi_status
acpi_ut_walk_package_tree ( acpi_ut_walk_package_tree (
union acpi_operand_object *source_object, union acpi_operand_object *source_object,
...@@ -60,7 +59,6 @@ acpi_ut_walk_package_tree ( ...@@ -60,7 +59,6 @@ acpi_ut_walk_package_tree (
acpi_pkg_callback walk_callback, acpi_pkg_callback walk_callback,
void *context); void *context);
struct acpi_pkg_info struct acpi_pkg_info
{ {
u8 *free_space; u8 *free_space;
...@@ -475,6 +473,10 @@ acpi_ut_delete_internal_object_list ( ...@@ -475,6 +473,10 @@ acpi_ut_delete_internal_object_list (
#define METHOD_NAME__PRS "_PRS" #define METHOD_NAME__PRS "_PRS"
acpi_status
acpi_ut_osi_implementation (
struct acpi_walk_state *walk_state);
acpi_status acpi_status
acpi_ut_evaluate_object ( acpi_ut_evaluate_object (
struct acpi_namespace_node *prefix_node, struct acpi_namespace_node *prefix_node,
......
...@@ -496,11 +496,17 @@ typedef enum ...@@ -496,11 +496,17 @@ typedef enum
} AML_ACCESS_ATTRIBUTE; } AML_ACCESS_ATTRIBUTE;
/* bit fields in method_flags byte */ /* Bit fields in method_flags byte */
#define METHOD_FLAGS_ARG_COUNT 0x07 #define AML_METHOD_ARG_COUNT 0x07
#define METHOD_FLAGS_SERIALIZED 0x08 #define AML_METHOD_SERIALIZED 0x08
#define METHOD_FLAGS_SYNCH_LEVEL 0xF0 #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__ */ #endif /* __AMLCODE_H__ */
...@@ -28,6 +28,8 @@ ...@@ -28,6 +28,8 @@
#ifdef __KERNEL__ #ifdef __KERNEL__
#include <asm/system.h> /* defines cmpxchg */
#define COMPILER_DEPENDENT_INT64 long long #define COMPILER_DEPENDENT_INT64 long long
#define COMPILER_DEPENDENT_UINT64 unsigned long long #define COMPILER_DEPENDENT_UINT64 unsigned long long
...@@ -61,33 +63,36 @@ ...@@ -61,33 +63,36 @@
* Immediate values in the assembly are preceded by "$" as in "$0x1" * Immediate values in the assembly are preceded by "$" as in "$0x1"
* The final asm parameter are the operation altered non-output registers. * 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) \ #define ACPI_ACQUIRE_GLOBAL_LOCK(GLptr, Acq) \
do { \ ((Acq) = __acpi_acquire_global_lock((unsigned int *) GLptr))
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)
#define ACPI_RELEASE_GLOBAL_LOCK(GLptr, Acq) \ #define ACPI_RELEASE_GLOBAL_LOCK(GLptr, Acq) \
do { \ ((Acq) = __acpi_release_global_lock((unsigned int *) GLptr))
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)
/* /*
* Math helper asm macros * Math helper asm macros
......
...@@ -60,7 +60,7 @@ __acpi_acquire_global_lock (unsigned int *lock) ...@@ -60,7 +60,7 @@ __acpi_acquire_global_lock (unsigned int *lock)
do { do {
old = *lock; old = *lock;
new = (((old & ~0x3) + 2) + ((old >> 1) & 0x1)); new = (((old & ~0x3) + 2) + ((old >> 1) & 0x1));
val = cmpxchg4_locked(lock, new, old); val = cmpxchg(lock, old, new);
} while (unlikely (val != old)); } while (unlikely (val != old));
return (new < 3) ? -1 : 0; return (new < 3) ? -1 : 0;
} }
...@@ -72,7 +72,7 @@ __acpi_release_global_lock (unsigned int *lock) ...@@ -72,7 +72,7 @@ __acpi_release_global_lock (unsigned int *lock)
do { do {
old = *lock; old = *lock;
new = old & ~0x3; new = old & ~0x3;
val = cmpxchg4_locked(lock, new, old); val = cmpxchg(lock, old, new);
} while (unlikely (val != old)); } while (unlikely (val != old));
return old & 0x1; return old & 0x1;
} }
......
...@@ -276,13 +276,6 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old, ...@@ -276,13 +276,6 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),\ ((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),\
(unsigned long)(n),sizeof(*(ptr)))) (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 #ifdef CONFIG_SMP
#define smp_mb() mb() #define smp_mb() mb()
#define smp_rmb() rmb() #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