aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/acpica/evmisc.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-01-13 23:15:35 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2011-01-13 23:15:35 -0500
commit52cfd503ad7176d23a5dd7af3981744feb60622f (patch)
tree0a8aeaaf4acbc86ac682f18632b8070c1c6b7ba1 /drivers/acpi/acpica/evmisc.c
parentdc8e7e3ec60bd5ef7868aa88755e9d4c948dc5cc (diff)
parent4263d9a3ae4d15785897d0543bb59316c84ee605 (diff)
Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6
* 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6: (59 commits) ACPI / PM: Fix build problems for !CONFIG_ACPI related to NVS rework ACPI: fix resource check message ACPI / Battery: Update information on info notification and resume ACPI: Drop device flag wake_capable ACPI: Always check if _PRW is present before trying to evaluate it ACPI / PM: Check status of power resources under mutexes ACPI / PM: Rename acpi_power_off_device() ACPI / PM: Drop acpi_power_nocheck ACPI / PM: Drop acpi_bus_get_power() Platform / x86: Make fujitsu_laptop use acpi_bus_update_power() ACPI / Fan: Rework the handling of power resources ACPI / PM: Register power resource devices as soon as they are needed ACPI / PM: Register acpi_power_driver early ACPI / PM: Add function for updating device power state consistently ACPI / PM: Add function for device power state initialization ACPI / PM: Introduce __acpi_bus_get_power() ACPI / PM: Introduce function for refcounting device power resources ACPI / PM: Add functions for manipulating lists of power resources ACPI / PM: Prevent acpi_power_get_inferred_state() from making changes ACPICA: Update version to 20101209 ...
Diffstat (limited to 'drivers/acpi/acpica/evmisc.c')
-rw-r--r--drivers/acpi/acpica/evmisc.c94
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 ******************************************************************************/
295static u8 acpi_ev_global_lock_pending;
296static spinlock_t _acpi_ev_global_lock_pending_lock;
297#define acpi_ev_global_lock_pending_lock &_acpi_ev_global_lock_pending_lock
295 298
296static u32 acpi_ev_global_lock_handler(void *context) 299static 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
416acpi_status acpi_ev_acquire_global_lock(u16 timeout) 416acpi_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}