Print this page
update to acpica-unix2-20140114
update to acpica-unix2-20131218
acpica-unix2-20130823
PANKOVs restructure
   1 /******************************************************************************
   2  *
   3  * Module Name: evgpeutil - GPE utilities
   4  *
   5  *****************************************************************************/
   6 
   7 /*
   8  * Copyright (C) 2000 - 2011, Intel Corp.
   9  * All rights reserved.
  10  *
  11  * Redistribution and use in source and binary forms, with or without
  12  * modification, are permitted provided that the following conditions
  13  * are met:
  14  * 1. Redistributions of source code must retain the above copyright
  15  *    notice, this list of conditions, and the following disclaimer,
  16  *    without modification.
  17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
  18  *    substantially similar to the "NO WARRANTY" disclaimer below
  19  *    ("Disclaimer") and any redistribution must be conditioned upon
  20  *    including a substantially similar Disclaimer requirement for further
  21  *    binary redistribution.
  22  * 3. Neither the names of the above-listed copyright holders nor the names
  23  *    of any contributors may be used to endorse or promote products derived
  24  *    from this software without specific prior written permission.
  25  *
  26  * Alternatively, this software may be distributed under the terms of the
  27  * GNU General Public License ("GPL") version 2 as published by the Free
  28  * Software Foundation.
  29  *
  30  * NO WARRANTY
  31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
  34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
  40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  41  * POSSIBILITY OF SUCH DAMAGES.
  42  */
  43 
  44 
  45 #include "acpi.h"
  46 #include "accommon.h"
  47 #include "acevents.h"
  48 
  49 #define _COMPONENT          ACPI_EVENTS
  50         ACPI_MODULE_NAME    ("evgpeutil")
  51 
  52 

  53 /*******************************************************************************
  54  *
  55  * FUNCTION:    AcpiEvWalkGpeList
  56  *
  57  * PARAMETERS:  GpeWalkCallback     - Routine called for each GPE block
  58  *              Context             - Value passed to callback
  59  *
  60  * RETURN:      Status
  61  *
  62  * DESCRIPTION: Walk the GPE lists.
  63  *
  64  ******************************************************************************/
  65 
  66 ACPI_STATUS
  67 AcpiEvWalkGpeList (
  68     ACPI_GPE_CALLBACK       GpeWalkCallback,
  69     void                    *Context)
  70 {
  71     ACPI_GPE_BLOCK_INFO     *GpeBlock;
  72     ACPI_GPE_XRUPT_INFO     *GpeXruptInfo;


 200          * NULL for the FADT-defined GPEs
 201          */
 202         if ((GpeBlock->Node)->Type == ACPI_TYPE_DEVICE)
 203         {
 204             Info->GpeDevice = GpeBlock->Node;
 205         }
 206 
 207         Info->Status = AE_OK;
 208         return (AE_CTRL_END);
 209     }
 210 
 211     return (AE_OK);
 212 }
 213 
 214 
 215 /*******************************************************************************
 216  *
 217  * FUNCTION:    AcpiEvGetGpeXruptBlock
 218  *
 219  * PARAMETERS:  InterruptNumber      - Interrupt for a GPE block

 220  *
 221  * RETURN:      A GPE interrupt block
 222  *
 223  * DESCRIPTION: Get or Create a GPE interrupt block. There is one interrupt
 224  *              block per unique interrupt level used for GPEs. Should be
 225  *              called only when the GPE lists are semaphore locked and not
 226  *              subject to change.
 227  *
 228  ******************************************************************************/
 229 
 230 ACPI_GPE_XRUPT_INFO *
 231 AcpiEvGetGpeXruptBlock (
 232     UINT32                  InterruptNumber)

 233 {
 234     ACPI_GPE_XRUPT_INFO     *NextGpeXrupt;
 235     ACPI_GPE_XRUPT_INFO     *GpeXrupt;
 236     ACPI_STATUS             Status;
 237     ACPI_CPU_FLAGS          Flags;
 238 
 239 
 240     ACPI_FUNCTION_TRACE (EvGetGpeXruptBlock);
 241 
 242 
 243     /* No need for lock since we are not changing any list elements here */
 244 
 245     NextGpeXrupt = AcpiGbl_GpeXruptListHead;
 246     while (NextGpeXrupt)
 247     {
 248         if (NextGpeXrupt->InterruptNumber == InterruptNumber)
 249         {
 250             return_PTR (NextGpeXrupt);

 251         }
 252 
 253         NextGpeXrupt = NextGpeXrupt->Next;
 254     }
 255 
 256     /* Not found, must allocate a new xrupt descriptor */
 257 
 258     GpeXrupt = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_GPE_XRUPT_INFO));
 259     if (!GpeXrupt)
 260     {
 261         return_PTR (NULL);
 262     }
 263 
 264     GpeXrupt->InterruptNumber = InterruptNumber;
 265 
 266     /* Install new interrupt descriptor with spin lock */
 267 
 268     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
 269     if (AcpiGbl_GpeXruptListHead)
 270     {
 271         NextGpeXrupt = AcpiGbl_GpeXruptListHead;
 272         while (NextGpeXrupt->Next)
 273         {
 274             NextGpeXrupt = NextGpeXrupt->Next;
 275         }
 276 
 277         NextGpeXrupt->Next = GpeXrupt;
 278         GpeXrupt->Previous = NextGpeXrupt;
 279     }
 280     else
 281     {
 282         AcpiGbl_GpeXruptListHead = GpeXrupt;
 283     }

 284     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
 285 
 286     /* Install new interrupt handler if not SCI_INT */
 287 
 288     if (InterruptNumber != AcpiGbl_FADT.SciInterrupt)
 289     {
 290         Status = AcpiOsInstallInterruptHandler (InterruptNumber,
 291                     AcpiEvGpeXruptHandler, GpeXrupt);
 292         if (ACPI_FAILURE (Status))
 293         {
 294             ACPI_ERROR ((AE_INFO,
 295                 "Could not install GPE interrupt handler at level 0x%X",
 296                 InterruptNumber));
 297             return_PTR (NULL);
 298         }
 299     }
 300 
 301     return_PTR (GpeXrupt);

 302 }
 303 
 304 
 305 /*******************************************************************************
 306  *
 307  * FUNCTION:    AcpiEvDeleteGpeXrupt
 308  *
 309  * PARAMETERS:  GpeXrupt        - A GPE interrupt info block
 310  *
 311  * RETURN:      Status
 312  *
 313  * DESCRIPTION: Remove and free a GpeXrupt block. Remove an associated
 314  *              interrupt handler if not the SCI interrupt.
 315  *
 316  ******************************************************************************/
 317 
 318 ACPI_STATUS
 319 AcpiEvDeleteGpeXrupt (
 320     ACPI_GPE_XRUPT_INFO     *GpeXrupt)
 321 {


 374  *
 375  * FUNCTION:    AcpiEvDeleteGpeHandlers
 376  *
 377  * PARAMETERS:  GpeXruptInfo        - GPE Interrupt info
 378  *              GpeBlock            - Gpe Block info
 379  *
 380  * RETURN:      Status
 381  *
 382  * DESCRIPTION: Delete all Handler objects found in the GPE data structs.
 383  *              Used only prior to termination.
 384  *
 385  ******************************************************************************/
 386 
 387 ACPI_STATUS
 388 AcpiEvDeleteGpeHandlers (
 389     ACPI_GPE_XRUPT_INFO     *GpeXruptInfo,
 390     ACPI_GPE_BLOCK_INFO     *GpeBlock,
 391     void                    *Context)
 392 {
 393     ACPI_GPE_EVENT_INFO     *GpeEventInfo;


 394     UINT32                  i;
 395     UINT32                  j;
 396 
 397 
 398     ACPI_FUNCTION_TRACE (EvDeleteGpeHandlers);
 399 
 400 
 401     /* Examine each GPE Register within the block */
 402 
 403     for (i = 0; i < GpeBlock->RegisterCount; i++)
 404     {
 405         /* Now look at the individual GPEs in this byte register */
 406 
 407         for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++)
 408         {
 409             GpeEventInfo = &GpeBlock->EventInfo[((ACPI_SIZE) i *
 410                 ACPI_GPE_REGISTER_WIDTH) + j];
 411 
 412             if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) ==
 413                     ACPI_GPE_DISPATCH_HANDLER)
 414             {


 415                 ACPI_FREE (GpeEventInfo->Dispatch.Handler);
 416                 GpeEventInfo->Dispatch.Handler = NULL;
 417                 GpeEventInfo->Flags &= ~ACPI_GPE_DISPATCH_MASK;
 418             }











 419         }


 420     }


 421 
 422     return_ACPI_STATUS (AE_OK);
 423 }
 424 

   1 /******************************************************************************
   2  *
   3  * Module Name: evgpeutil - GPE utilities
   4  *
   5  *****************************************************************************/
   6 
   7 /*
   8  * Copyright (C) 2000 - 2014, Intel Corp.
   9  * All rights reserved.
  10  *
  11  * Redistribution and use in source and binary forms, with or without
  12  * modification, are permitted provided that the following conditions
  13  * are met:
  14  * 1. Redistributions of source code must retain the above copyright
  15  *    notice, this list of conditions, and the following disclaimer,
  16  *    without modification.
  17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
  18  *    substantially similar to the "NO WARRANTY" disclaimer below
  19  *    ("Disclaimer") and any redistribution must be conditioned upon
  20  *    including a substantially similar Disclaimer requirement for further
  21  *    binary redistribution.
  22  * 3. Neither the names of the above-listed copyright holders nor the names
  23  *    of any contributors may be used to endorse or promote products derived
  24  *    from this software without specific prior written permission.
  25  *
  26  * Alternatively, this software may be distributed under the terms of the
  27  * GNU General Public License ("GPL") version 2 as published by the Free
  28  * Software Foundation.
  29  *
  30  * NO WARRANTY
  31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
  34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
  40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  41  * POSSIBILITY OF SUCH DAMAGES.
  42  */
  43 

  44 #include "acpi.h"
  45 #include "accommon.h"
  46 #include "acevents.h"
  47 
  48 #define _COMPONENT          ACPI_EVENTS
  49         ACPI_MODULE_NAME    ("evgpeutil")
  50 
  51 
  52 #if (!ACPI_REDUCED_HARDWARE) /* Entire module */
  53 /*******************************************************************************
  54  *
  55  * FUNCTION:    AcpiEvWalkGpeList
  56  *
  57  * PARAMETERS:  GpeWalkCallback     - Routine called for each GPE block
  58  *              Context             - Value passed to callback
  59  *
  60  * RETURN:      Status
  61  *
  62  * DESCRIPTION: Walk the GPE lists.
  63  *
  64  ******************************************************************************/
  65 
  66 ACPI_STATUS
  67 AcpiEvWalkGpeList (
  68     ACPI_GPE_CALLBACK       GpeWalkCallback,
  69     void                    *Context)
  70 {
  71     ACPI_GPE_BLOCK_INFO     *GpeBlock;
  72     ACPI_GPE_XRUPT_INFO     *GpeXruptInfo;


 200          * NULL for the FADT-defined GPEs
 201          */
 202         if ((GpeBlock->Node)->Type == ACPI_TYPE_DEVICE)
 203         {
 204             Info->GpeDevice = GpeBlock->Node;
 205         }
 206 
 207         Info->Status = AE_OK;
 208         return (AE_CTRL_END);
 209     }
 210 
 211     return (AE_OK);
 212 }
 213 
 214 
 215 /*******************************************************************************
 216  *
 217  * FUNCTION:    AcpiEvGetGpeXruptBlock
 218  *
 219  * PARAMETERS:  InterruptNumber             - Interrupt for a GPE block
 220  *              GpeXruptBlock               - Where the block is returned
 221  *
 222  * RETURN:      Status
 223  *
 224  * DESCRIPTION: Get or Create a GPE interrupt block. There is one interrupt
 225  *              block per unique interrupt level used for GPEs. Should be
 226  *              called only when the GPE lists are semaphore locked and not
 227  *              subject to change.
 228  *
 229  ******************************************************************************/
 230 
 231 ACPI_STATUS
 232 AcpiEvGetGpeXruptBlock (
 233     UINT32                  InterruptNumber,
 234     ACPI_GPE_XRUPT_INFO     **GpeXruptBlock)
 235 {
 236     ACPI_GPE_XRUPT_INFO     *NextGpeXrupt;
 237     ACPI_GPE_XRUPT_INFO     *GpeXrupt;
 238     ACPI_STATUS             Status;
 239     ACPI_CPU_FLAGS          Flags;
 240 
 241 
 242     ACPI_FUNCTION_TRACE (EvGetGpeXruptBlock);
 243 
 244 
 245     /* No need for lock since we are not changing any list elements here */
 246 
 247     NextGpeXrupt = AcpiGbl_GpeXruptListHead;
 248     while (NextGpeXrupt)
 249     {
 250         if (NextGpeXrupt->InterruptNumber == InterruptNumber)
 251         {
 252             *GpeXruptBlock = NextGpeXrupt;
 253             return_ACPI_STATUS (AE_OK);
 254         }
 255 
 256         NextGpeXrupt = NextGpeXrupt->Next;
 257     }
 258 
 259     /* Not found, must allocate a new xrupt descriptor */
 260 
 261     GpeXrupt = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_GPE_XRUPT_INFO));
 262     if (!GpeXrupt)
 263     {
 264         return_ACPI_STATUS (AE_NO_MEMORY);
 265     }
 266 
 267     GpeXrupt->InterruptNumber = InterruptNumber;
 268 
 269     /* Install new interrupt descriptor with spin lock */
 270 
 271     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
 272     if (AcpiGbl_GpeXruptListHead)
 273     {
 274         NextGpeXrupt = AcpiGbl_GpeXruptListHead;
 275         while (NextGpeXrupt->Next)
 276         {
 277             NextGpeXrupt = NextGpeXrupt->Next;
 278         }
 279 
 280         NextGpeXrupt->Next = GpeXrupt;
 281         GpeXrupt->Previous = NextGpeXrupt;
 282     }
 283     else
 284     {
 285         AcpiGbl_GpeXruptListHead = GpeXrupt;
 286     }
 287 
 288     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
 289 
 290     /* Install new interrupt handler if not SCI_INT */
 291 
 292     if (InterruptNumber != AcpiGbl_FADT.SciInterrupt)
 293     {
 294         Status = AcpiOsInstallInterruptHandler (InterruptNumber,
 295                     AcpiEvGpeXruptHandler, GpeXrupt);
 296         if (ACPI_FAILURE (Status))
 297         {
 298             ACPI_EXCEPTION ((AE_INFO, Status,
 299                 "Could not install GPE interrupt handler at level 0x%X",
 300                 InterruptNumber));
 301             return_ACPI_STATUS (Status);
 302         }
 303     }
 304 
 305     *GpeXruptBlock = GpeXrupt;
 306     return_ACPI_STATUS (AE_OK);
 307 }
 308 
 309 
 310 /*******************************************************************************
 311  *
 312  * FUNCTION:    AcpiEvDeleteGpeXrupt
 313  *
 314  * PARAMETERS:  GpeXrupt        - A GPE interrupt info block
 315  *
 316  * RETURN:      Status
 317  *
 318  * DESCRIPTION: Remove and free a GpeXrupt block. Remove an associated
 319  *              interrupt handler if not the SCI interrupt.
 320  *
 321  ******************************************************************************/
 322 
 323 ACPI_STATUS
 324 AcpiEvDeleteGpeXrupt (
 325     ACPI_GPE_XRUPT_INFO     *GpeXrupt)
 326 {


 379  *
 380  * FUNCTION:    AcpiEvDeleteGpeHandlers
 381  *
 382  * PARAMETERS:  GpeXruptInfo        - GPE Interrupt info
 383  *              GpeBlock            - Gpe Block info
 384  *
 385  * RETURN:      Status
 386  *
 387  * DESCRIPTION: Delete all Handler objects found in the GPE data structs.
 388  *              Used only prior to termination.
 389  *
 390  ******************************************************************************/
 391 
 392 ACPI_STATUS
 393 AcpiEvDeleteGpeHandlers (
 394     ACPI_GPE_XRUPT_INFO     *GpeXruptInfo,
 395     ACPI_GPE_BLOCK_INFO     *GpeBlock,
 396     void                    *Context)
 397 {
 398     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
 399     ACPI_GPE_NOTIFY_INFO    *Notify;
 400     ACPI_GPE_NOTIFY_INFO    *Next;
 401     UINT32                  i;
 402     UINT32                  j;
 403 
 404 
 405     ACPI_FUNCTION_TRACE (EvDeleteGpeHandlers);
 406 
 407 
 408     /* Examine each GPE Register within the block */
 409 
 410     for (i = 0; i < GpeBlock->RegisterCount; i++)
 411     {
 412         /* Now look at the individual GPEs in this byte register */
 413 
 414         for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++)
 415         {
 416             GpeEventInfo = &GpeBlock->EventInfo[((ACPI_SIZE) i *
 417                 ACPI_GPE_REGISTER_WIDTH) + j];
 418 
 419             if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) ==
 420                     ACPI_GPE_DISPATCH_HANDLER)
 421             {
 422                 /* Delete an installed handler block */
 423 
 424                 ACPI_FREE (GpeEventInfo->Dispatch.Handler);
 425                 GpeEventInfo->Dispatch.Handler = NULL;
 426                 GpeEventInfo->Flags &= ~ACPI_GPE_DISPATCH_MASK;
 427             }
 428             else if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) ==
 429                     ACPI_GPE_DISPATCH_NOTIFY)
 430             {
 431                 /* Delete the implicit notification device list */
 432 
 433                 Notify = GpeEventInfo->Dispatch.NotifyList;
 434                 while (Notify)
 435                 {
 436                     Next = Notify->Next;
 437                     ACPI_FREE (Notify);
 438                     Notify = Next;
 439                 }
 440                 GpeEventInfo->Dispatch.NotifyList = NULL;
 441                 GpeEventInfo->Flags &= ~ACPI_GPE_DISPATCH_MASK;
 442             }
 443         }
 444     }
 445 
 446     return_ACPI_STATUS (AE_OK);
 447 }
 448 
 449 #endif /* !ACPI_REDUCED_HARDWARE */