1220604Sjkim/****************************************************************************** 2220604Sjkim * 3220604Sjkim * Module Name: evglock - Global Lock support 4220604Sjkim * 5220604Sjkim *****************************************************************************/ 6220604Sjkim 7316303Sjkim/****************************************************************************** 8316303Sjkim * 9316303Sjkim * 1. Copyright Notice 10316303Sjkim * 11316303Sjkim * Some or all of this work - Copyright (c) 1999 - 2017, Intel Corp. 12220604Sjkim * All rights reserved. 13220604Sjkim * 14316303Sjkim * 2. License 15316303Sjkim * 16316303Sjkim * 2.1. This is your license from Intel Corp. under its intellectual property 17316303Sjkim * rights. You may have additional license terms from the party that provided 18316303Sjkim * you this software, covering your right to use that party's intellectual 19316303Sjkim * property rights. 20316303Sjkim * 21316303Sjkim * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 22316303Sjkim * copy of the source code appearing in this file ("Covered Code") an 23316303Sjkim * irrevocable, perpetual, worldwide license under Intel's copyrights in the 24316303Sjkim * base code distributed originally by Intel ("Original Intel Code") to copy, 25316303Sjkim * make derivatives, distribute, use and display any portion of the Covered 26316303Sjkim * Code in any form, with the right to sublicense such rights; and 27316303Sjkim * 28316303Sjkim * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 29316303Sjkim * license (with the right to sublicense), under only those claims of Intel 30316303Sjkim * patents that are infringed by the Original Intel Code, to make, use, sell, 31316303Sjkim * offer to sell, and import the Covered Code and derivative works thereof 32316303Sjkim * solely to the minimum extent necessary to exercise the above copyright 33316303Sjkim * license, and in no event shall the patent license extend to any additions 34316303Sjkim * to or modifications of the Original Intel Code. No other license or right 35316303Sjkim * is granted directly or by implication, estoppel or otherwise; 36316303Sjkim * 37316303Sjkim * The above copyright and patent license is granted only if the following 38316303Sjkim * conditions are met: 39316303Sjkim * 40316303Sjkim * 3. Conditions 41316303Sjkim * 42316303Sjkim * 3.1. Redistribution of Source with Rights to Further Distribute Source. 43316303Sjkim * Redistribution of source code of any substantial portion of the Covered 44316303Sjkim * Code or modification with rights to further distribute source must include 45316303Sjkim * the above Copyright Notice, the above License, this list of Conditions, 46316303Sjkim * and the following Disclaimer and Export Compliance provision. In addition, 47316303Sjkim * Licensee must cause all Covered Code to which Licensee contributes to 48316303Sjkim * contain a file documenting the changes Licensee made to create that Covered 49316303Sjkim * Code and the date of any change. Licensee must include in that file the 50316303Sjkim * documentation of any changes made by any predecessor Licensee. Licensee 51316303Sjkim * must include a prominent statement that the modification is derived, 52316303Sjkim * directly or indirectly, from Original Intel Code. 53316303Sjkim * 54316303Sjkim * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 55316303Sjkim * Redistribution of source code of any substantial portion of the Covered 56316303Sjkim * Code or modification without rights to further distribute source must 57316303Sjkim * include the following Disclaimer and Export Compliance provision in the 58316303Sjkim * documentation and/or other materials provided with distribution. In 59316303Sjkim * addition, Licensee may not authorize further sublicense of source of any 60316303Sjkim * portion of the Covered Code, and must include terms to the effect that the 61316303Sjkim * license from Licensee to its licensee is limited to the intellectual 62316303Sjkim * property embodied in the software Licensee provides to its licensee, and 63316303Sjkim * not to intellectual property embodied in modifications its licensee may 64316303Sjkim * make. 65316303Sjkim * 66316303Sjkim * 3.3. Redistribution of Executable. Redistribution in executable form of any 67316303Sjkim * substantial portion of the Covered Code or modification must reproduce the 68316303Sjkim * above Copyright Notice, and the following Disclaimer and Export Compliance 69316303Sjkim * provision in the documentation and/or other materials provided with the 70316303Sjkim * distribution. 71316303Sjkim * 72316303Sjkim * 3.4. Intel retains all right, title, and interest in and to the Original 73316303Sjkim * Intel Code. 74316303Sjkim * 75316303Sjkim * 3.5. Neither the name Intel nor any other trademark owned or controlled by 76316303Sjkim * Intel shall be used in advertising or otherwise to promote the sale, use or 77316303Sjkim * other dealings in products derived from or relating to the Covered Code 78316303Sjkim * without prior written authorization from Intel. 79316303Sjkim * 80316303Sjkim * 4. Disclaimer and Export Compliance 81316303Sjkim * 82316303Sjkim * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 83316303Sjkim * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 84316303Sjkim * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 85316303Sjkim * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 86316303Sjkim * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 87316303Sjkim * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 88316303Sjkim * PARTICULAR PURPOSE. 89316303Sjkim * 90316303Sjkim * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 91316303Sjkim * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 92316303Sjkim * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 93316303Sjkim * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 94316303Sjkim * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 95316303Sjkim * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 96316303Sjkim * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 97316303Sjkim * LIMITED REMEDY. 98316303Sjkim * 99316303Sjkim * 4.3. Licensee shall not export, either directly or indirectly, any of this 100316303Sjkim * software or system incorporating such software without first obtaining any 101316303Sjkim * required license or other approval from the U. S. Department of Commerce or 102316303Sjkim * any other agency or department of the United States Government. In the 103316303Sjkim * event Licensee exports any such software from the United States or 104316303Sjkim * re-exports any such software from a foreign destination, Licensee shall 105316303Sjkim * ensure that the distribution and export/re-export of the software is in 106316303Sjkim * compliance with all laws, regulations, orders, or other restrictions of the 107316303Sjkim * U.S. Export Administration Regulations. Licensee agrees that neither it nor 108316303Sjkim * any of its subsidiaries will export/re-export any technical data, process, 109316303Sjkim * software, or service, directly or indirectly, to any country for which the 110316303Sjkim * United States government or any agency thereof requires an export license, 111316303Sjkim * other governmental approval, or letter of assurance, without first obtaining 112316303Sjkim * such license, approval or letter. 113316303Sjkim * 114316303Sjkim ***************************************************************************** 115316303Sjkim * 116316303Sjkim * Alternatively, you may choose to be licensed under the terms of the 117316303Sjkim * following license: 118316303Sjkim * 119220604Sjkim * Redistribution and use in source and binary forms, with or without 120220604Sjkim * modification, are permitted provided that the following conditions 121220604Sjkim * are met: 122220604Sjkim * 1. Redistributions of source code must retain the above copyright 123220604Sjkim * notice, this list of conditions, and the following disclaimer, 124220604Sjkim * without modification. 125220604Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 126220604Sjkim * substantially similar to the "NO WARRANTY" disclaimer below 127220604Sjkim * ("Disclaimer") and any redistribution must be conditioned upon 128220604Sjkim * including a substantially similar Disclaimer requirement for further 129220604Sjkim * binary redistribution. 130220604Sjkim * 3. Neither the names of the above-listed copyright holders nor the names 131220604Sjkim * of any contributors may be used to endorse or promote products derived 132220604Sjkim * from this software without specific prior written permission. 133220604Sjkim * 134316303Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 135316303Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 136316303Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 137316303Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 138316303Sjkim * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 139316303Sjkim * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 140316303Sjkim * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 141316303Sjkim * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 142316303Sjkim * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 143316303Sjkim * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 144316303Sjkim * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 145316303Sjkim * 146316303Sjkim * Alternatively, you may choose to be licensed under the terms of the 147220604Sjkim * GNU General Public License ("GPL") version 2 as published by the Free 148220604Sjkim * Software Foundation. 149220604Sjkim * 150316303Sjkim *****************************************************************************/ 151220604Sjkim 152220663Sjkim#include <contrib/dev/acpica/include/acpi.h> 153220663Sjkim#include <contrib/dev/acpica/include/accommon.h> 154220663Sjkim#include <contrib/dev/acpica/include/acevents.h> 155220663Sjkim#include <contrib/dev/acpica/include/acinterp.h> 156220604Sjkim 157220604Sjkim#define _COMPONENT ACPI_EVENTS 158220604Sjkim ACPI_MODULE_NAME ("evglock") 159220604Sjkim 160231844Sjkim#if (!ACPI_REDUCED_HARDWARE) /* Entire module */ 161220604Sjkim 162220604Sjkim/* Local prototypes */ 163220604Sjkim 164220604Sjkimstatic UINT32 165220604SjkimAcpiEvGlobalLockHandler ( 166220604Sjkim void *Context); 167220604Sjkim 168220604Sjkim 169220604Sjkim/******************************************************************************* 170220604Sjkim * 171220604Sjkim * FUNCTION: AcpiEvInitGlobalLockHandler 172220604Sjkim * 173220604Sjkim * PARAMETERS: None 174220604Sjkim * 175220604Sjkim * RETURN: Status 176220604Sjkim * 177220604Sjkim * DESCRIPTION: Install a handler for the global lock release event 178220604Sjkim * 179220604Sjkim ******************************************************************************/ 180220604Sjkim 181220604SjkimACPI_STATUS 182220604SjkimAcpiEvInitGlobalLockHandler ( 183220604Sjkim void) 184220604Sjkim{ 185220604Sjkim ACPI_STATUS Status; 186220604Sjkim 187220604Sjkim 188220604Sjkim ACPI_FUNCTION_TRACE (EvInitGlobalLockHandler); 189220604Sjkim 190220604Sjkim 191228110Sjkim /* If Hardware Reduced flag is set, there is no global lock */ 192228110Sjkim 193228110Sjkim if (AcpiGbl_ReducedHardware) 194228110Sjkim { 195228110Sjkim return_ACPI_STATUS (AE_OK); 196228110Sjkim } 197228110Sjkim 198220604Sjkim /* Attempt installation of the global lock handler */ 199220604Sjkim 200220604Sjkim Status = AcpiInstallFixedEventHandler (ACPI_EVENT_GLOBAL, 201298714Sjkim AcpiEvGlobalLockHandler, NULL); 202220604Sjkim 203220604Sjkim /* 204220604Sjkim * If the global lock does not exist on this platform, the attempt to 205220604Sjkim * enable GBL_STATUS will fail (the GBL_ENABLE bit will not stick). 206220604Sjkim * Map to AE_OK, but mark global lock as not present. Any attempt to 207220604Sjkim * actually use the global lock will be flagged with an error. 208220604Sjkim */ 209220604Sjkim AcpiGbl_GlobalLockPresent = FALSE; 210220604Sjkim if (Status == AE_NO_HARDWARE_RESPONSE) 211220604Sjkim { 212220604Sjkim ACPI_ERROR ((AE_INFO, 213220604Sjkim "No response from Global Lock hardware, disabling lock")); 214220604Sjkim 215220604Sjkim return_ACPI_STATUS (AE_OK); 216220604Sjkim } 217220604Sjkim 218220604Sjkim Status = AcpiOsCreateLock (&AcpiGbl_GlobalLockPendingLock); 219220604Sjkim if (ACPI_FAILURE (Status)) 220220604Sjkim { 221220604Sjkim return_ACPI_STATUS (Status); 222220604Sjkim } 223220604Sjkim 224220604Sjkim AcpiGbl_GlobalLockPending = FALSE; 225220604Sjkim AcpiGbl_GlobalLockPresent = TRUE; 226220604Sjkim return_ACPI_STATUS (Status); 227220604Sjkim} 228220604Sjkim 229220604Sjkim 230220604Sjkim/******************************************************************************* 231220604Sjkim * 232220604Sjkim * FUNCTION: AcpiEvRemoveGlobalLockHandler 233220604Sjkim * 234220604Sjkim * PARAMETERS: None 235220604Sjkim * 236220604Sjkim * RETURN: Status 237220604Sjkim * 238220604Sjkim * DESCRIPTION: Remove the handler for the Global Lock 239220604Sjkim * 240220604Sjkim ******************************************************************************/ 241220604Sjkim 242220604SjkimACPI_STATUS 243220604SjkimAcpiEvRemoveGlobalLockHandler ( 244220604Sjkim void) 245220604Sjkim{ 246220604Sjkim ACPI_STATUS Status; 247220604Sjkim 248220604Sjkim 249220604Sjkim ACPI_FUNCTION_TRACE (EvRemoveGlobalLockHandler); 250220604Sjkim 251298714Sjkim 252220604Sjkim AcpiGbl_GlobalLockPresent = FALSE; 253220604Sjkim Status = AcpiRemoveFixedEventHandler (ACPI_EVENT_GLOBAL, 254298714Sjkim AcpiEvGlobalLockHandler); 255220604Sjkim 256250838Sjkim AcpiOsDeleteLock (AcpiGbl_GlobalLockPendingLock); 257220604Sjkim return_ACPI_STATUS (Status); 258220604Sjkim} 259220604Sjkim 260220604Sjkim 261220604Sjkim/******************************************************************************* 262220604Sjkim * 263220604Sjkim * FUNCTION: AcpiEvGlobalLockHandler 264220604Sjkim * 265220604Sjkim * PARAMETERS: Context - From thread interface, not used 266220604Sjkim * 267220604Sjkim * RETURN: ACPI_INTERRUPT_HANDLED 268220604Sjkim * 269220604Sjkim * DESCRIPTION: Invoked directly from the SCI handler when a global lock 270220604Sjkim * release interrupt occurs. If there is actually a pending 271220604Sjkim * request for the lock, signal the waiting thread. 272220604Sjkim * 273220604Sjkim ******************************************************************************/ 274220604Sjkim 275220604Sjkimstatic UINT32 276220604SjkimAcpiEvGlobalLockHandler ( 277220604Sjkim void *Context) 278220604Sjkim{ 279220604Sjkim ACPI_STATUS Status; 280220604Sjkim ACPI_CPU_FLAGS Flags; 281220604Sjkim 282220604Sjkim 283220604Sjkim Flags = AcpiOsAcquireLock (AcpiGbl_GlobalLockPendingLock); 284220604Sjkim 285220604Sjkim /* 286220604Sjkim * If a request for the global lock is not actually pending, 287220604Sjkim * we are done. This handles "spurious" global lock interrupts 288220604Sjkim * which are possible (and have been seen) with bad BIOSs. 289220604Sjkim */ 290220604Sjkim if (!AcpiGbl_GlobalLockPending) 291220604Sjkim { 292220604Sjkim goto CleanupAndExit; 293220604Sjkim } 294220604Sjkim 295220604Sjkim /* 296220604Sjkim * Send a unit to the global lock semaphore. The actual acquisition 297220604Sjkim * of the global lock will be performed by the waiting thread. 298220604Sjkim */ 299220604Sjkim Status = AcpiOsSignalSemaphore (AcpiGbl_GlobalLockSemaphore, 1); 300220604Sjkim if (ACPI_FAILURE (Status)) 301220604Sjkim { 302220604Sjkim ACPI_ERROR ((AE_INFO, "Could not signal Global Lock semaphore")); 303220604Sjkim } 304220604Sjkim 305220604Sjkim AcpiGbl_GlobalLockPending = FALSE; 306220604Sjkim 307220604Sjkim 308220604SjkimCleanupAndExit: 309220604Sjkim 310220604Sjkim AcpiOsReleaseLock (AcpiGbl_GlobalLockPendingLock, Flags); 311220604Sjkim return (ACPI_INTERRUPT_HANDLED); 312220604Sjkim} 313220604Sjkim 314220604Sjkim 315220604Sjkim/****************************************************************************** 316220604Sjkim * 317220604Sjkim * FUNCTION: AcpiEvAcquireGlobalLock 318220604Sjkim * 319220604Sjkim * PARAMETERS: Timeout - Max time to wait for the lock, in millisec. 320220604Sjkim * 321220604Sjkim * RETURN: Status 322220604Sjkim * 323220604Sjkim * DESCRIPTION: Attempt to gain ownership of the Global Lock. 324220604Sjkim * 325220604Sjkim * MUTEX: Interpreter must be locked 326220604Sjkim * 327220604Sjkim * Note: The original implementation allowed multiple threads to "acquire" the 328220604Sjkim * Global Lock, and the OS would hold the lock until the last thread had 329220604Sjkim * released it. However, this could potentially starve the BIOS out of the 330220604Sjkim * lock, especially in the case where there is a tight handshake between the 331220604Sjkim * Embedded Controller driver and the BIOS. Therefore, this implementation 332220604Sjkim * allows only one thread to acquire the HW Global Lock at a time, and makes 333220604Sjkim * the global lock appear as a standard mutex on the OS side. 334220604Sjkim * 335220604Sjkim *****************************************************************************/ 336220604Sjkim 337220604SjkimACPI_STATUS 338220604SjkimAcpiEvAcquireGlobalLock ( 339220604Sjkim UINT16 Timeout) 340220604Sjkim{ 341220604Sjkim ACPI_CPU_FLAGS Flags; 342220604Sjkim ACPI_STATUS Status; 343220604Sjkim BOOLEAN Acquired = FALSE; 344220604Sjkim 345220604Sjkim 346220604Sjkim ACPI_FUNCTION_TRACE (EvAcquireGlobalLock); 347220604Sjkim 348220604Sjkim 349220604Sjkim /* 350220604Sjkim * Only one thread can acquire the GL at a time, the GlobalLockMutex 351220604Sjkim * enforces this. This interface releases the interpreter if we must wait. 352220604Sjkim */ 353220604Sjkim Status = AcpiExSystemWaitMutex (AcpiGbl_GlobalLockMutex->Mutex.OsMutex, 354220604Sjkim Timeout); 355220604Sjkim if (ACPI_FAILURE (Status)) 356220604Sjkim { 357220604Sjkim return_ACPI_STATUS (Status); 358220604Sjkim } 359220604Sjkim 360220604Sjkim /* 361220604Sjkim * Update the global lock handle and check for wraparound. The handle is 362220604Sjkim * only used for the external global lock interfaces, but it is updated 363220604Sjkim * here to properly handle the case where a single thread may acquire the 364220604Sjkim * lock via both the AML and the AcpiAcquireGlobalLock interfaces. The 365220604Sjkim * handle is therefore updated on the first acquire from a given thread 366220604Sjkim * regardless of where the acquisition request originated. 367220604Sjkim */ 368220604Sjkim AcpiGbl_GlobalLockHandle++; 369220604Sjkim if (AcpiGbl_GlobalLockHandle == 0) 370220604Sjkim { 371220604Sjkim AcpiGbl_GlobalLockHandle = 1; 372220604Sjkim } 373220604Sjkim 374220604Sjkim /* 375220604Sjkim * Make sure that a global lock actually exists. If not, just 376220604Sjkim * treat the lock as a standard mutex. 377220604Sjkim */ 378220604Sjkim if (!AcpiGbl_GlobalLockPresent) 379220604Sjkim { 380220604Sjkim AcpiGbl_GlobalLockAcquired = TRUE; 381220604Sjkim return_ACPI_STATUS (AE_OK); 382220604Sjkim } 383220604Sjkim 384220604Sjkim Flags = AcpiOsAcquireLock (AcpiGbl_GlobalLockPendingLock); 385220604Sjkim 386220604Sjkim do 387220604Sjkim { 388220604Sjkim /* Attempt to acquire the actual hardware lock */ 389220604Sjkim 390220604Sjkim ACPI_ACQUIRE_GLOBAL_LOCK (AcpiGbl_FACS, Acquired); 391220604Sjkim if (Acquired) 392220604Sjkim { 393220604Sjkim AcpiGbl_GlobalLockAcquired = TRUE; 394220604Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 395220604Sjkim "Acquired hardware Global Lock\n")); 396220604Sjkim break; 397220604Sjkim } 398220604Sjkim 399220604Sjkim /* 400220604Sjkim * Did not get the lock. The pending bit was set above, and 401220604Sjkim * we must now wait until we receive the global lock 402220604Sjkim * released interrupt. 403220604Sjkim */ 404220604Sjkim AcpiGbl_GlobalLockPending = TRUE; 405220604Sjkim AcpiOsReleaseLock (AcpiGbl_GlobalLockPendingLock, Flags); 406220604Sjkim 407220604Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 408220604Sjkim "Waiting for hardware Global Lock\n")); 409220604Sjkim 410220604Sjkim /* 411220604Sjkim * Wait for handshake with the global lock interrupt handler. 412220604Sjkim * This interface releases the interpreter if we must wait. 413220604Sjkim */ 414298714Sjkim Status = AcpiExSystemWaitSemaphore ( 415298714Sjkim AcpiGbl_GlobalLockSemaphore, ACPI_WAIT_FOREVER); 416220604Sjkim 417220604Sjkim Flags = AcpiOsAcquireLock (AcpiGbl_GlobalLockPendingLock); 418220604Sjkim 419220604Sjkim } while (ACPI_SUCCESS (Status)); 420220604Sjkim 421220604Sjkim AcpiGbl_GlobalLockPending = FALSE; 422220604Sjkim AcpiOsReleaseLock (AcpiGbl_GlobalLockPendingLock, Flags); 423220604Sjkim 424220604Sjkim return_ACPI_STATUS (Status); 425220604Sjkim} 426220604Sjkim 427220604Sjkim 428220604Sjkim/******************************************************************************* 429220604Sjkim * 430220604Sjkim * FUNCTION: AcpiEvReleaseGlobalLock 431220604Sjkim * 432220604Sjkim * PARAMETERS: None 433220604Sjkim * 434220604Sjkim * RETURN: Status 435220604Sjkim * 436220604Sjkim * DESCRIPTION: Releases ownership of the Global Lock. 437220604Sjkim * 438220604Sjkim ******************************************************************************/ 439220604Sjkim 440220604SjkimACPI_STATUS 441220604SjkimAcpiEvReleaseGlobalLock ( 442220604Sjkim void) 443220604Sjkim{ 444220604Sjkim BOOLEAN Pending = FALSE; 445220604Sjkim ACPI_STATUS Status = AE_OK; 446220604Sjkim 447220604Sjkim 448220604Sjkim ACPI_FUNCTION_TRACE (EvReleaseGlobalLock); 449220604Sjkim 450220604Sjkim 451220604Sjkim /* Lock must be already acquired */ 452220604Sjkim 453220604Sjkim if (!AcpiGbl_GlobalLockAcquired) 454220604Sjkim { 455220604Sjkim ACPI_WARNING ((AE_INFO, 456220604Sjkim "Cannot release the ACPI Global Lock, it has not been acquired")); 457220604Sjkim return_ACPI_STATUS (AE_NOT_ACQUIRED); 458220604Sjkim } 459220604Sjkim 460220604Sjkim if (AcpiGbl_GlobalLockPresent) 461220604Sjkim { 462220604Sjkim /* Allow any thread to release the lock */ 463220604Sjkim 464220604Sjkim ACPI_RELEASE_GLOBAL_LOCK (AcpiGbl_FACS, Pending); 465220604Sjkim 466220604Sjkim /* 467220604Sjkim * If the pending bit was set, we must write GBL_RLS to the control 468220604Sjkim * register 469220604Sjkim */ 470220604Sjkim if (Pending) 471220604Sjkim { 472220604Sjkim Status = AcpiWriteBitRegister ( 473298714Sjkim ACPI_BITREG_GLOBAL_LOCK_RELEASE, ACPI_ENABLE_EVENT); 474220604Sjkim } 475220604Sjkim 476220604Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Released hardware Global Lock\n")); 477220604Sjkim } 478220604Sjkim 479220604Sjkim AcpiGbl_GlobalLockAcquired = FALSE; 480220604Sjkim 481220604Sjkim /* Release the local GL mutex */ 482220604Sjkim 483220604Sjkim AcpiOsReleaseMutex (AcpiGbl_GlobalLockMutex->Mutex.OsMutex); 484220604Sjkim return_ACPI_STATUS (Status); 485220604Sjkim} 486231844Sjkim 487231844Sjkim#endif /* !ACPI_REDUCED_HARDWARE */ 488