aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
authorBob Moore <robert.moore@intel.com>2007-02-02 11:48:18 -0500
committerLen Brown <len.brown@intel.com>2007-02-02 21:14:20 -0500
commitc81da66608d65dab04730582dfdfcdcab779e2fe (patch)
treee1d2936a457d3ac2b359b4fc676bedfd341fee86 /drivers/acpi
parent8f9337c88335846b01801b1047a4caf10527a320 (diff)
ACPICA: Delete recursive feature of ACPI Global Lock
Completed a new design and implementation for the ACPI Global Lock support. On the OS side, the global lock is now treated as a standard AML mutex. Previously, multiple OS threads could acquire the global lock simultaneously, but this could cause the BIOS to be starved by the lock in cases such as the Embedded Controller driver, where there is a tight coupling between the OS and the BIOS. Signed-off-by: Alexey Starikovskiy <alexey.y.starikovskiy@intel.com> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/events/evmisc.c113
-rw-r--r--drivers/acpi/executer/exmutex.c78
-rw-r--r--drivers/acpi/executer/exsystem.c78
-rw-r--r--drivers/acpi/namespace/nsaccess.c36
-rw-r--r--drivers/acpi/utilities/utdelete.c14
-rw-r--r--drivers/acpi/utilities/utglobal.c2
6 files changed, 131 insertions, 190 deletions
diff --git a/drivers/acpi/events/evmisc.c b/drivers/acpi/events/evmisc.c
index bf63edc6608d..f82b81cc1838 100644
--- a/drivers/acpi/events/evmisc.c
+++ b/drivers/acpi/events/evmisc.c
@@ -298,19 +298,13 @@ static void ACPI_SYSTEM_XFACE acpi_ev_global_lock_thread(void *context)
298{ 298{
299 acpi_status status; 299 acpi_status status;
300 300
301 /* Signal threads that are waiting for the lock */ 301 /* Signal the thread that is waiting for the lock */
302 302
303 if (acpi_gbl_global_lock_thread_count) { 303 /* Send a unit to the semaphore */
304 304
305 /* Send sufficient units to the semaphore */ 305 status = acpi_os_signal_semaphore(acpi_gbl_global_lock_semaphore, 1);
306 306 if (ACPI_FAILURE(status)) {
307 status = 307 ACPI_ERROR((AE_INFO, "Could not signal Global Lock semaphore"));
308 acpi_os_signal_semaphore(acpi_gbl_global_lock_semaphore,
309 acpi_gbl_global_lock_thread_count);
310 if (ACPI_FAILURE(status)) {
311 ACPI_ERROR((AE_INFO,
312 "Could not signal Global Lock semaphore"));
313 }
314 } 308 }
315} 309}
316 310
@@ -333,7 +327,8 @@ static u32 acpi_ev_global_lock_handler(void *context)
333 u8 acquired = FALSE; 327 u8 acquired = FALSE;
334 328
335 /* 329 /*
336 * Attempt to get the lock 330 * Attempt to get the lock.
331 *
337 * If we don't get it now, it will be marked pending and we will 332 * If we don't get it now, it will be marked pending and we will
338 * take another interrupt when it becomes free. 333 * take another interrupt when it becomes free.
339 */ 334 */
@@ -341,6 +336,7 @@ static u32 acpi_ev_global_lock_handler(void *context)
341 if (acquired) { 336 if (acquired) {
342 337
343 /* Got the lock, now wake all threads waiting for it */ 338 /* Got the lock, now wake all threads waiting for it */
339
344 acpi_gbl_global_lock_acquired = TRUE; 340 acpi_gbl_global_lock_acquired = TRUE;
345 acpi_ev_global_lock_thread(context); 341 acpi_ev_global_lock_thread(context);
346 } 342 }
@@ -399,6 +395,16 @@ acpi_status acpi_ev_init_global_lock_handler(void)
399 * 395 *
400 * DESCRIPTION: Attempt to gain ownership of the Global Lock. 396 * DESCRIPTION: Attempt to gain ownership of the Global Lock.
401 * 397 *
398 * MUTEX: Interpreter must be locked
399 *
400 * Note: The original implementation allowed multiple threads to "acquire" the
401 * Global Lock, and the OS would hold the lock until the last thread had
402 * released it. However, this could potentially starve the BIOS out of the
403 * lock, especially in the case where there is a tight handshake between the
404 * Embedded Controller driver and the BIOS. Therefore, this implementation
405 * allows only one thread to acquire the HW Global Lock at a time, and makes
406 * the global lock appear as a standard mutex on the OS side.
407 *
402 *****************************************************************************/ 408 *****************************************************************************/
403 409
404acpi_status acpi_ev_acquire_global_lock(u16 timeout) 410acpi_status acpi_ev_acquire_global_lock(u16 timeout)
@@ -408,27 +414,25 @@ acpi_status acpi_ev_acquire_global_lock(u16 timeout)
408 414
409 ACPI_FUNCTION_TRACE(ev_acquire_global_lock); 415 ACPI_FUNCTION_TRACE(ev_acquire_global_lock);
410 416
411#ifndef ACPI_APPLICATION 417 /*
412 /* Make sure that we actually have a global lock */ 418 * Only one thread can acquire the GL at a time, the global_lock_mutex
413 419 * enforces this. This interface releases the interpreter if we must wait.
414 if (!acpi_gbl_global_lock_present) { 420 */
415 return_ACPI_STATUS(AE_NO_GLOBAL_LOCK); 421 status = acpi_ex_system_wait_mutex(acpi_gbl_global_lock_mutex, timeout);
422 if (ACPI_FAILURE(status)) {
423 return_ACPI_STATUS(status);
416 } 424 }
417#endif
418
419 /* One more thread wants the global lock */
420
421 acpi_gbl_global_lock_thread_count++;
422 425
423 /* 426 /*
424 * If we (OS side vs. BIOS side) have the hardware lock already, 427 * Make sure that a global lock actually exists. If not, just treat
425 * we are done 428 * the lock as a standard mutex.
426 */ 429 */
427 if (acpi_gbl_global_lock_acquired) { 430 if (!acpi_gbl_global_lock_present) {
431 acpi_gbl_global_lock_acquired = TRUE;
428 return_ACPI_STATUS(AE_OK); 432 return_ACPI_STATUS(AE_OK);
429 } 433 }
430 434
431 /* We must acquire the actual hardware lock */ 435 /* Attempt to acquire the actual hardware lock */
432 436
433 ACPI_ACQUIRE_GLOBAL_LOCK(acpi_gbl_common_fACS.global_lock, acquired); 437 ACPI_ACQUIRE_GLOBAL_LOCK(acpi_gbl_common_fACS.global_lock, acquired);
434 if (acquired) { 438 if (acquired) {
@@ -436,25 +440,24 @@ acpi_status acpi_ev_acquire_global_lock(u16 timeout)
436 /* We got the lock */ 440 /* We got the lock */
437 441
438 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, 442 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
439 "Acquired the HW Global Lock\n")); 443 "Acquired hardware Global Lock\n"));
440 444
441 acpi_gbl_global_lock_acquired = TRUE; 445 acpi_gbl_global_lock_acquired = TRUE;
442 return_ACPI_STATUS(AE_OK); 446 return_ACPI_STATUS(AE_OK);
443 } 447 }
444 448
445 /* 449 /*
446 * Did not get the lock. The pending bit was set above, and we must now 450 * Did not get the lock. The pending bit was set above, and we must now
447 * wait until we get the global lock released interrupt. 451 * wait until we get the global lock released interrupt.
448 */ 452 */
449 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Waiting for the HW Global Lock\n")); 453 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Waiting for hardware Global Lock\n"));
450 454
451 /* 455 /*
452 * Acquire the global lock semaphore first. 456 * Wait for handshake with the global lock interrupt handler.
453 * Since this wait will block, we must release the interpreter 457 * This interface releases the interpreter if we must wait.
454 */ 458 */
455 status = 459 status = acpi_ex_system_wait_semaphore(acpi_gbl_global_lock_semaphore,
456 acpi_ex_system_wait_semaphore(acpi_gbl_global_lock_semaphore, 460 ACPI_WAIT_FOREVER);
457 timeout);
458 return_ACPI_STATUS(status); 461 return_ACPI_STATUS(status);
459} 462}
460 463
@@ -477,38 +480,40 @@ acpi_status acpi_ev_release_global_lock(void)
477 480
478 ACPI_FUNCTION_TRACE(ev_release_global_lock); 481 ACPI_FUNCTION_TRACE(ev_release_global_lock);
479 482
480 if (!acpi_gbl_global_lock_thread_count) { 483 /* Lock must be acquired */
484
485 if (!acpi_gbl_global_lock_acquired) {
481 ACPI_WARNING((AE_INFO, 486 ACPI_WARNING((AE_INFO,
482 "Cannot release HW Global Lock, it has not been acquired")); 487 "Cannot release the ACPI Global Lock, it has not been acquired"));
483 return_ACPI_STATUS(AE_NOT_ACQUIRED); 488 return_ACPI_STATUS(AE_NOT_ACQUIRED);
484 } 489 }
485 490
486 /* One fewer thread has the global lock */ 491 if (acpi_gbl_global_lock_present) {
487 492
488 acpi_gbl_global_lock_thread_count--; 493 /* Allow any thread to release the lock */
489 if (acpi_gbl_global_lock_thread_count) {
490 494
491 /* There are still some threads holding the lock, cannot release */ 495 ACPI_RELEASE_GLOBAL_LOCK(acpi_gbl_common_fACS.global_lock,
496 pending);
492 497
493 return_ACPI_STATUS(AE_OK); 498 /*
499 * If the pending bit was set, we must write GBL_RLS to the control
500 * register
501 */
502 if (pending) {
503 status =
504 acpi_set_register(ACPI_BITREG_GLOBAL_LOCK_RELEASE,
505 1, ACPI_MTX_LOCK);
506 }
507
508 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
509 "Released hardware Global Lock\n"));
494 } 510 }
495 511
496 /*
497 * No more threads holding lock, we can do the actual hardware
498 * release
499 */
500 ACPI_RELEASE_GLOBAL_LOCK(acpi_gbl_common_fACS.global_lock, pending);
501 acpi_gbl_global_lock_acquired = FALSE; 512 acpi_gbl_global_lock_acquired = FALSE;
502 513
503 /* 514 /* Release the local GL mutex */
504 * If the pending bit was set, we must write GBL_RLS to the control
505 * register
506 */
507 if (pending) {
508 status = acpi_set_register(ACPI_BITREG_GLOBAL_LOCK_RELEASE,
509 1, ACPI_MTX_LOCK);
510 }
511 515
516 acpi_os_release_mutex(acpi_gbl_global_lock_mutex);
512 return_ACPI_STATUS(status); 517 return_ACPI_STATUS(status);
513} 518}
514 519
diff --git a/drivers/acpi/executer/exmutex.c b/drivers/acpi/executer/exmutex.c
index bf90f04f2c60..f1dd1b07d482 100644
--- a/drivers/acpi/executer/exmutex.c
+++ b/drivers/acpi/executer/exmutex.c
@@ -44,6 +44,7 @@
44 44
45#include <acpi/acpi.h> 45#include <acpi/acpi.h>
46#include <acpi/acinterp.h> 46#include <acpi/acinterp.h>
47#include <acpi/acevents.h>
47 48
48#define _COMPONENT ACPI_EXECUTER 49#define _COMPONENT ACPI_EXECUTER
49ACPI_MODULE_NAME("exmutex") 50ACPI_MODULE_NAME("exmutex")
@@ -150,7 +151,7 @@ acpi_ex_acquire_mutex(union acpi_operand_object *time_desc,
150 return_ACPI_STATUS(AE_BAD_PARAMETER); 151 return_ACPI_STATUS(AE_BAD_PARAMETER);
151 } 152 }
152 153
153 /* Sanity check -- we must have a valid thread ID */ 154 /* Sanity check: we must have a valid thread ID */
154 155
155 if (!walk_state->thread) { 156 if (!walk_state->thread) {
156 ACPI_ERROR((AE_INFO, 157 ACPI_ERROR((AE_INFO,
@@ -174,24 +175,28 @@ acpi_ex_acquire_mutex(union acpi_operand_object *time_desc,
174 /* Support for multiple acquires by the owning thread */ 175 /* Support for multiple acquires by the owning thread */
175 176
176 if (obj_desc->mutex.owner_thread) { 177 if (obj_desc->mutex.owner_thread) {
177 178 if (obj_desc->mutex.owner_thread->thread_id ==
178 /* Special case for Global Lock, allow all threads */ 179 walk_state->thread->thread_id) {
179
180 if ((obj_desc->mutex.owner_thread->thread_id ==
181 walk_state->thread->thread_id) ||
182 (obj_desc->mutex.os_mutex == ACPI_GLOBAL_LOCK)) {
183 /* 180 /*
184 * The mutex is already owned by this thread, 181 * The mutex is already owned by this thread, just increment the
185 * just increment the acquisition depth 182 * acquisition depth
186 */ 183 */
187 obj_desc->mutex.acquisition_depth++; 184 obj_desc->mutex.acquisition_depth++;
188 return_ACPI_STATUS(AE_OK); 185 return_ACPI_STATUS(AE_OK);
189 } 186 }
190 } 187 }
191 188
192 /* Acquire the mutex, wait if necessary */ 189 /* Acquire the mutex, wait if necessary. Special case for Global Lock */
190
191 if (obj_desc->mutex.os_mutex == acpi_gbl_global_lock_mutex) {
192 status =
193 acpi_ev_acquire_global_lock((u16) time_desc->integer.value);
194 } else {
195 status = acpi_ex_system_wait_mutex(obj_desc->mutex.os_mutex,
196 (u16) time_desc->integer.
197 value);
198 }
193 199
194 status = acpi_ex_system_acquire_mutex(time_desc, obj_desc);
195 if (ACPI_FAILURE(status)) { 200 if (ACPI_FAILURE(status)) {
196 201
197 /* Includes failure from a timeout on time_desc */ 202 /* Includes failure from a timeout on time_desc */
@@ -211,7 +216,6 @@ acpi_ex_acquire_mutex(union acpi_operand_object *time_desc,
211 /* Link the mutex to the current thread for force-unlock at method exit */ 216 /* Link the mutex to the current thread for force-unlock at method exit */
212 217
213 acpi_ex_link_mutex(obj_desc, walk_state->thread); 218 acpi_ex_link_mutex(obj_desc, walk_state->thread);
214
215 return_ACPI_STATUS(AE_OK); 219 return_ACPI_STATUS(AE_OK);
216} 220}
217 221
@@ -232,7 +236,7 @@ acpi_status
232acpi_ex_release_mutex(union acpi_operand_object *obj_desc, 236acpi_ex_release_mutex(union acpi_operand_object *obj_desc,
233 struct acpi_walk_state *walk_state) 237 struct acpi_walk_state *walk_state)
234{ 238{
235 acpi_status status; 239 acpi_status status = AE_OK;
236 240
237 ACPI_FUNCTION_TRACE(ex_release_mutex); 241 ACPI_FUNCTION_TRACE(ex_release_mutex);
238 242
@@ -249,7 +253,7 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc,
249 return_ACPI_STATUS(AE_AML_MUTEX_NOT_ACQUIRED); 253 return_ACPI_STATUS(AE_AML_MUTEX_NOT_ACQUIRED);
250 } 254 }
251 255
252 /* Sanity check -- we must have a valid thread ID */ 256 /* Sanity check: we must have a valid thread ID */
253 257
254 if (!walk_state->thread) { 258 if (!walk_state->thread) {
255 ACPI_ERROR((AE_INFO, 259 ACPI_ERROR((AE_INFO,
@@ -264,7 +268,7 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc,
264 */ 268 */
265 if ((obj_desc->mutex.owner_thread->thread_id != 269 if ((obj_desc->mutex.owner_thread->thread_id !=
266 walk_state->thread->thread_id) 270 walk_state->thread->thread_id)
267 && (obj_desc->mutex.os_mutex != ACPI_GLOBAL_LOCK)) { 271 && (obj_desc->mutex.os_mutex != acpi_gbl_global_lock_mutex)) {
268 ACPI_ERROR((AE_INFO, 272 ACPI_ERROR((AE_INFO,
269 "Thread %lX cannot release Mutex [%4.4s] acquired by thread %lX", 273 "Thread %lX cannot release Mutex [%4.4s] acquired by thread %lX",
270 (unsigned long)walk_state->thread->thread_id, 274 (unsigned long)walk_state->thread->thread_id,
@@ -274,8 +278,8 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc,
274 } 278 }
275 279
276 /* 280 /*
277 * The sync level of the mutex must be less than or 281 * The sync level of the mutex must be less than or equal to the current
278 * equal to the current sync level 282 * sync level
279 */ 283 */
280 if (obj_desc->mutex.sync_level > walk_state->thread->current_sync_level) { 284 if (obj_desc->mutex.sync_level > walk_state->thread->current_sync_level) {
281 ACPI_ERROR((AE_INFO, 285 ACPI_ERROR((AE_INFO,
@@ -298,11 +302,15 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc,
298 302
299 acpi_ex_unlink_mutex(obj_desc); 303 acpi_ex_unlink_mutex(obj_desc);
300 304
301 /* Release the mutex */ 305 /* Release the mutex, special case for Global Lock */
302 306
303 status = acpi_ex_system_release_mutex(obj_desc); 307 if (obj_desc->mutex.os_mutex == acpi_gbl_global_lock_mutex) {
308 status = acpi_ev_release_global_lock();
309 } else {
310 acpi_os_release_mutex(obj_desc->mutex.os_mutex);
311 }
304 312
305 /* Update the mutex and walk state, restore sync_level before acquire */ 313 /* Update the mutex and restore sync_level */
306 314
307 obj_desc->mutex.owner_thread = NULL; 315 obj_desc->mutex.owner_thread = NULL;
308 walk_state->thread->current_sync_level = 316 walk_state->thread->current_sync_level =
@@ -326,34 +334,38 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc,
326void acpi_ex_release_all_mutexes(struct acpi_thread_state *thread) 334void acpi_ex_release_all_mutexes(struct acpi_thread_state *thread)
327{ 335{
328 union acpi_operand_object *next = thread->acquired_mutex_list; 336 union acpi_operand_object *next = thread->acquired_mutex_list;
329 union acpi_operand_object *this; 337 union acpi_operand_object *obj_desc;
330 acpi_status status;
331 338
332 ACPI_FUNCTION_ENTRY(); 339 ACPI_FUNCTION_ENTRY();
333 340
334 /* Traverse the list of owned mutexes, releasing each one */ 341 /* Traverse the list of owned mutexes, releasing each one */
335 342
336 while (next) { 343 while (next) {
337 this = next; 344 obj_desc = next;
338 next = this->mutex.next; 345 next = obj_desc->mutex.next;
346
347 obj_desc->mutex.prev = NULL;
348 obj_desc->mutex.next = NULL;
349 obj_desc->mutex.acquisition_depth = 1;
350
351 /* Release the mutex, special case for Global Lock */
339 352
340 this->mutex.acquisition_depth = 1; 353 if (obj_desc->mutex.os_mutex == acpi_gbl_global_lock_mutex) {
341 this->mutex.prev = NULL;
342 this->mutex.next = NULL;
343 354
344 /* Release the mutex */ 355 /* Ignore errors */
345 356
346 status = acpi_ex_system_release_mutex(this); 357 (void)acpi_ev_release_global_lock();
347 if (ACPI_FAILURE(status)) { 358 } else {
348 continue; 359 acpi_os_release_mutex(obj_desc->mutex.os_mutex);
349 } 360 }
350 361
351 /* Mark mutex unowned */ 362 /* Mark mutex unowned */
352 363
353 this->mutex.owner_thread = NULL; 364 obj_desc->mutex.owner_thread = NULL;
354 365
355 /* Update Thread sync_level (Last mutex is the important one) */ 366 /* Update Thread sync_level (Last mutex is the important one) */
356 367
357 thread->current_sync_level = this->mutex.original_sync_level; 368 thread->current_sync_level =
369 obj_desc->mutex.original_sync_level;
358 } 370 }
359} 371}
diff --git a/drivers/acpi/executer/exsystem.c b/drivers/acpi/executer/exsystem.c
index 28aef3e69ecc..3b9736a3e1b7 100644
--- a/drivers/acpi/executer/exsystem.c
+++ b/drivers/acpi/executer/exsystem.c
@@ -227,82 +227,6 @@ acpi_status acpi_ex_system_do_suspend(acpi_integer how_long)
227 227
228/******************************************************************************* 228/*******************************************************************************
229 * 229 *
230 * FUNCTION: acpi_ex_system_acquire_mutex
231 *
232 * PARAMETERS: time_desc - Maximum time to wait for the mutex
233 * obj_desc - The object descriptor for this op
234 *
235 * RETURN: Status
236 *
237 * DESCRIPTION: Provides an access point to perform synchronization operations
238 * within the AML. This function will cause a lock to be generated
239 * for the Mutex pointed to by obj_desc.
240 *
241 ******************************************************************************/
242
243acpi_status
244acpi_ex_system_acquire_mutex(union acpi_operand_object * time_desc,
245 union acpi_operand_object * obj_desc)
246{
247 acpi_status status = AE_OK;
248
249 ACPI_FUNCTION_TRACE_PTR(ex_system_acquire_mutex, obj_desc);
250
251 if (!obj_desc) {
252 return_ACPI_STATUS(AE_BAD_PARAMETER);
253 }
254
255 /* Support for the _GL_ Mutex object -- go get the global lock */
256
257 if (obj_desc->mutex.os_mutex == ACPI_GLOBAL_LOCK) {
258 status =
259 acpi_ev_acquire_global_lock((u16) time_desc->integer.value);
260 return_ACPI_STATUS(status);
261 }
262
263 status = acpi_ex_system_wait_mutex(obj_desc->mutex.os_mutex,
264 (u16) time_desc->integer.value);
265 return_ACPI_STATUS(status);
266}
267
268/*******************************************************************************
269 *
270 * FUNCTION: acpi_ex_system_release_mutex
271 *
272 * PARAMETERS: obj_desc - The object descriptor for this op
273 *
274 * RETURN: Status
275 *
276 * DESCRIPTION: Provides an access point to perform synchronization operations
277 * within the AML. This operation is a request to release a
278 * previously acquired Mutex. If the Mutex variable is set then
279 * it will be decremented.
280 *
281 ******************************************************************************/
282
283acpi_status acpi_ex_system_release_mutex(union acpi_operand_object *obj_desc)
284{
285 acpi_status status = AE_OK;
286
287 ACPI_FUNCTION_TRACE(ex_system_release_mutex);
288
289 if (!obj_desc) {
290 return_ACPI_STATUS(AE_BAD_PARAMETER);
291 }
292
293 /* Support for the _GL_ Mutex object -- release the global lock */
294
295 if (obj_desc->mutex.os_mutex == ACPI_GLOBAL_LOCK) {
296 status = acpi_ev_release_global_lock();
297 return_ACPI_STATUS(status);
298 }
299
300 acpi_os_release_mutex(obj_desc->mutex.os_mutex);
301 return_ACPI_STATUS(AE_OK);
302}
303
304/*******************************************************************************
305 *
306 * FUNCTION: acpi_ex_system_signal_event 230 * FUNCTION: acpi_ex_system_signal_event
307 * 231 *
308 * PARAMETERS: obj_desc - The object descriptor for this op 232 * PARAMETERS: obj_desc - The object descriptor for this op
@@ -314,7 +238,7 @@ acpi_status acpi_ex_system_release_mutex(union acpi_operand_object *obj_desc)
314 * 238 *
315 ******************************************************************************/ 239 ******************************************************************************/
316 240
317acpi_status acpi_ex_system_signal_event(union acpi_operand_object *obj_desc) 241acpi_status acpi_ex_system_signal_event(union acpi_operand_object * obj_desc)
318{ 242{
319 acpi_status status = AE_OK; 243 acpi_status status = AE_OK;
320 244
diff --git a/drivers/acpi/namespace/nsaccess.c b/drivers/acpi/namespace/nsaccess.c
index c1c6c236df9a..b2ef6730be81 100644
--- a/drivers/acpi/namespace/nsaccess.c
+++ b/drivers/acpi/namespace/nsaccess.c
@@ -195,31 +195,27 @@ acpi_status acpi_ns_root_initialize(void)
195 obj_desc->mutex.sync_level = 195 obj_desc->mutex.sync_level =
196 (u8) (ACPI_TO_INTEGER(val) - 1); 196 (u8) (ACPI_TO_INTEGER(val) - 1);
197 197
198 if (ACPI_STRCMP(init_val->name, "_GL_") == 0) { 198 /* Create a mutex */
199 199
200 /* Create a counting semaphore for the global lock */ 200 status =
201 acpi_os_create_mutex(&obj_desc->mutex.
202 os_mutex);
203 if (ACPI_FAILURE(status)) {
204 acpi_ut_remove_reference(obj_desc);
205 goto unlock_and_exit;
206 }
201 207
202 status = 208 /* Special case for ACPI Global Lock */
203 acpi_os_create_semaphore
204 (ACPI_NO_UNIT_LIMIT, 1,
205 &acpi_gbl_global_lock_semaphore);
206 if (ACPI_FAILURE(status)) {
207 acpi_ut_remove_reference
208 (obj_desc);
209 goto unlock_and_exit;
210 }
211 209
212 /* Mark this mutex as very special */ 210 if (ACPI_STRCMP(init_val->name, "_GL_") == 0) {
211 acpi_gbl_global_lock_mutex =
212 obj_desc->mutex.os_mutex;
213 213
214 obj_desc->mutex.os_mutex = 214 /* Create additional counting semaphore for global lock */
215 ACPI_GLOBAL_LOCK;
216 } else {
217 /* Create a mutex */
218 215
219 status = 216 status =
220 acpi_os_create_mutex(&obj_desc-> 217 acpi_os_create_semaphore(1, 1,
221 mutex. 218 &acpi_gbl_global_lock_semaphore);
222 os_mutex);
223 if (ACPI_FAILURE(status)) { 219 if (ACPI_FAILURE(status)) {
224 acpi_ut_remove_reference 220 acpi_ut_remove_reference
225 (obj_desc); 221 (obj_desc);
diff --git a/drivers/acpi/utilities/utdelete.c b/drivers/acpi/utilities/utdelete.c
index 9d3f1149ba21..af8e65f17fb7 100644
--- a/drivers/acpi/utilities/utdelete.c
+++ b/drivers/acpi/utilities/utdelete.c
@@ -158,16 +158,20 @@ static void acpi_ut_delete_internal_obj(union acpi_operand_object *object)
158 "***** Mutex %p, OS Mutex %p\n", 158 "***** Mutex %p, OS Mutex %p\n",
159 object, object->mutex.os_mutex)); 159 object, object->mutex.os_mutex));
160 160
161 if (object->mutex.os_mutex != ACPI_GLOBAL_LOCK) { 161 if (object->mutex.os_mutex == acpi_gbl_global_lock_mutex) {
162 acpi_ex_unlink_mutex(object); 162
163 acpi_os_delete_mutex(object->mutex.os_mutex); 163 /* Global Lock has extra semaphore */
164 } else {
165 /* Global Lock "mutex" is actually a counting semaphore */
166 164
167 (void) 165 (void)
168 acpi_os_delete_semaphore 166 acpi_os_delete_semaphore
169 (acpi_gbl_global_lock_semaphore); 167 (acpi_gbl_global_lock_semaphore);
170 acpi_gbl_global_lock_semaphore = NULL; 168 acpi_gbl_global_lock_semaphore = NULL;
169
170 acpi_os_delete_mutex(object->mutex.os_mutex);
171 acpi_gbl_global_lock_mutex = NULL;
172 } else {
173 acpi_ex_unlink_mutex(object);
174 acpi_os_delete_mutex(object->mutex.os_mutex);
171 } 175 }
172 break; 176 break;
173 177
diff --git a/drivers/acpi/utilities/utglobal.c b/drivers/acpi/utilities/utglobal.c
index 014030af8b50..103845213e22 100644
--- a/drivers/acpi/utilities/utglobal.c
+++ b/drivers/acpi/utilities/utglobal.c
@@ -795,8 +795,8 @@ void acpi_ut_init_globals(void)
795 /* Global Lock support */ 795 /* Global Lock support */
796 796
797 acpi_gbl_global_lock_semaphore = NULL; 797 acpi_gbl_global_lock_semaphore = NULL;
798 acpi_gbl_global_lock_mutex = NULL;
798 acpi_gbl_global_lock_acquired = FALSE; 799 acpi_gbl_global_lock_acquired = FALSE;
799 acpi_gbl_global_lock_thread_count = 0;
800 acpi_gbl_global_lock_handle = 0; 800 acpi_gbl_global_lock_handle = 0;
801 801
802 /* Miscellaneous variables */ 802 /* Miscellaneous variables */