aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/events
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/events')
-rw-r--r--drivers/acpi/events/evmisc.c113
1 files changed, 59 insertions, 54 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