diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/acpi/events/evmisc.c | 25 |
1 files changed, 23 insertions, 2 deletions
diff --git a/drivers/acpi/events/evmisc.c b/drivers/acpi/events/evmisc.c index d572700197f3..8dcade63b04b 100644 --- a/drivers/acpi/events/evmisc.c +++ b/drivers/acpi/events/evmisc.c | |||
@@ -423,6 +423,8 @@ static acpi_status acpi_ev_remove_global_lock_handler(void) | |||
423 | * the global lock appear as a standard mutex on the OS side. | 423 | * the global lock appear as a standard mutex on the OS side. |
424 | * | 424 | * |
425 | *****************************************************************************/ | 425 | *****************************************************************************/ |
426 | static acpi_thread_id acpi_ev_global_lock_thread_id; | ||
427 | static int acpi_ev_global_lock_acquired; | ||
426 | 428 | ||
427 | acpi_status acpi_ev_acquire_global_lock(u16 timeout) | 429 | acpi_status acpi_ev_acquire_global_lock(u16 timeout) |
428 | { | 430 | { |
@@ -435,11 +437,24 @@ acpi_status acpi_ev_acquire_global_lock(u16 timeout) | |||
435 | * Only one thread can acquire the GL at a time, the global_lock_mutex | 437 | * Only one thread can acquire the GL at a time, the global_lock_mutex |
436 | * enforces this. This interface releases the interpreter if we must wait. | 438 | * enforces this. This interface releases the interpreter if we must wait. |
437 | */ | 439 | */ |
438 | status = acpi_ex_system_wait_mutex(acpi_gbl_global_lock_mutex, timeout); | 440 | status = acpi_ex_system_wait_mutex(acpi_gbl_global_lock_mutex, 0); |
441 | if (status == AE_TIME) { | ||
442 | if (acpi_ev_global_lock_thread_id == acpi_os_get_thread_id()) { | ||
443 | acpi_ev_global_lock_acquired++; | ||
444 | return AE_OK; | ||
445 | } | ||
446 | } | ||
447 | |||
448 | if (ACPI_FAILURE(status)) { | ||
449 | status = acpi_ex_system_wait_mutex(acpi_gbl_global_lock_mutex, timeout); | ||
450 | } | ||
439 | if (ACPI_FAILURE(status)) { | 451 | if (ACPI_FAILURE(status)) { |
440 | return_ACPI_STATUS(status); | 452 | return_ACPI_STATUS(status); |
441 | } | 453 | } |
442 | 454 | ||
455 | acpi_ev_global_lock_thread_id = acpi_os_get_thread_id(); | ||
456 | acpi_ev_global_lock_acquired++; | ||
457 | |||
443 | /* | 458 | /* |
444 | * Make sure that a global lock actually exists. If not, just treat | 459 | * Make sure that a global lock actually exists. If not, just treat |
445 | * the lock as a standard mutex. | 460 | * the lock as a standard mutex. |
@@ -506,6 +521,11 @@ acpi_status acpi_ev_release_global_lock(void) | |||
506 | return_ACPI_STATUS(AE_NOT_ACQUIRED); | 521 | return_ACPI_STATUS(AE_NOT_ACQUIRED); |
507 | } | 522 | } |
508 | 523 | ||
524 | acpi_ev_global_lock_acquired--; | ||
525 | if (acpi_ev_global_lock_acquired > 0) { | ||
526 | return AE_OK; | ||
527 | } | ||
528 | |||
509 | if (acpi_gbl_global_lock_present) { | 529 | if (acpi_gbl_global_lock_present) { |
510 | 530 | ||
511 | /* Allow any thread to release the lock */ | 531 | /* Allow any thread to release the lock */ |
@@ -529,7 +549,8 @@ acpi_status acpi_ev_release_global_lock(void) | |||
529 | acpi_gbl_global_lock_acquired = FALSE; | 549 | acpi_gbl_global_lock_acquired = FALSE; |
530 | 550 | ||
531 | /* Release the local GL mutex */ | 551 | /* Release the local GL mutex */ |
532 | 552 | acpi_ev_global_lock_thread_id = 0; | |
553 | acpi_ev_global_lock_acquired = 0; | ||
533 | acpi_os_release_mutex(acpi_gbl_global_lock_mutex); | 554 | acpi_os_release_mutex(acpi_gbl_global_lock_mutex); |
534 | return_ACPI_STATUS(status); | 555 | return_ACPI_STATUS(status); |
535 | } | 556 | } |