diff options
author | Paul Mackerras <paulus@samba.org> | 2007-04-13 03:50:03 +1000 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2007-04-13 03:50:03 +1000 |
commit | e049d1ca3094f3d1d94617f456a9961202f96e3a (patch) | |
tree | a30397ad22f2fbea268bd28fa69c60aad9dfa62a /drivers/acpi/events | |
parent | edfac96a92b88d3b0b53e3f8231b74beee9ecd1d (diff) | |
parent | 80584ff3b99c36ead7e130e453b3a48b18072d18 (diff) |
Merge branch 'linux-2.6' into for-2.6.22
Diffstat (limited to 'drivers/acpi/events')
-rw-r--r-- | drivers/acpi/events/evmisc.c | 33 | ||||
-rw-r--r-- | drivers/acpi/events/evregion.c | 15 | ||||
-rw-r--r-- | drivers/acpi/events/evxface.c | 6 |
3 files changed, 44 insertions, 10 deletions
diff --git a/drivers/acpi/events/evmisc.c b/drivers/acpi/events/evmisc.c index d572700197f..cae786ca860 100644 --- a/drivers/acpi/events/evmisc.c +++ b/drivers/acpi/events/evmisc.c @@ -196,11 +196,15 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node * node, notify_info->notify.value = (u16) notify_value; notify_info->notify.handler_obj = handler_obj; - acpi_ex_relinquish_interpreter(); + acpi_ex_exit_interpreter(); acpi_ev_notify_dispatch(notify_info); - acpi_ex_reacquire_interpreter(); + status = acpi_ex_enter_interpreter(); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + } if (!handler_obj) { @@ -423,6 +427,8 @@ static acpi_status acpi_ev_remove_global_lock_handler(void) * the global lock appear as a standard mutex on the OS side. * *****************************************************************************/ +static acpi_thread_id acpi_ev_global_lock_thread_id; +static int acpi_ev_global_lock_acquired; acpi_status acpi_ev_acquire_global_lock(u16 timeout) { @@ -435,11 +441,24 @@ acpi_status acpi_ev_acquire_global_lock(u16 timeout) * Only one thread can acquire the GL at a time, the global_lock_mutex * enforces this. This interface releases the interpreter if we must wait. */ - status = acpi_ex_system_wait_mutex(acpi_gbl_global_lock_mutex, timeout); + status = acpi_ex_system_wait_mutex(acpi_gbl_global_lock_mutex, 0); + if (status == AE_TIME) { + if (acpi_ev_global_lock_thread_id == acpi_os_get_thread_id()) { + acpi_ev_global_lock_acquired++; + return AE_OK; + } + } + + if (ACPI_FAILURE(status)) { + status = acpi_ex_system_wait_mutex(acpi_gbl_global_lock_mutex, timeout); + } if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } + acpi_ev_global_lock_thread_id = acpi_os_get_thread_id(); + acpi_ev_global_lock_acquired++; + /* * Make sure that a global lock actually exists. If not, just treat * the lock as a standard mutex. @@ -506,6 +525,11 @@ acpi_status acpi_ev_release_global_lock(void) return_ACPI_STATUS(AE_NOT_ACQUIRED); } + acpi_ev_global_lock_acquired--; + if (acpi_ev_global_lock_acquired > 0) { + return AE_OK; + } + if (acpi_gbl_global_lock_present) { /* Allow any thread to release the lock */ @@ -529,7 +553,8 @@ acpi_status acpi_ev_release_global_lock(void) acpi_gbl_global_lock_acquired = FALSE; /* Release the local GL mutex */ - + acpi_ev_global_lock_thread_id = NULL; + acpi_ev_global_lock_acquired = 0; acpi_os_release_mutex(acpi_gbl_global_lock_mutex); return_ACPI_STATUS(status); } diff --git a/drivers/acpi/events/evregion.c b/drivers/acpi/events/evregion.c index e99f0c435a4..96b0e843174 100644 --- a/drivers/acpi/events/evregion.c +++ b/drivers/acpi/events/evregion.c @@ -291,6 +291,7 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, u32 bit_width, acpi_integer * value) { acpi_status status; + acpi_status status2; acpi_adr_space_handler handler; acpi_adr_space_setup region_setup; union acpi_operand_object *handler_desc; @@ -344,7 +345,7 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, * setup will potentially execute control methods * (e.g., _REG method for this region) */ - acpi_ex_relinquish_interpreter(); + acpi_ex_exit_interpreter(); status = region_setup(region_obj, ACPI_REGION_ACTIVATE, handler_desc->address_space.context, @@ -352,7 +353,10 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, /* Re-enter the interpreter */ - acpi_ex_reacquire_interpreter(); + status2 = acpi_ex_enter_interpreter(); + if (ACPI_FAILURE(status2)) { + return_ACPI_STATUS(status2); + } /* Check for failure of the Region Setup */ @@ -405,7 +409,7 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, * exit the interpreter because the handler *might* block -- we don't * know what it will do, so we can't hold the lock on the intepreter. */ - acpi_ex_relinquish_interpreter(); + acpi_ex_exit_interpreter(); } /* Call the handler */ @@ -426,7 +430,10 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, * We just returned from a non-default handler, we must re-enter the * interpreter */ - acpi_ex_reacquire_interpreter(); + status2 = acpi_ex_enter_interpreter(); + if (ACPI_FAILURE(status2)) { + return_ACPI_STATUS(status2); + } } return_ACPI_STATUS(status); diff --git a/drivers/acpi/events/evxface.c b/drivers/acpi/events/evxface.c index 685a103a358..a3379bafa67 100644 --- a/drivers/acpi/events/evxface.c +++ b/drivers/acpi/events/evxface.c @@ -768,9 +768,11 @@ acpi_status acpi_acquire_global_lock(u16 timeout, u32 * handle) return (AE_BAD_PARAMETER); } - /* Must lock interpreter to prevent race conditions */ + status = acpi_ex_enter_interpreter(); + if (ACPI_FAILURE(status)) { + return (status); + } - acpi_ex_enter_interpreter(); status = acpi_ev_acquire_global_lock(timeout); acpi_ex_exit_interpreter(); |