*****************************************************************************/
/*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
static u32 acpi_ev_global_lock_handler(void *context);
+static acpi_status acpi_ev_remove_global_lock_handler(void);
+
/*******************************************************************************
*
* FUNCTION: acpi_ev_is_notify_object
acpi_gbl_global_lock_acquired = TRUE;
/* Send a unit to the semaphore */
- if (ACPI_FAILURE(acpi_os_signal_semaphore(
- acpi_gbl_global_lock_semaphore, 1))) {
+ if (ACPI_FAILURE
+ (acpi_os_signal_semaphore
+ (acpi_gbl_global_lock_semaphore, 1))) {
ACPI_ERROR((AE_INFO,
"Could not signal Global Lock semaphore"));
}
ACPI_FUNCTION_TRACE(ev_init_global_lock_handler);
status =
- acpi_get_table(ACPI_SIG_FACS, 0,
- (struct acpi_table_header **)&facs);
+ acpi_get_table_by_index(ACPI_TABLE_INDEX_FACS,
+ (struct acpi_table_header **)&facs);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
return_ACPI_STATUS(status);
}
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ev_remove_global_lock_handler
+ *
+ * PARAMETERS: None
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Remove the handler for the Global Lock
+ *
+ ******************************************************************************/
+
+static acpi_status acpi_ev_remove_global_lock_handler(void)
+{
+ acpi_status status;
+
+ ACPI_FUNCTION_TRACE(ev_remove_global_lock_handler);
+
+ acpi_gbl_global_lock_present = FALSE;
+ status = acpi_remove_fixed_event_handler(ACPI_EVENT_GLOBAL,
+ acpi_ev_global_lock_handler);
+
+ return_ACPI_STATUS(status);
+}
+
/******************************************************************************
*
* FUNCTION: acpi_ev_acquire_global_lock
* 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)
{
* 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.
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 */
if (pending) {
status =
acpi_set_register(ACPI_BITREG_GLOBAL_LOCK_RELEASE,
- 1, ACPI_MTX_LOCK);
+ 1);
}
ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
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);
}
if (ACPI_FAILURE(status)) {
ACPI_ERROR((AE_INFO, "Could not remove SCI handler"));
}
+
+ status = acpi_ev_remove_global_lock_handler();
+ if (ACPI_FAILURE(status)) {
+ ACPI_ERROR((AE_INFO,
+ "Could not remove Global Lock handler"));
+ }
}
/* Deallocate all handler objects installed within GPE info structs */