167754Smsmith/****************************************************************************** 267754Smsmith * 3245582Sjkim * Module Name: evregion - Operation Region support 467754Smsmith * 567754Smsmith *****************************************************************************/ 667754Smsmith 7316303Sjkim/****************************************************************************** 8316303Sjkim * 9316303Sjkim * 1. Copyright Notice 10316303Sjkim * 11316303Sjkim * Some or all of this work - Copyright (c) 1999 - 2017, Intel Corp. 1270243Smsmith * All rights reserved. 1367754Smsmith * 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 * 119217365Sjkim * Redistribution and use in source and binary forms, with or without 120217365Sjkim * modification, are permitted provided that the following conditions 121217365Sjkim * are met: 122217365Sjkim * 1. Redistributions of source code must retain the above copyright 123217365Sjkim * notice, this list of conditions, and the following disclaimer, 124217365Sjkim * without modification. 125217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 126217365Sjkim * substantially similar to the "NO WARRANTY" disclaimer below 127217365Sjkim * ("Disclaimer") and any redistribution must be conditioned upon 128217365Sjkim * including a substantially similar Disclaimer requirement for further 129217365Sjkim * binary redistribution. 130217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names 131217365Sjkim * of any contributors may be used to endorse or promote products derived 132217365Sjkim * from this software without specific prior written permission. 13367754Smsmith * 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 147217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free 148217365Sjkim * Software Foundation. 14967754Smsmith * 150316303Sjkim *****************************************************************************/ 15167754Smsmith 152193341Sjkim#include <contrib/dev/acpica/include/acpi.h> 153193341Sjkim#include <contrib/dev/acpica/include/accommon.h> 154193341Sjkim#include <contrib/dev/acpica/include/acevents.h> 155193341Sjkim#include <contrib/dev/acpica/include/acnamesp.h> 156193341Sjkim#include <contrib/dev/acpica/include/acinterp.h> 15767754Smsmith 15877424Smsmith#define _COMPONENT ACPI_EVENTS 15991116Smsmith ACPI_MODULE_NAME ("evregion") 16067754Smsmith 16167754Smsmith 162245582Sjkimextern UINT8 AcpiGbl_DefaultAddressSpaces[]; 163245582Sjkim 164151937Sjkim/* Local prototypes */ 165117521Snjl 166220663Sjkimstatic void 167220663SjkimAcpiEvOrphanEcRegMethod ( 168249663Sjkim ACPI_NAMESPACE_NODE *EcDeviceNode); 169220663Sjkim 170151937Sjkimstatic ACPI_STATUS 171151937SjkimAcpiEvRegRun ( 172151937Sjkim ACPI_HANDLE ObjHandle, 173151937Sjkim UINT32 Level, 174151937Sjkim void *Context, 175151937Sjkim void **ReturnValue); 176151937Sjkim 177151937Sjkim 17877424Smsmith/******************************************************************************* 17967754Smsmith * 180129684Snjl * FUNCTION: AcpiEvInitializeOpRegions 181129684Snjl * 182129684Snjl * PARAMETERS: None 183129684Snjl * 184129684Snjl * RETURN: Status 185129684Snjl * 186129684Snjl * DESCRIPTION: Execute _REG methods for all Operation Regions that have 187129684Snjl * an installed default region handler. 188129684Snjl * 189129684Snjl ******************************************************************************/ 190129684Snjl 191129684SnjlACPI_STATUS 192129684SnjlAcpiEvInitializeOpRegions ( 193129684Snjl void) 194129684Snjl{ 195129684Snjl ACPI_STATUS Status; 196193267Sjkim UINT32 i; 197129684Snjl 198129684Snjl 199167802Sjkim ACPI_FUNCTION_TRACE (EvInitializeOpRegions); 200129684Snjl 201129684Snjl 202129684Snjl Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 203129684Snjl if (ACPI_FAILURE (Status)) 204129684Snjl { 205129684Snjl return_ACPI_STATUS (Status); 206129684Snjl } 207129684Snjl 208193267Sjkim /* Run the _REG methods for OpRegions in each default address space */ 209193267Sjkim 210129684Snjl for (i = 0; i < ACPI_NUM_DEFAULT_SPACES; i++) 211129684Snjl { 212193267Sjkim /* 213198237Sjkim * Make sure the installed handler is the DEFAULT handler. If not the 214198237Sjkim * default, the _REG methods will have already been run (when the 215198237Sjkim * handler was installed) 216129684Snjl */ 217198237Sjkim if (AcpiEvHasDefaultHandler (AcpiGbl_RootNode, 218198237Sjkim AcpiGbl_DefaultAddressSpaces[i])) 219198237Sjkim { 220298714Sjkim AcpiEvExecuteRegMethods (AcpiGbl_RootNode, 221298714Sjkim AcpiGbl_DefaultAddressSpaces[i], ACPI_REG_CONNECT); 222198237Sjkim } 223129684Snjl } 224129684Snjl 225129684Snjl (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 226129684Snjl return_ACPI_STATUS (Status); 227129684Snjl} 228129684Snjl 229129684Snjl 230129684Snjl/******************************************************************************* 231129684Snjl * 23267754Smsmith * FUNCTION: AcpiEvAddressSpaceDispatch 23367754Smsmith * 234123315Snjl * PARAMETERS: RegionObj - Internal region object 235228110Sjkim * FieldObj - Corresponding field. Can be NULL. 23667754Smsmith * Function - Read or Write operation 237193267Sjkim * RegionOffset - Where in the region to read or write 23887031Smsmith * BitWidth - Field width in bits (8, 16, 32, or 64) 239167802Sjkim * Value - Pointer to in or out value, must be 240202771Sjkim * a full 64-bit integer 24167754Smsmith * 24267754Smsmith * RETURN: Status 24367754Smsmith * 24467754Smsmith * DESCRIPTION: Dispatch an address space or operation region access to 24567754Smsmith * a previously installed handler. 24667754Smsmith * 247298714Sjkim * NOTE: During early initialization, we always install the default region 248298714Sjkim * handlers for Memory, I/O and PCI_Config. This ensures that these operation 249298714Sjkim * region address spaces are always available as per the ACPI specification. 250298714Sjkim * This is especially needed in order to support the execution of 251298714Sjkim * module-level AML code during loading of the ACPI tables. 252298714Sjkim * 25377424Smsmith ******************************************************************************/ 25467754Smsmith 25567754SmsmithACPI_STATUS 25667754SmsmithAcpiEvAddressSpaceDispatch ( 25767754Smsmith ACPI_OPERAND_OBJECT *RegionObj, 258228110Sjkim ACPI_OPERAND_OBJECT *FieldObj, 25967754Smsmith UINT32 Function, 260193267Sjkim UINT32 RegionOffset, 26167754Smsmith UINT32 BitWidth, 262202771Sjkim UINT64 *Value) 26367754Smsmith{ 26467754Smsmith ACPI_STATUS Status; 26577424Smsmith ACPI_ADR_SPACE_HANDLER Handler; 26677424Smsmith ACPI_ADR_SPACE_SETUP RegionSetup; 26767754Smsmith ACPI_OPERAND_OBJECT *HandlerDesc; 26887031Smsmith ACPI_OPERAND_OBJECT *RegionObj2; 26967754Smsmith void *RegionContext = NULL; 270228110Sjkim ACPI_CONNECTION_INFO *Context; 271272444Sjkim ACPI_PHYSICAL_ADDRESS Address; 27267754Smsmith 27367754Smsmith 274167802Sjkim ACPI_FUNCTION_TRACE (EvAddressSpaceDispatch); 27567754Smsmith 27667754Smsmith 27787031Smsmith RegionObj2 = AcpiNsGetSecondaryObject (RegionObj); 27887031Smsmith if (!RegionObj2) 27987031Smsmith { 28087031Smsmith return_ACPI_STATUS (AE_NOT_EXIST); 28187031Smsmith } 28287031Smsmith 283117521Snjl /* Ensure that there is a handler associated with this region */ 284117521Snjl 285123315Snjl HandlerDesc = RegionObj->Region.Handler; 28667754Smsmith if (!HandlerDesc) 28767754Smsmith { 288167802Sjkim ACPI_ERROR ((AE_INFO, 289167802Sjkim "No handler for Region [%4.4s] (%p) [%s]", 290123315Snjl AcpiUtGetNodeName (RegionObj->Region.Node), 29177424Smsmith RegionObj, AcpiUtGetRegionName (RegionObj->Region.SpaceId))); 29277424Smsmith 29387031Smsmith return_ACPI_STATUS (AE_NOT_EXIST); 29467754Smsmith } 29567754Smsmith 296228110Sjkim Context = HandlerDesc->AddressSpace.Context; 297228110Sjkim 29867754Smsmith /* 299193267Sjkim * It may be the case that the region has never been initialized. 30077424Smsmith * Some types of regions require special init code 30167754Smsmith */ 30287031Smsmith if (!(RegionObj->Region.Flags & AOPOBJ_SETUP_COMPLETE)) 30367754Smsmith { 304193267Sjkim /* This region has not been initialized yet, do it */ 305193267Sjkim 306117521Snjl RegionSetup = HandlerDesc->AddressSpace.Setup; 30767754Smsmith if (!RegionSetup) 30867754Smsmith { 309117521Snjl /* No initialization routine, exit with error */ 310117521Snjl 311167802Sjkim ACPI_ERROR ((AE_INFO, 312167802Sjkim "No init routine for region(%p) [%s]", 31377424Smsmith RegionObj, AcpiUtGetRegionName (RegionObj->Region.SpaceId))); 314117521Snjl return_ACPI_STATUS (AE_NOT_EXIST); 31567754Smsmith } 31667754Smsmith 31767754Smsmith /* 318193267Sjkim * We must exit the interpreter because the region setup will 319193267Sjkim * potentially execute control methods (for example, the _REG method 320193267Sjkim * for this region) 32167754Smsmith */ 322193267Sjkim AcpiExExitInterpreter (); 32367754Smsmith 32467754Smsmith Status = RegionSetup (RegionObj, ACPI_REGION_ACTIVATE, 325298714Sjkim Context, &RegionContext); 32667754Smsmith 32767754Smsmith /* Re-enter the interpreter */ 32867754Smsmith 329193267Sjkim AcpiExEnterInterpreter (); 33067754Smsmith 331117521Snjl /* Check for failure of the Region Setup */ 332117521Snjl 33367754Smsmith if (ACPI_FAILURE (Status)) 33467754Smsmith { 335167802Sjkim ACPI_EXCEPTION ((AE_INFO, Status, 336167802Sjkim "During region initialization: [%s]", 33777424Smsmith AcpiUtGetRegionName (RegionObj->Region.SpaceId))); 33887031Smsmith return_ACPI_STATUS (Status); 33967754Smsmith } 34067754Smsmith 341193267Sjkim /* Region initialization may have been completed by RegionSetup */ 342193267Sjkim 343117521Snjl if (!(RegionObj->Region.Flags & AOPOBJ_SETUP_COMPLETE)) 344117521Snjl { 345117521Snjl RegionObj->Region.Flags |= AOPOBJ_SETUP_COMPLETE; 346117521Snjl 347254745Sjkim /* 348254745Sjkim * Save the returned context for use in all accesses to 349254745Sjkim * the handler for this particular region 350254745Sjkim */ 351254745Sjkim if (!(RegionObj2->Extra.RegionContext)) 352117521Snjl { 353117521Snjl RegionObj2->Extra.RegionContext = RegionContext; 354117521Snjl } 355117521Snjl } 35667754Smsmith } 35767754Smsmith 358117521Snjl /* We have everything we need, we can invoke the address space handler */ 35967754Smsmith 360117521Snjl Handler = HandlerDesc->AddressSpace.Handler; 361272444Sjkim Address = (RegionObj->Region.Address + RegionOffset); 362117521Snjl 363228110Sjkim /* 364228110Sjkim * Special handling for GenericSerialBus and GeneralPurposeIo: 365228110Sjkim * There are three extra parameters that must be passed to the 366228110Sjkim * handler via the context: 367272444Sjkim * 1) Connection buffer, a resource template from Connection() op 368272444Sjkim * 2) Length of the above buffer 369272444Sjkim * 3) Actual access length from the AccessAs() op 370272444Sjkim * 371272444Sjkim * In addition, for GeneralPurposeIo, the Address and BitWidth fields 372272444Sjkim * are defined as follows: 373272444Sjkim * 1) Address is the pin number index of the field (bit offset from 374272444Sjkim * the previous Connection) 375272444Sjkim * 2) BitWidth is the actual bit length of the field (number of pins) 376228110Sjkim */ 377272444Sjkim if ((RegionObj->Region.SpaceId == ACPI_ADR_SPACE_GSBUS) && 378228110Sjkim Context && 379228110Sjkim FieldObj) 380228110Sjkim { 381228110Sjkim /* Get the Connection (ResourceTemplate) buffer */ 382228110Sjkim 383228110Sjkim Context->Connection = FieldObj->Field.ResourceBuffer; 384228110Sjkim Context->Length = FieldObj->Field.ResourceLength; 385228110Sjkim Context->AccessLength = FieldObj->Field.AccessLength; 386228110Sjkim } 387272444Sjkim if ((RegionObj->Region.SpaceId == ACPI_ADR_SPACE_GPIO) && 388272444Sjkim Context && 389272444Sjkim FieldObj) 390272444Sjkim { 391272444Sjkim /* Get the Connection (ResourceTemplate) buffer */ 392228110Sjkim 393272444Sjkim Context->Connection = FieldObj->Field.ResourceBuffer; 394272444Sjkim Context->Length = FieldObj->Field.ResourceLength; 395272444Sjkim Context->AccessLength = FieldObj->Field.AccessLength; 396272444Sjkim Address = FieldObj->Field.PinNumberIndex; 397272444Sjkim BitWidth = FieldObj->Field.BitLength; 398272444Sjkim } 399272444Sjkim 400272444Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, 401272444Sjkim "Handler %p (@%p) Address %8.8X%8.8X [%s]\n", 402272444Sjkim &RegionObj->Region.Handler->AddressSpace, Handler, 403281396Sjkim ACPI_FORMAT_UINT64 (Address), 404272444Sjkim AcpiUtGetRegionName (RegionObj->Region.SpaceId))); 405272444Sjkim 406167802Sjkim if (!(HandlerDesc->AddressSpace.HandlerFlags & 407298714Sjkim ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) 40867754Smsmith { 40967754Smsmith /* 410117521Snjl * For handlers other than the default (supplied) handlers, we must 411117521Snjl * exit the interpreter because the handler *might* block -- we don't 412117521Snjl * know what it will do, so we can't hold the lock on the intepreter. 41367754Smsmith */ 414193267Sjkim AcpiExExitInterpreter(); 41567754Smsmith } 41667754Smsmith 417117521Snjl /* Call the handler */ 418117521Snjl 419272444Sjkim Status = Handler (Function, Address, BitWidth, Value, Context, 420272444Sjkim RegionObj2->Extra.RegionContext); 42167754Smsmith 42267754Smsmith if (ACPI_FAILURE (Status)) 42367754Smsmith { 424167802Sjkim ACPI_EXCEPTION ((AE_INFO, Status, "Returned by Handler for [%s]", 425167802Sjkim AcpiUtGetRegionName (RegionObj->Region.SpaceId))); 426327557Sjkim 427327557Sjkim /* 428327557Sjkim * Special case for an EC timeout. These are seen so frequently 429327557Sjkim * that an additional error message is helpful 430327557Sjkim */ 431327557Sjkim if ((RegionObj->Region.SpaceId == ACPI_ADR_SPACE_EC) && 432327557Sjkim (Status == AE_TIME)) 433327557Sjkim { 434327557Sjkim ACPI_ERROR ((AE_INFO, 435327557Sjkim "Timeout from EC hardware or EC device driver")); 436327557Sjkim } 43767754Smsmith } 43867754Smsmith 439167802Sjkim if (!(HandlerDesc->AddressSpace.HandlerFlags & 440298714Sjkim ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) 44167754Smsmith { 44283174Smsmith /* 44383174Smsmith * We just returned from a non-default handler, we must re-enter the 44483174Smsmith * interpreter 44583174Smsmith */ 446298714Sjkim AcpiExEnterInterpreter (); 44767754Smsmith } 44867754Smsmith 44967754Smsmith return_ACPI_STATUS (Status); 45067754Smsmith} 45167754Smsmith 452123315Snjl 45377424Smsmith/******************************************************************************* 45467754Smsmith * 45599679Siwasaki * FUNCTION: AcpiEvDetachRegion 45667754Smsmith * 457138287Smarks * PARAMETERS: RegionObj - Region Object 458138287Smarks * AcpiNsIsLocked - Namespace Region Already Locked? 45967754Smsmith * 46067754Smsmith * RETURN: None 46167754Smsmith * 46267754Smsmith * DESCRIPTION: Break the association between the handler and the region 46367754Smsmith * this is a two way association. 46467754Smsmith * 46567754Smsmith ******************************************************************************/ 46667754Smsmith 46767754Smsmithvoid 468298714SjkimAcpiEvDetachRegion ( 46970243Smsmith ACPI_OPERAND_OBJECT *RegionObj, 47070243Smsmith BOOLEAN AcpiNsIsLocked) 47167754Smsmith{ 47267754Smsmith ACPI_OPERAND_OBJECT *HandlerObj; 47367754Smsmith ACPI_OPERAND_OBJECT *ObjDesc; 474272444Sjkim ACPI_OPERAND_OBJECT *StartDesc; 47567754Smsmith ACPI_OPERAND_OBJECT **LastObjPtr; 47677424Smsmith ACPI_ADR_SPACE_SETUP RegionSetup; 477123315Snjl void **RegionContext; 47887031Smsmith ACPI_OPERAND_OBJECT *RegionObj2; 47967754Smsmith ACPI_STATUS Status; 48067754Smsmith 48167754Smsmith 482167802Sjkim ACPI_FUNCTION_TRACE (EvDetachRegion); 48367754Smsmith 48483174Smsmith 48587031Smsmith RegionObj2 = AcpiNsGetSecondaryObject (RegionObj); 48687031Smsmith if (!RegionObj2) 48787031Smsmith { 48899679Siwasaki return_VOID; 48987031Smsmith } 490123315Snjl RegionContext = &RegionObj2->Extra.RegionContext; 49167754Smsmith 492117521Snjl /* Get the address handler from the region object */ 493117521Snjl 494123315Snjl HandlerObj = RegionObj->Region.Handler; 49567754Smsmith if (!HandlerObj) 49667754Smsmith { 497117521Snjl /* This region has no handler, all done */ 498117521Snjl 49967754Smsmith return_VOID; 50067754Smsmith } 50167754Smsmith 502117521Snjl /* Find this region in the handler's list */ 50367754Smsmith 504117521Snjl ObjDesc = HandlerObj->AddressSpace.RegionList; 505272444Sjkim StartDesc = ObjDesc; 506117521Snjl LastObjPtr = &HandlerObj->AddressSpace.RegionList; 50767754Smsmith 50867754Smsmith while (ObjDesc) 50967754Smsmith { 510117521Snjl /* Is this the correct Region? */ 511117521Snjl 51267754Smsmith if (ObjDesc == RegionObj) 51367754Smsmith { 51482367Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, 51582367Smsmith "Removing Region %p from address handler %p\n", 51667754Smsmith RegionObj, HandlerObj)); 517117521Snjl 518117521Snjl /* This is it, remove it from the handler's list */ 519117521Snjl 52067754Smsmith *LastObjPtr = ObjDesc->Region.Next; 521193267Sjkim ObjDesc->Region.Next = NULL; /* Must clear field */ 52267754Smsmith 52370243Smsmith if (AcpiNsIsLocked) 52470243Smsmith { 52591116Smsmith Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 52691116Smsmith if (ACPI_FAILURE (Status)) 52791116Smsmith { 52891116Smsmith return_VOID; 52991116Smsmith } 53070243Smsmith } 53170243Smsmith 532117521Snjl /* Now stop region accesses by executing the _REG method */ 533117521Snjl 534220663Sjkim Status = AcpiEvExecuteRegMethod (RegionObj, ACPI_REG_DISCONNECT); 53599679Siwasaki if (ACPI_FAILURE (Status)) 53699679Siwasaki { 537167802Sjkim ACPI_EXCEPTION ((AE_INFO, Status, "from region _REG, [%s]", 53899679Siwasaki AcpiUtGetRegionName (RegionObj->Region.SpaceId))); 53999679Siwasaki } 54067754Smsmith 54170243Smsmith if (AcpiNsIsLocked) 54270243Smsmith { 54391116Smsmith Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 54491116Smsmith if (ACPI_FAILURE (Status)) 54591116Smsmith { 54691116Smsmith return_VOID; 54791116Smsmith } 54870243Smsmith } 54970243Smsmith 550167802Sjkim /* 551193267Sjkim * If the region has been activated, call the setup handler with 552193267Sjkim * the deactivate notification 553167802Sjkim */ 554167802Sjkim if (RegionObj->Region.Flags & AOPOBJ_SETUP_COMPLETE) 555167802Sjkim { 556167802Sjkim RegionSetup = HandlerObj->AddressSpace.Setup; 557167802Sjkim Status = RegionSetup (RegionObj, ACPI_REGION_DEACTIVATE, 558167802Sjkim HandlerObj->AddressSpace.Context, RegionContext); 559117521Snjl 560254745Sjkim /* 561254745Sjkim * RegionContext should have been released by the deactivate 562254745Sjkim * operation. We don't need access to it anymore here. 563254745Sjkim */ 564254745Sjkim if (RegionContext) 565254745Sjkim { 566254745Sjkim *RegionContext = NULL; 567254745Sjkim } 568254745Sjkim 569167802Sjkim /* Init routine may fail, Just ignore errors */ 57067754Smsmith 571167802Sjkim if (ACPI_FAILURE (Status)) 572167802Sjkim { 573167802Sjkim ACPI_EXCEPTION ((AE_INFO, Status, 574167802Sjkim "from region handler - deactivate, [%s]", 575167802Sjkim AcpiUtGetRegionName (RegionObj->Region.SpaceId))); 576167802Sjkim } 577117521Snjl 578167802Sjkim RegionObj->Region.Flags &= ~(AOPOBJ_SETUP_COMPLETE); 57967754Smsmith } 58067754Smsmith 58167754Smsmith /* 582117521Snjl * Remove handler reference in the region 58367754Smsmith * 584167802Sjkim * NOTE: this doesn't mean that the region goes away, the region 585167802Sjkim * is just inaccessible as indicated to the _REG method 58667754Smsmith * 587167802Sjkim * If the region is on the handler's list, this must be the 588167802Sjkim * region's handler 58967754Smsmith */ 590123315Snjl RegionObj->Region.Handler = NULL; 591117521Snjl AcpiUtRemoveReference (HandlerObj); 59267754Smsmith 59367754Smsmith return_VOID; 594117521Snjl } 59567754Smsmith 596117521Snjl /* Walk the linked list of handlers */ 59767754Smsmith 59867754Smsmith LastObjPtr = &ObjDesc->Region.Next; 59967754Smsmith ObjDesc = ObjDesc->Region.Next; 600272444Sjkim 601272444Sjkim /* Prevent infinite loop if list is corrupted */ 602272444Sjkim 603272444Sjkim if (ObjDesc == StartDesc) 604272444Sjkim { 605272444Sjkim ACPI_ERROR ((AE_INFO, 606272444Sjkim "Circular handler list in region object %p", 607272444Sjkim RegionObj)); 608272444Sjkim return_VOID; 609272444Sjkim } 61067754Smsmith } 61167754Smsmith 612117521Snjl /* If we get here, the region was not in the handler's region list */ 613117521Snjl 61482367Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, 61582367Smsmith "Cannot remove region %p from address handler %p\n", 61667754Smsmith RegionObj, HandlerObj)); 61767754Smsmith 61867754Smsmith return_VOID; 61967754Smsmith} 62067754Smsmith 62167754Smsmith 62277424Smsmith/******************************************************************************* 62367754Smsmith * 62499679Siwasaki * FUNCTION: AcpiEvAttachRegion 62567754Smsmith * 626138287Smarks * PARAMETERS: HandlerObj - Handler Object 627138287Smarks * RegionObj - Region Object 628138287Smarks * AcpiNsIsLocked - Namespace Region Already Locked? 62967754Smsmith * 63067754Smsmith * RETURN: None 63167754Smsmith * 63267754Smsmith * DESCRIPTION: Create the association between the handler and the region 63367754Smsmith * this is a two way association. 63467754Smsmith * 63567754Smsmith ******************************************************************************/ 63667754Smsmith 63767754SmsmithACPI_STATUS 63899679SiwasakiAcpiEvAttachRegion ( 63967754Smsmith ACPI_OPERAND_OBJECT *HandlerObj, 64067754Smsmith ACPI_OPERAND_OBJECT *RegionObj, 64167754Smsmith BOOLEAN AcpiNsIsLocked) 64267754Smsmith{ 64367754Smsmith 644167802Sjkim ACPI_FUNCTION_TRACE (EvAttachRegion); 64567754Smsmith 64667754Smsmith 647298714Sjkim /* Install the region's handler */ 648298714Sjkim 649298714Sjkim if (RegionObj->Region.Handler) 650298714Sjkim { 651298714Sjkim return_ACPI_STATUS (AE_ALREADY_EXISTS); 652298714Sjkim } 653298714Sjkim 65483174Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, 655123315Snjl "Adding Region [%4.4s] %p to address handler %p [%s]\n", 656123315Snjl AcpiUtGetNodeName (RegionObj->Region.Node), 657126372Snjl RegionObj, HandlerObj, 658123315Snjl AcpiUtGetRegionName (RegionObj->Region.SpaceId))); 65967754Smsmith 660117521Snjl /* Link this region to the front of the handler's list */ 66167754Smsmith 662117521Snjl RegionObj->Region.Next = HandlerObj->AddressSpace.RegionList; 663117521Snjl HandlerObj->AddressSpace.RegionList = RegionObj; 664123315Snjl RegionObj->Region.Handler = HandlerObj; 665117521Snjl AcpiUtAddReference (HandlerObj); 666117521Snjl 667123315Snjl return_ACPI_STATUS (AE_OK); 66867754Smsmith} 66967754Smsmith 67067754Smsmith 67177424Smsmith/******************************************************************************* 67267754Smsmith * 673245582Sjkim * FUNCTION: AcpiEvExecuteRegMethod 67467754Smsmith * 675245582Sjkim * PARAMETERS: RegionObj - Region object 676245582Sjkim * Function - Passed to _REG: On (1) or Off (0) 67767754Smsmith * 678245582Sjkim * RETURN: Status 67967754Smsmith * 680245582Sjkim * DESCRIPTION: Execute _REG method for a region 68167754Smsmith * 68277424Smsmith ******************************************************************************/ 68367754Smsmith 684245582SjkimACPI_STATUS 685245582SjkimAcpiEvExecuteRegMethod ( 686245582Sjkim ACPI_OPERAND_OBJECT *RegionObj, 687245582Sjkim UINT32 Function) 68867754Smsmith{ 689245582Sjkim ACPI_EVALUATE_INFO *Info; 690245582Sjkim ACPI_OPERAND_OBJECT *Args[3]; 691245582Sjkim ACPI_OPERAND_OBJECT *RegionObj2; 692298714Sjkim const ACPI_NAME *RegNamePtr = ACPI_CAST_PTR (ACPI_NAME, METHOD_NAME__REG); 693298714Sjkim ACPI_NAMESPACE_NODE *MethodNode; 694298714Sjkim ACPI_NAMESPACE_NODE *Node; 69567754Smsmith ACPI_STATUS Status; 69667754Smsmith 69767754Smsmith 698245582Sjkim ACPI_FUNCTION_TRACE (EvExecuteRegMethod); 69977424Smsmith 70077424Smsmith 701298714Sjkim if (!AcpiGbl_NamespaceInitialized || 702298714Sjkim RegionObj->Region.Handler == NULL) 703298714Sjkim { 704298714Sjkim return_ACPI_STATUS (AE_OK); 705298714Sjkim } 706298714Sjkim 707245582Sjkim RegionObj2 = AcpiNsGetSecondaryObject (RegionObj); 708245582Sjkim if (!RegionObj2) 70967754Smsmith { 710245582Sjkim return_ACPI_STATUS (AE_NOT_EXIST); 71167754Smsmith } 71267754Smsmith 713298714Sjkim /* 714298714Sjkim * Find any "_REG" method associated with this region definition. 715298714Sjkim * The method should always be updated as this function may be 716298714Sjkim * invoked after a namespace change. 717298714Sjkim */ 718298714Sjkim Node = RegionObj->Region.Node->Parent; 719298714Sjkim Status = AcpiNsSearchOneScope ( 720298714Sjkim *RegNamePtr, Node, ACPI_TYPE_METHOD, &MethodNode); 721298714Sjkim if (ACPI_SUCCESS (Status)) 722298714Sjkim { 723298714Sjkim /* 724298714Sjkim * The _REG method is optional and there can be only one per 725298714Sjkim * region definition. This will be executed when the handler is 726298714Sjkim * attached or removed. 727298714Sjkim */ 728298714Sjkim RegionObj2->Extra.Method_REG = MethodNode; 729298714Sjkim } 730245582Sjkim if (RegionObj2->Extra.Method_REG == NULL) 73167754Smsmith { 732245582Sjkim return_ACPI_STATUS (AE_OK); 73367754Smsmith } 73467754Smsmith 735298714Sjkim /* _REG(DISCONNECT) should be paired with _REG(CONNECT) */ 736298714Sjkim 737298714Sjkim if ((Function == ACPI_REG_CONNECT && 738298714Sjkim RegionObj->Common.Flags & AOPOBJ_REG_CONNECTED) || 739298714Sjkim (Function == ACPI_REG_DISCONNECT && 740298714Sjkim !(RegionObj->Common.Flags & AOPOBJ_REG_CONNECTED))) 741298714Sjkim { 742298714Sjkim return_ACPI_STATUS (AE_OK); 743298714Sjkim } 744298714Sjkim 745245582Sjkim /* Allocate and initialize the evaluation information block */ 74667754Smsmith 747245582Sjkim Info = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO)); 748245582Sjkim if (!Info) 74967754Smsmith { 750245582Sjkim return_ACPI_STATUS (AE_NO_MEMORY); 75167754Smsmith } 75267754Smsmith 753245582Sjkim Info->PrefixNode = RegionObj2->Extra.Method_REG; 754249663Sjkim Info->RelativePathname = NULL; 755245582Sjkim Info->Parameters = Args; 756245582Sjkim Info->Flags = ACPI_IGNORE_RETURN_VALUE; 757117521Snjl 75867754Smsmith /* 759245582Sjkim * The _REG method has two arguments: 76067754Smsmith * 761245582Sjkim * Arg0 - Integer: 762245582Sjkim * Operation region space ID Same value as RegionObj->Region.SpaceId 763245582Sjkim * 764245582Sjkim * Arg1 - Integer: 765245582Sjkim * connection status 1 for connecting the handler, 0 for disconnecting 766245582Sjkim * the handler (Passed as a parameter) 76767754Smsmith */ 768245582Sjkim Args[0] = AcpiUtCreateIntegerObject ((UINT64) RegionObj->Region.SpaceId); 769245582Sjkim if (!Args[0]) 770129684Snjl { 771245582Sjkim Status = AE_NO_MEMORY; 772245582Sjkim goto Cleanup1; 773129684Snjl } 774129684Snjl 775245582Sjkim Args[1] = AcpiUtCreateIntegerObject ((UINT64) Function); 776245582Sjkim if (!Args[1]) 777129684Snjl { 778129684Snjl Status = AE_NO_MEMORY; 779245582Sjkim goto Cleanup2; 780129684Snjl } 781129684Snjl 782245582Sjkim Args[2] = NULL; /* Terminate list */ 783129684Snjl 784245582Sjkim /* Execute the method, no return value */ 785129684Snjl 786245582Sjkim ACPI_DEBUG_EXEC ( 787245582Sjkim AcpiUtDisplayInitPathname (ACPI_TYPE_METHOD, Info->PrefixNode, NULL)); 788129684Snjl 789245582Sjkim Status = AcpiNsEvaluate (Info); 790245582Sjkim AcpiUtRemoveReference (Args[1]); 791129684Snjl 792298714Sjkim if (ACPI_FAILURE (Status)) 793298714Sjkim { 794298714Sjkim goto Cleanup2; 795298714Sjkim } 796298714Sjkim 797298714Sjkim if (Function == ACPI_REG_CONNECT) 798298714Sjkim { 799298714Sjkim RegionObj->Common.Flags |= AOPOBJ_REG_CONNECTED; 800298714Sjkim } 801298714Sjkim else 802298714Sjkim { 803298714Sjkim RegionObj->Common.Flags &= ~AOPOBJ_REG_CONNECTED; 804298714Sjkim } 805298714Sjkim 806245582SjkimCleanup2: 807245582Sjkim AcpiUtRemoveReference (Args[0]); 808129684Snjl 809245582SjkimCleanup1: 810245582Sjkim ACPI_FREE (Info); 811129684Snjl return_ACPI_STATUS (Status); 812129684Snjl} 813129684Snjl 814129684Snjl 815129684Snjl/******************************************************************************* 816129684Snjl * 817129684Snjl * FUNCTION: AcpiEvExecuteRegMethods 818129684Snjl * 819129684Snjl * PARAMETERS: Node - Namespace node for the device 820129684Snjl * SpaceId - The address space ID 821298714Sjkim * Function - Passed to _REG: On (1) or Off (0) 822129684Snjl * 823298714Sjkim * RETURN: None 824129684Snjl * 825138287Smarks * DESCRIPTION: Run all _REG methods for the input Space ID; 826129684Snjl * Note: assumes namespace is locked, or system init time. 827129684Snjl * 828129684Snjl ******************************************************************************/ 829129684Snjl 830298714Sjkimvoid 831129684SnjlAcpiEvExecuteRegMethods ( 832129684Snjl ACPI_NAMESPACE_NODE *Node, 833298714Sjkim ACPI_ADR_SPACE_TYPE SpaceId, 834298714Sjkim UINT32 Function) 835129684Snjl{ 836287168Sjkim ACPI_REG_WALK_INFO Info; 837129684Snjl 838129684Snjl 839167802Sjkim ACPI_FUNCTION_TRACE (EvExecuteRegMethods); 840129684Snjl 841287168Sjkim Info.SpaceId = SpaceId; 842298714Sjkim Info.Function = Function; 843287168Sjkim Info.RegRunCount = 0; 844129684Snjl 845287168Sjkim ACPI_DEBUG_PRINT_RAW ((ACPI_DB_NAMES, 846287168Sjkim " Running _REG methods for SpaceId %s\n", 847287168Sjkim AcpiUtGetRegionName (Info.SpaceId))); 848287168Sjkim 849129684Snjl /* 850193267Sjkim * Run all _REG methods for all Operation Regions for this space ID. This 851193267Sjkim * is a separate walk in order to handle any interdependencies between 852193267Sjkim * regions and _REG methods. (i.e. handlers must be installed for all 853193267Sjkim * regions of this Space ID before we can run any _REG methods) 854129684Snjl */ 855298714Sjkim (void) AcpiNsWalkNamespace (ACPI_TYPE_ANY, Node, ACPI_UINT32_MAX, 856287168Sjkim ACPI_NS_WALK_UNLOCK, AcpiEvRegRun, NULL, &Info, NULL); 857129684Snjl 858220663Sjkim /* Special case for EC: handle "orphan" _REG methods with no region */ 859220663Sjkim 860220663Sjkim if (SpaceId == ACPI_ADR_SPACE_EC) 861220663Sjkim { 862249663Sjkim AcpiEvOrphanEcRegMethod (Node); 863220663Sjkim } 864220663Sjkim 865287168Sjkim ACPI_DEBUG_PRINT_RAW ((ACPI_DB_NAMES, 866287168Sjkim " Executed %u _REG methods for SpaceId %s\n", 867287168Sjkim Info.RegRunCount, AcpiUtGetRegionName (Info.SpaceId))); 868287168Sjkim 869298714Sjkim return_VOID; 870129684Snjl} 871129684Snjl 872129684Snjl 873129684Snjl/******************************************************************************* 874129684Snjl * 875123315Snjl * FUNCTION: AcpiEvRegRun 876123315Snjl * 877123315Snjl * PARAMETERS: WalkNamespace callback 878123315Snjl * 879123315Snjl * DESCRIPTION: Run _REG method for region objects of the requested spaceID 880123315Snjl * 881123315Snjl ******************************************************************************/ 88267754Smsmith 883151937Sjkimstatic ACPI_STATUS 884123315SnjlAcpiEvRegRun ( 885123315Snjl ACPI_HANDLE ObjHandle, 886123315Snjl UINT32 Level, 887123315Snjl void *Context, 888123315Snjl void **ReturnValue) 889123315Snjl{ 890123315Snjl ACPI_OPERAND_OBJECT *ObjDesc; 891123315Snjl ACPI_NAMESPACE_NODE *Node; 892123315Snjl ACPI_STATUS Status; 893287168Sjkim ACPI_REG_WALK_INFO *Info; 894123315Snjl 895123315Snjl 896287168Sjkim Info = ACPI_CAST_PTR (ACPI_REG_WALK_INFO, Context); 897123315Snjl 898123315Snjl /* Convert and validate the device handle */ 899123315Snjl 900200553Sjkim Node = AcpiNsValidateHandle (ObjHandle); 901123315Snjl if (!Node) 902123315Snjl { 903123315Snjl return (AE_BAD_PARAMETER); 904123315Snjl } 905123315Snjl 906123315Snjl /* 907193267Sjkim * We only care about regions.and objects that are allowed to have address 908193267Sjkim * space handlers 909123315Snjl */ 910123315Snjl if ((Node->Type != ACPI_TYPE_REGION) && 911123315Snjl (Node != AcpiGbl_RootNode)) 912123315Snjl { 913123315Snjl return (AE_OK); 914123315Snjl } 915123315Snjl 916123315Snjl /* Check for an existing internal object */ 917123315Snjl 918123315Snjl ObjDesc = AcpiNsGetAttachedObject (Node); 919123315Snjl if (!ObjDesc) 920123315Snjl { 921123315Snjl /* No object, just exit */ 922123315Snjl 923123315Snjl return (AE_OK); 924123315Snjl } 925123315Snjl 926123315Snjl /* Object is a Region */ 927123315Snjl 928287168Sjkim if (ObjDesc->Region.SpaceId != Info->SpaceId) 929123315Snjl { 930193267Sjkim /* This region is for a different address space, just ignore it */ 931193267Sjkim 932123315Snjl return (AE_OK); 933123315Snjl } 934123315Snjl 935287168Sjkim Info->RegRunCount++; 936298714Sjkim Status = AcpiEvExecuteRegMethod (ObjDesc, Info->Function); 937123315Snjl return (Status); 938123315Snjl} 939123315Snjl 940220663Sjkim 941220663Sjkim/******************************************************************************* 942220663Sjkim * 943220663Sjkim * FUNCTION: AcpiEvOrphanEcRegMethod 944220663Sjkim * 945249663Sjkim * PARAMETERS: EcDeviceNode - Namespace node for an EC device 946220663Sjkim * 947220663Sjkim * RETURN: None 948220663Sjkim * 949220663Sjkim * DESCRIPTION: Execute an "orphan" _REG method that appears under the EC 950220663Sjkim * device. This is a _REG method that has no corresponding region 951220663Sjkim * within the EC device scope. The orphan _REG method appears to 952220663Sjkim * have been enabled by the description of the ECDT in the ACPI 953220663Sjkim * specification: "The availability of the region space can be 954220663Sjkim * detected by providing a _REG method object underneath the 955220663Sjkim * Embedded Controller device." 956220663Sjkim * 957249663Sjkim * To quickly access the EC device, we use the EcDeviceNode used 958249663Sjkim * during EC handler installation. Otherwise, we would need to 959249663Sjkim * perform a time consuming namespace walk, executing _HID 960249663Sjkim * methods to find the EC device. 961220663Sjkim * 962249663Sjkim * MUTEX: Assumes the namespace is locked 963249663Sjkim * 964220663Sjkim ******************************************************************************/ 965220663Sjkim 966220663Sjkimstatic void 967220663SjkimAcpiEvOrphanEcRegMethod ( 968249663Sjkim ACPI_NAMESPACE_NODE *EcDeviceNode) 969220663Sjkim{ 970249663Sjkim ACPI_HANDLE RegMethod; 971249663Sjkim ACPI_NAMESPACE_NODE *NextNode; 972220663Sjkim ACPI_STATUS Status; 973220663Sjkim ACPI_OBJECT_LIST Args; 974220663Sjkim ACPI_OBJECT Objects[2]; 975220663Sjkim 976220663Sjkim 977220663Sjkim ACPI_FUNCTION_TRACE (EvOrphanEcRegMethod); 978220663Sjkim 979220663Sjkim 980249663Sjkim if (!EcDeviceNode) 981220663Sjkim { 982220663Sjkim return_VOID; 983220663Sjkim } 984220663Sjkim 985220663Sjkim /* Namespace is currently locked, must release */ 986220663Sjkim 987220663Sjkim (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 988220663Sjkim 989220663Sjkim /* Get a handle to a _REG method immediately under the EC device */ 990220663Sjkim 991249663Sjkim Status = AcpiGetHandle (EcDeviceNode, METHOD_NAME__REG, &RegMethod); 992220663Sjkim if (ACPI_FAILURE (Status)) 993220663Sjkim { 994249663Sjkim goto Exit; /* There is no _REG method present */ 995220663Sjkim } 996220663Sjkim 997220663Sjkim /* 998220663Sjkim * Execute the _REG method only if there is no Operation Region in 999220663Sjkim * this scope with the Embedded Controller space ID. Otherwise, it 1000220663Sjkim * will already have been executed. Note, this allows for Regions 1001220663Sjkim * with other space IDs to be present; but the code below will then 1002249663Sjkim * execute the _REG method with the EmbeddedControl SpaceID argument. 1003220663Sjkim */ 1004220663Sjkim NextNode = AcpiNsGetNextNode (EcDeviceNode, NULL); 1005220663Sjkim while (NextNode) 1006220663Sjkim { 1007220663Sjkim if ((NextNode->Type == ACPI_TYPE_REGION) && 1008220663Sjkim (NextNode->Object) && 1009220663Sjkim (NextNode->Object->Region.SpaceId == ACPI_ADR_SPACE_EC)) 1010220663Sjkim { 1011249663Sjkim goto Exit; /* Do not execute the _REG */ 1012220663Sjkim } 1013249663Sjkim 1014220663Sjkim NextNode = AcpiNsGetNextNode (EcDeviceNode, NextNode); 1015220663Sjkim } 1016220663Sjkim 1017249663Sjkim /* Evaluate the _REG(EmbeddedControl,Connect) method */ 1018220663Sjkim 1019220663Sjkim Args.Count = 2; 1020220663Sjkim Args.Pointer = Objects; 1021220663Sjkim Objects[0].Type = ACPI_TYPE_INTEGER; 1022220663Sjkim Objects[0].Integer.Value = ACPI_ADR_SPACE_EC; 1023220663Sjkim Objects[1].Type = ACPI_TYPE_INTEGER; 1024220663Sjkim Objects[1].Integer.Value = ACPI_REG_CONNECT; 1025220663Sjkim 1026220663Sjkim Status = AcpiEvaluateObject (RegMethod, NULL, &Args, NULL); 1027220663Sjkim 1028220663SjkimExit: 1029220663Sjkim /* We ignore all errors from above, don't care */ 1030220663Sjkim 1031220663Sjkim Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 1032220663Sjkim return_VOID; 1033220663Sjkim} 1034