diff options
Diffstat (limited to 'drivers/acpi/events/evmisc.c')
-rw-r--r-- | drivers/acpi/events/evmisc.c | 33 |
1 files changed, 29 insertions, 4 deletions
diff --git a/drivers/acpi/events/evmisc.c b/drivers/acpi/events/evmisc.c index d572700197f3..cae786ca8600 100644 --- a/drivers/acpi/events/evmisc.c +++ b/drivers/acpi/events/evmisc.c | |||
@@ -196,11 +196,15 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node * node, | |||
196 | notify_info->notify.value = (u16) notify_value; | 196 | notify_info->notify.value = (u16) notify_value; |
197 | notify_info->notify.handler_obj = handler_obj; | 197 | notify_info->notify.handler_obj = handler_obj; |
198 | 198 | ||
199 | acpi_ex_relinquish_interpreter(); | 199 | acpi_ex_exit_interpreter(); |
200 | 200 | ||
201 | acpi_ev_notify_dispatch(notify_info); | 201 | acpi_ev_notify_dispatch(notify_info); |
202 | 202 | ||
203 | acpi_ex_reacquire_interpreter(); | 203 | status = acpi_ex_enter_interpreter(); |
204 | if (ACPI_FAILURE(status)) { | ||
205 | return_ACPI_STATUS(status); | ||
206 | } | ||
207 | |||
204 | } | 208 | } |
205 | 209 | ||
206 | if (!handler_obj) { | 210 | if (!handler_obj) { |
@@ -423,6 +427,8 @@ static acpi_status acpi_ev_remove_global_lock_handler(void) | |||
423 | * the global lock appear as a standard mutex on the OS side. | 427 | * the global lock appear as a standard mutex on the OS side. |
424 | * | 428 | * |
425 | *****************************************************************************/ | 429 | *****************************************************************************/ |
430 | static acpi_thread_id acpi_ev_global_lock_thread_id; | ||
431 | static int acpi_ev_global_lock_acquired; | ||
426 | 432 | ||
427 | acpi_status acpi_ev_acquire_global_lock(u16 timeout) | 433 | acpi_status acpi_ev_acquire_global_lock(u16 timeout) |
428 | { | 434 | { |
@@ -435,11 +441,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 | 441 | * 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. | 442 | * enforces this. This interface releases the interpreter if we must wait. |
437 | */ | 443 | */ |
438 | status = acpi_ex_system_wait_mutex(acpi_gbl_global_lock_mutex, timeout); | 444 | status = acpi_ex_system_wait_mutex(acpi_gbl_global_lock_mutex, 0); |
445 | if (status == AE_TIME) { | ||
446 | if (acpi_ev_global_lock_thread_id == acpi_os_get_thread_id()) { | ||
447 | acpi_ev_global_lock_acquired++; | ||
448 | return AE_OK; | ||
449 | } | ||
450 | } | ||
451 | |||
452 | if (ACPI_FAILURE(status)) { | ||
453 | status = acpi_ex_system_wait_mutex(acpi_gbl_global_lock_mutex, timeout); | ||
454 | } | ||
439 | if (ACPI_FAILURE(status)) { | 455 | if (ACPI_FAILURE(status)) { |
440 | return_ACPI_STATUS(status); | 456 | return_ACPI_STATUS(status); |
441 | } | 457 | } |
442 | 458 | ||
459 | acpi_ev_global_lock_thread_id = acpi_os_get_thread_id(); | ||
460 | acpi_ev_global_lock_acquired++; | ||
461 | |||
443 | /* | 462 | /* |
444 | * Make sure that a global lock actually exists. If not, just treat | 463 | * Make sure that a global lock actually exists. If not, just treat |
445 | * the lock as a standard mutex. | 464 | * the lock as a standard mutex. |
@@ -506,6 +525,11 @@ acpi_status acpi_ev_release_global_lock(void) | |||
506 | return_ACPI_STATUS(AE_NOT_ACQUIRED); | 525 | return_ACPI_STATUS(AE_NOT_ACQUIRED); |
507 | } | 526 | } |
508 | 527 | ||
528 | acpi_ev_global_lock_acquired--; | ||
529 | if (acpi_ev_global_lock_acquired > 0) { | ||
530 | return AE_OK; | ||
531 | } | ||
532 | |||
509 | if (acpi_gbl_global_lock_present) { | 533 | if (acpi_gbl_global_lock_present) { |
510 | 534 | ||
511 | /* Allow any thread to release the lock */ | 535 | /* Allow any thread to release the lock */ |
@@ -529,7 +553,8 @@ acpi_status acpi_ev_release_global_lock(void) | |||
529 | acpi_gbl_global_lock_acquired = FALSE; | 553 | acpi_gbl_global_lock_acquired = FALSE; |
530 | 554 | ||
531 | /* Release the local GL mutex */ | 555 | /* Release the local GL mutex */ |
532 | 556 | acpi_ev_global_lock_thread_id = NULL; | |
557 | acpi_ev_global_lock_acquired = 0; | ||
533 | acpi_os_release_mutex(acpi_gbl_global_lock_mutex); | 558 | acpi_os_release_mutex(acpi_gbl_global_lock_mutex); |
534 | return_ACPI_STATUS(status); | 559 | return_ACPI_STATUS(status); |
535 | } | 560 | } |