^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Module Name: evglock - Global Lock support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2000 - 2020, Intel Corp.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <acpi/acpi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include "accommon.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include "acevents.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include "acinterp.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #define _COMPONENT ACPI_EVENTS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) ACPI_MODULE_NAME("evglock")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #if (!ACPI_REDUCED_HARDWARE) /* Entire module */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) /* Local prototypes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) static u32 acpi_ev_global_lock_handler(void *context);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) /*******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * FUNCTION: acpi_ev_init_global_lock_handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * PARAMETERS: None
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * RETURN: Status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * DESCRIPTION: Install a handler for the global lock release event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) acpi_status acpi_ev_init_global_lock_handler(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) ACPI_FUNCTION_TRACE(ev_init_global_lock_handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) /* If Hardware Reduced flag is set, there is no global lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) if (acpi_gbl_reduced_hardware) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) return_ACPI_STATUS(AE_OK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) /* Attempt installation of the global lock handler */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) status = acpi_install_fixed_event_handler(ACPI_EVENT_GLOBAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) acpi_ev_global_lock_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * If the global lock does not exist on this platform, the attempt to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * enable GBL_STATUS will fail (the GBL_ENABLE bit will not stick).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) * Map to AE_OK, but mark global lock as not present. Any attempt to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) * actually use the global lock will be flagged with an error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) acpi_gbl_global_lock_present = FALSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) if (status == AE_NO_HARDWARE_RESPONSE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) ACPI_ERROR((AE_INFO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) "No response from Global Lock hardware, disabling lock"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) return_ACPI_STATUS(AE_OK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) status = acpi_os_create_lock(&acpi_gbl_global_lock_pending_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) if (ACPI_FAILURE(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) return_ACPI_STATUS(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) acpi_gbl_global_lock_pending = FALSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) acpi_gbl_global_lock_present = TRUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) return_ACPI_STATUS(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) /*******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) * FUNCTION: acpi_ev_remove_global_lock_handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) * PARAMETERS: None
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * RETURN: Status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) * DESCRIPTION: Remove the handler for the Global Lock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) acpi_status acpi_ev_remove_global_lock_handler(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) ACPI_FUNCTION_TRACE(ev_remove_global_lock_handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) acpi_gbl_global_lock_present = FALSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) status = acpi_remove_fixed_event_handler(ACPI_EVENT_GLOBAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) acpi_ev_global_lock_handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) acpi_os_delete_lock(acpi_gbl_global_lock_pending_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) return_ACPI_STATUS(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) /*******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) * FUNCTION: acpi_ev_global_lock_handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) * PARAMETERS: context - From thread interface, not used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) * RETURN: ACPI_INTERRUPT_HANDLED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) * DESCRIPTION: Invoked directly from the SCI handler when a global lock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) * release interrupt occurs. If there is actually a pending
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) * request for the lock, signal the waiting thread.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) static u32 acpi_ev_global_lock_handler(void *context)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) acpi_cpu_flags flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) flags = acpi_os_acquire_lock(acpi_gbl_global_lock_pending_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) * If a request for the global lock is not actually pending,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) * we are done. This handles "spurious" global lock interrupts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) * which are possible (and have been seen) with bad BIOSs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) if (!acpi_gbl_global_lock_pending) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) goto cleanup_and_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) * Send a unit to the global lock semaphore. The actual acquisition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) * of the global lock will be performed by the waiting thread.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) status = acpi_os_signal_semaphore(acpi_gbl_global_lock_semaphore, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) if (ACPI_FAILURE(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) ACPI_ERROR((AE_INFO, "Could not signal Global Lock semaphore"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) acpi_gbl_global_lock_pending = FALSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) cleanup_and_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) acpi_os_release_lock(acpi_gbl_global_lock_pending_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) return (ACPI_INTERRUPT_HANDLED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) /******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) * FUNCTION: acpi_ev_acquire_global_lock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) * PARAMETERS: timeout - Max time to wait for the lock, in millisec.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) * RETURN: Status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) * DESCRIPTION: Attempt to gain ownership of the Global Lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) * MUTEX: Interpreter must be locked
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) * Note: The original implementation allowed multiple threads to "acquire" the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) * Global Lock, and the OS would hold the lock until the last thread had
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) * released it. However, this could potentially starve the BIOS out of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) * lock, especially in the case where there is a tight handshake between the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) * Embedded Controller driver and the BIOS. Therefore, this implementation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) * allows only one thread to acquire the HW Global Lock at a time, and makes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) * the global lock appear as a standard mutex on the OS side.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) *****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) acpi_status acpi_ev_acquire_global_lock(u16 timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) acpi_cpu_flags flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) u8 acquired = FALSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) ACPI_FUNCTION_TRACE(ev_acquire_global_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) * Only one thread can acquire the GL at a time, the global_lock_mutex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) * enforces this. This interface releases the interpreter if we must wait.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) status =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) acpi_ex_system_wait_mutex(acpi_gbl_global_lock_mutex->mutex.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) os_mutex, timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) if (ACPI_FAILURE(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) return_ACPI_STATUS(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) * Update the global lock handle and check for wraparound. The handle is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) * only used for the external global lock interfaces, but it is updated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) * here to properly handle the case where a single thread may acquire the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) * lock via both the AML and the acpi_acquire_global_lock interfaces. The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) * handle is therefore updated on the first acquire from a given thread
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) * regardless of where the acquisition request originated.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) acpi_gbl_global_lock_handle++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) if (acpi_gbl_global_lock_handle == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) acpi_gbl_global_lock_handle = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) * Make sure that a global lock actually exists. If not, just
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) * treat the lock as a standard mutex.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) if (!acpi_gbl_global_lock_present) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) acpi_gbl_global_lock_acquired = TRUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) return_ACPI_STATUS(AE_OK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) flags = acpi_os_acquire_lock(acpi_gbl_global_lock_pending_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) /* Attempt to acquire the actual hardware lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) ACPI_ACQUIRE_GLOBAL_LOCK(acpi_gbl_FACS, acquired);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) if (acquired) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) acpi_gbl_global_lock_acquired = TRUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) "Acquired hardware Global Lock\n"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) * Did not get the lock. The pending bit was set above, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) * we must now wait until we receive the global lock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) * released interrupt.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) acpi_gbl_global_lock_pending = TRUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) acpi_os_release_lock(acpi_gbl_global_lock_pending_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) "Waiting for hardware Global Lock\n"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) * Wait for handshake with the global lock interrupt handler.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) * This interface releases the interpreter if we must wait.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) status =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) acpi_ex_system_wait_semaphore
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) (acpi_gbl_global_lock_semaphore, ACPI_WAIT_FOREVER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) flags = acpi_os_acquire_lock(acpi_gbl_global_lock_pending_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) } while (ACPI_SUCCESS(status));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) acpi_gbl_global_lock_pending = FALSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) acpi_os_release_lock(acpi_gbl_global_lock_pending_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) return_ACPI_STATUS(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) /*******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) * FUNCTION: acpi_ev_release_global_lock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) * PARAMETERS: None
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) * RETURN: Status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) * DESCRIPTION: Releases ownership of the Global Lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) ******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) acpi_status acpi_ev_release_global_lock(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) u8 pending = FALSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) acpi_status status = AE_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) ACPI_FUNCTION_TRACE(ev_release_global_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) /* Lock must be already acquired */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) if (!acpi_gbl_global_lock_acquired) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) ACPI_WARNING((AE_INFO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) "Cannot release the ACPI Global Lock, it has not been acquired"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) return_ACPI_STATUS(AE_NOT_ACQUIRED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) if (acpi_gbl_global_lock_present) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) /* Allow any thread to release the lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) ACPI_RELEASE_GLOBAL_LOCK(acpi_gbl_FACS, pending);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) * If the pending bit was set, we must write GBL_RLS to the control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) * register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) if (pending) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) status =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) acpi_write_bit_register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) (ACPI_BITREG_GLOBAL_LOCK_RELEASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) ACPI_ENABLE_EVENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) "Released hardware Global Lock\n"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) acpi_gbl_global_lock_acquired = FALSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) /* Release the local GL mutex */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) acpi_os_release_mutex(acpi_gbl_global_lock_mutex->mutex.os_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) return_ACPI_STATUS(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) #endif /* !ACPI_REDUCED_HARDWARE */