diff options
author | Len Brown <len.brown@intel.com> | 2011-01-12 04:55:46 -0500 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2011-01-12 04:55:46 -0500 |
commit | fb4af417cce9ff87abf33a6bb9a0cf613e285364 (patch) | |
tree | 328ce710c6e6acf7b58145da939fb3cc91d188c9 /drivers/acpi/acpica | |
parent | 07bf280521bb06bc8e64f0b998fc391253fcb959 (diff) | |
parent | 7b330707dddab1ad772898c1c82516342a551173 (diff) |
Merge branch 'wakeup-etc-rafael' into release
Diffstat (limited to 'drivers/acpi/acpica')
-rw-r--r-- | drivers/acpi/acpica/evmisc.c | 94 |
1 files changed, 55 insertions, 39 deletions
diff --git a/drivers/acpi/acpica/evmisc.c b/drivers/acpi/acpica/evmisc.c index fcaed9fb44ff..8e31bb5a973a 100644 --- a/drivers/acpi/acpica/evmisc.c +++ b/drivers/acpi/acpica/evmisc.c | |||
@@ -284,41 +284,41 @@ static void ACPI_SYSTEM_XFACE acpi_ev_notify_dispatch(void *context) | |||
284 | * RETURN: ACPI_INTERRUPT_HANDLED | 284 | * RETURN: ACPI_INTERRUPT_HANDLED |
285 | * | 285 | * |
286 | * DESCRIPTION: Invoked directly from the SCI handler when a global lock | 286 | * DESCRIPTION: Invoked directly from the SCI handler when a global lock |
287 | * release interrupt occurs. Attempt to acquire the global lock, | 287 | * release interrupt occurs. If there's a thread waiting for |
288 | * if successful, signal the thread waiting for the lock. | 288 | * the global lock, signal it. |
289 | * | 289 | * |
290 | * NOTE: Assumes that the semaphore can be signaled from interrupt level. If | 290 | * NOTE: Assumes that the semaphore can be signaled from interrupt level. If |
291 | * this is not possible for some reason, a separate thread will have to be | 291 | * this is not possible for some reason, a separate thread will have to be |
292 | * scheduled to do this. | 292 | * scheduled to do this. |
293 | * | 293 | * |
294 | ******************************************************************************/ | 294 | ******************************************************************************/ |
295 | static u8 acpi_ev_global_lock_pending; | ||
296 | static spinlock_t _acpi_ev_global_lock_pending_lock; | ||
297 | #define acpi_ev_global_lock_pending_lock &_acpi_ev_global_lock_pending_lock | ||
295 | 298 | ||
296 | static u32 acpi_ev_global_lock_handler(void *context) | 299 | static u32 acpi_ev_global_lock_handler(void *context) |
297 | { | 300 | { |
298 | u8 acquired = FALSE; | 301 | acpi_status status; |
302 | acpi_cpu_flags flags; | ||
299 | 303 | ||
300 | /* | 304 | flags = acpi_os_acquire_lock(acpi_ev_global_lock_pending_lock); |
301 | * Attempt to get the lock. | ||
302 | * | ||
303 | * If we don't get it now, it will be marked pending and we will | ||
304 | * take another interrupt when it becomes free. | ||
305 | */ | ||
306 | ACPI_ACQUIRE_GLOBAL_LOCK(acpi_gbl_FACS, acquired); | ||
307 | if (acquired) { | ||
308 | 305 | ||
309 | /* Got the lock, now wake all threads waiting for it */ | 306 | if (!acpi_ev_global_lock_pending) { |
307 | goto out; | ||
308 | } | ||
310 | 309 | ||
311 | acpi_gbl_global_lock_acquired = TRUE; | 310 | /* Send a unit to the semaphore */ |
312 | /* Send a unit to the semaphore */ | ||
313 | 311 | ||
314 | if (ACPI_FAILURE | 312 | status = acpi_os_signal_semaphore(acpi_gbl_global_lock_semaphore, 1); |
315 | (acpi_os_signal_semaphore | 313 | if (ACPI_FAILURE(status)) { |
316 | (acpi_gbl_global_lock_semaphore, 1))) { | 314 | ACPI_ERROR((AE_INFO, "Could not signal Global Lock semaphore")); |
317 | ACPI_ERROR((AE_INFO, | ||
318 | "Could not signal Global Lock semaphore")); | ||
319 | } | ||
320 | } | 315 | } |
321 | 316 | ||
317 | acpi_ev_global_lock_pending = FALSE; | ||
318 | |||
319 | out: | ||
320 | acpi_os_release_lock(acpi_ev_global_lock_pending_lock, flags); | ||
321 | |||
322 | return (ACPI_INTERRUPT_HANDLED); | 322 | return (ACPI_INTERRUPT_HANDLED); |
323 | } | 323 | } |
324 | 324 | ||
@@ -415,6 +415,7 @@ static int acpi_ev_global_lock_acquired; | |||
415 | 415 | ||
416 | acpi_status acpi_ev_acquire_global_lock(u16 timeout) | 416 | acpi_status acpi_ev_acquire_global_lock(u16 timeout) |
417 | { | 417 | { |
418 | acpi_cpu_flags flags; | ||
418 | acpi_status status = AE_OK; | 419 | acpi_status status = AE_OK; |
419 | u8 acquired = FALSE; | 420 | u8 acquired = FALSE; |
420 | 421 | ||
@@ -467,32 +468,47 @@ acpi_status acpi_ev_acquire_global_lock(u16 timeout) | |||
467 | return_ACPI_STATUS(AE_OK); | 468 | return_ACPI_STATUS(AE_OK); |
468 | } | 469 | } |
469 | 470 | ||
470 | /* Attempt to acquire the actual hardware lock */ | 471 | flags = acpi_os_acquire_lock(acpi_ev_global_lock_pending_lock); |
472 | |||
473 | do { | ||
474 | |||
475 | /* Attempt to acquire the actual hardware lock */ | ||
476 | |||
477 | ACPI_ACQUIRE_GLOBAL_LOCK(acpi_gbl_FACS, acquired); | ||
478 | if (acquired) { | ||
479 | acpi_gbl_global_lock_acquired = TRUE; | ||
480 | |||
481 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | ||
482 | "Acquired hardware Global Lock\n")); | ||
483 | break; | ||
484 | } | ||
471 | 485 | ||
472 | ACPI_ACQUIRE_GLOBAL_LOCK(acpi_gbl_FACS, acquired); | 486 | acpi_ev_global_lock_pending = TRUE; |
473 | if (acquired) { | ||
474 | 487 | ||
475 | /* We got the lock */ | 488 | acpi_os_release_lock(acpi_ev_global_lock_pending_lock, flags); |
476 | 489 | ||
490 | /* | ||
491 | * Did not get the lock. The pending bit was set above, and we | ||
492 | * must wait until we get the global lock released interrupt. | ||
493 | */ | ||
477 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | 494 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, |
478 | "Acquired hardware Global Lock\n")); | 495 | "Waiting for hardware Global Lock\n")); |
479 | 496 | ||
480 | acpi_gbl_global_lock_acquired = TRUE; | 497 | /* |
481 | return_ACPI_STATUS(AE_OK); | 498 | * Wait for handshake with the global lock interrupt handler. |
482 | } | 499 | * This interface releases the interpreter if we must wait. |
500 | */ | ||
501 | status = acpi_ex_system_wait_semaphore( | ||
502 | acpi_gbl_global_lock_semaphore, | ||
503 | ACPI_WAIT_FOREVER); | ||
483 | 504 | ||
484 | /* | 505 | flags = acpi_os_acquire_lock(acpi_ev_global_lock_pending_lock); |
485 | * Did not get the lock. The pending bit was set above, and we must now | ||
486 | * wait until we get the global lock released interrupt. | ||
487 | */ | ||
488 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Waiting for hardware Global Lock\n")); | ||
489 | 506 | ||
490 | /* | 507 | } while (ACPI_SUCCESS(status)); |
491 | * Wait for handshake with the global lock interrupt handler. | 508 | |
492 | * This interface releases the interpreter if we must wait. | 509 | acpi_ev_global_lock_pending = FALSE; |
493 | */ | 510 | |
494 | status = acpi_ex_system_wait_semaphore(acpi_gbl_global_lock_semaphore, | 511 | acpi_os_release_lock(acpi_ev_global_lock_pending_lock, flags); |
495 | ACPI_WAIT_FOREVER); | ||
496 | 512 | ||
497 | return_ACPI_STATUS(status); | 513 | return_ACPI_STATUS(status); |
498 | } | 514 | } |