summaryrefslogtreecommitdiff
path: root/drivers/acpi/events
diff options
context:
space:
mode:
authorBob Moore <robert.moore@intel.com>2008-04-10 19:06:37 +0400
committerLen Brown <len.brown@intel.com>2008-04-22 14:29:21 -0400
commitba886cd4ac957608777fbc8d137f6b9f0450e775 (patch)
treed7dabaa586af41c293977443ee20df6b6b13d171 /drivers/acpi/events
parentf654ecbfacb47d20e8cac087bbada1b947db846b (diff)
ACPICA: Update for mutiple global lock acquisitions by same thread
Allows AcpiAcquireGlobalLock external interface to be called multiple times by the same thread. Allows use of AML fields that require the global lock while the running AML is already holding the global lock. Signed-off-by: Bob Moore <robert.moore@intel.com> Signed-off-by: Alexey Starikovskiy <astarikovskiy@suse.de> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/events')
-rw-r--r--drivers/acpi/events/evmisc.c11
-rw-r--r--drivers/acpi/events/evxface.c26
2 files changed, 28 insertions, 9 deletions
diff --git a/drivers/acpi/events/evmisc.c b/drivers/acpi/events/evmisc.c
index 21cb749d0c75..2d34663dc1ed 100644
--- a/drivers/acpi/events/evmisc.c
+++ b/drivers/acpi/events/evmisc.c
@@ -439,7 +439,8 @@ 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, 0);
+ status = acpi_ex_system_wait_mutex(
+ acpi_gbl_global_lock_mutex->mutex.os_mutex, 0);
if (status == AE_TIME) {
if (acpi_ev_global_lock_thread_id == acpi_os_get_thread_id()) {
acpi_ev_global_lock_acquired++;
@@ -448,9 +449,9 @@ acpi_status acpi_ev_acquire_global_lock(u16 timeout)
}
if (ACPI_FAILURE(status)) {
- status =
- acpi_ex_system_wait_mutex(acpi_gbl_global_lock_mutex,
- timeout);
+ status = acpi_ex_system_wait_mutex(
+ acpi_gbl_global_lock_mutex->mutex.os_mutex,
+ timeout);
}
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
@@ -555,7 +556,7 @@ acpi_status acpi_ev_release_global_lock(void)
/* 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);
+ acpi_os_release_mutex(acpi_gbl_global_lock_mutex->mutex.os_mutex);
return_ACPI_STATUS(status);
}
diff --git a/drivers/acpi/events/evxface.c b/drivers/acpi/events/evxface.c
index 6d866a01f5f4..dbf34a5fc1e0 100644
--- a/drivers/acpi/events/evxface.c
+++ b/drivers/acpi/events/evxface.c
@@ -758,6 +758,12 @@ ACPI_EXPORT_SYMBOL(acpi_remove_gpe_handler)
*
* DESCRIPTION: Acquire the ACPI Global Lock
*
+ * Note: Allows callers with the same thread ID to acquire the global lock
+ * multiple times. In other words, externally, the behavior of the global lock
+ * is identical to an AML mutex. On the first acquire, a new handle is
+ * returned. On any subsequent calls to acquire by the same thread, the same
+ * handle is returned.
+ *
******************************************************************************/
acpi_status acpi_acquire_global_lock(u16 timeout, u32 * handle)
{
@@ -770,14 +776,26 @@ acpi_status acpi_acquire_global_lock(u16 timeout, u32 * handle)
/* Must lock interpreter to prevent race conditions */
acpi_ex_enter_interpreter();
- status = acpi_ev_acquire_global_lock(timeout);
- acpi_ex_exit_interpreter();
+
+ status = acpi_ex_acquire_mutex_object(timeout,
+ acpi_gbl_global_lock_mutex,
+ acpi_os_get_thread_id());
if (ACPI_SUCCESS(status)) {
- acpi_gbl_global_lock_handle++;
+ /*
+ * If this was the first acquisition of the Global Lock by this thread,
+ * create a new handle. Otherwise, return the existing handle.
+ */
+ if (acpi_gbl_global_lock_mutex->mutex.acquisition_depth == 1) {
+ acpi_gbl_global_lock_handle++;
+ }
+
+ /* Return the global lock handle */
+
*handle = acpi_gbl_global_lock_handle;
}
+ acpi_ex_exit_interpreter();
return (status);
}
@@ -802,7 +820,7 @@ acpi_status acpi_release_global_lock(u32 handle)
return (AE_NOT_ACQUIRED);
}
- status = acpi_ev_release_global_lock();
+ status = acpi_ex_release_mutex_object(acpi_gbl_global_lock_mutex);
return (status);
}