Home | History | Annotate | Line # | Download | only in events
evxface.c revision 1.4.20.1
      1       1.1  jruoho /******************************************************************************
      2       1.1  jruoho  *
      3       1.1  jruoho  * Module Name: evxface - External interfaces for ACPI events
      4       1.1  jruoho  *
      5       1.1  jruoho  *****************************************************************************/
      6       1.1  jruoho 
      7       1.4  jruoho /*
      8  1.4.20.1     tls  * Copyright (C) 2000 - 2013, Intel Corp.
      9       1.1  jruoho  * All rights reserved.
     10       1.1  jruoho  *
     11       1.4  jruoho  * Redistribution and use in source and binary forms, with or without
     12       1.4  jruoho  * modification, are permitted provided that the following conditions
     13       1.4  jruoho  * are met:
     14       1.4  jruoho  * 1. Redistributions of source code must retain the above copyright
     15       1.4  jruoho  *    notice, this list of conditions, and the following disclaimer,
     16       1.4  jruoho  *    without modification.
     17       1.4  jruoho  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
     18       1.4  jruoho  *    substantially similar to the "NO WARRANTY" disclaimer below
     19       1.4  jruoho  *    ("Disclaimer") and any redistribution must be conditioned upon
     20       1.4  jruoho  *    including a substantially similar Disclaimer requirement for further
     21       1.4  jruoho  *    binary redistribution.
     22       1.4  jruoho  * 3. Neither the names of the above-listed copyright holders nor the names
     23       1.4  jruoho  *    of any contributors may be used to endorse or promote products derived
     24       1.4  jruoho  *    from this software without specific prior written permission.
     25       1.4  jruoho  *
     26       1.4  jruoho  * Alternatively, this software may be distributed under the terms of the
     27       1.4  jruoho  * GNU General Public License ("GPL") version 2 as published by the Free
     28       1.4  jruoho  * Software Foundation.
     29       1.4  jruoho  *
     30       1.4  jruoho  * NO WARRANTY
     31       1.4  jruoho  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     32       1.4  jruoho  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     33       1.4  jruoho  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
     34       1.4  jruoho  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     35       1.4  jruoho  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     36       1.4  jruoho  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     37       1.4  jruoho  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     38       1.4  jruoho  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     39       1.4  jruoho  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
     40       1.4  jruoho  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     41       1.4  jruoho  * POSSIBILITY OF SUCH DAMAGES.
     42       1.4  jruoho  */
     43       1.1  jruoho 
     44       1.1  jruoho 
     45       1.1  jruoho #define __EVXFACE_C__
     46  1.4.20.1     tls #define EXPORT_ACPI_INTERFACES
     47       1.1  jruoho 
     48       1.1  jruoho #include "acpi.h"
     49       1.1  jruoho #include "accommon.h"
     50       1.1  jruoho #include "acnamesp.h"
     51       1.1  jruoho #include "acevents.h"
     52       1.1  jruoho #include "acinterp.h"
     53       1.1  jruoho 
     54       1.1  jruoho #define _COMPONENT          ACPI_EVENTS
     55       1.1  jruoho         ACPI_MODULE_NAME    ("evxface")
     56       1.1  jruoho 
     57       1.1  jruoho 
     58       1.1  jruoho /*******************************************************************************
     59       1.1  jruoho  *
     60  1.4.20.1     tls  * FUNCTION:    AcpiInstallNotifyHandler
     61  1.4.20.1     tls  *
     62  1.4.20.1     tls  * PARAMETERS:  Device          - The device for which notifies will be handled
     63  1.4.20.1     tls  *              HandlerType     - The type of handler:
     64  1.4.20.1     tls  *                                  ACPI_SYSTEM_NOTIFY: System Handler (00-7F)
     65  1.4.20.1     tls  *                                  ACPI_DEVICE_NOTIFY: Device Handler (80-FF)
     66  1.4.20.1     tls  *                                  ACPI_ALL_NOTIFY:    Both System and Device
     67  1.4.20.1     tls  *              Handler         - Address of the handler
     68  1.4.20.1     tls  *              Context         - Value passed to the handler on each GPE
     69  1.4.20.1     tls  *
     70  1.4.20.1     tls  * RETURN:      Status
     71  1.4.20.1     tls  *
     72  1.4.20.1     tls  * DESCRIPTION: Install a handler for notifications on an ACPI Device,
     73  1.4.20.1     tls  *              ThermalZone, or Processor object.
     74  1.4.20.1     tls  *
     75  1.4.20.1     tls  * NOTES:       The Root namespace object may have only one handler for each
     76  1.4.20.1     tls  *              type of notify (System/Device). Device/Thermal/Processor objects
     77  1.4.20.1     tls  *              may have one device notify handler, and multiple system notify
     78  1.4.20.1     tls  *              handlers.
     79  1.4.20.1     tls  *
     80  1.4.20.1     tls  ******************************************************************************/
     81  1.4.20.1     tls 
     82  1.4.20.1     tls ACPI_STATUS
     83  1.4.20.1     tls AcpiInstallNotifyHandler (
     84  1.4.20.1     tls     ACPI_HANDLE             Device,
     85  1.4.20.1     tls     UINT32                  HandlerType,
     86  1.4.20.1     tls     ACPI_NOTIFY_HANDLER     Handler,
     87  1.4.20.1     tls     void                    *Context)
     88  1.4.20.1     tls {
     89  1.4.20.1     tls     ACPI_NAMESPACE_NODE     *Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Device);
     90  1.4.20.1     tls     ACPI_OPERAND_OBJECT     *ObjDesc;
     91  1.4.20.1     tls     ACPI_OPERAND_OBJECT     *HandlerObj;
     92  1.4.20.1     tls     ACPI_STATUS             Status;
     93  1.4.20.1     tls     UINT32                  i;
     94  1.4.20.1     tls 
     95  1.4.20.1     tls 
     96  1.4.20.1     tls     ACPI_FUNCTION_TRACE (AcpiInstallNotifyHandler);
     97  1.4.20.1     tls 
     98  1.4.20.1     tls 
     99  1.4.20.1     tls     /* Parameter validation */
    100  1.4.20.1     tls 
    101  1.4.20.1     tls     if ((!Device) || (!Handler) || (!HandlerType) ||
    102  1.4.20.1     tls         (HandlerType > ACPI_MAX_NOTIFY_HANDLER_TYPE))
    103  1.4.20.1     tls     {
    104  1.4.20.1     tls         return_ACPI_STATUS (AE_BAD_PARAMETER);
    105  1.4.20.1     tls     }
    106  1.4.20.1     tls 
    107  1.4.20.1     tls     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
    108  1.4.20.1     tls     if (ACPI_FAILURE (Status))
    109  1.4.20.1     tls     {
    110  1.4.20.1     tls         return_ACPI_STATUS (Status);
    111  1.4.20.1     tls     }
    112  1.4.20.1     tls 
    113  1.4.20.1     tls     /*
    114  1.4.20.1     tls      * Root Object:
    115  1.4.20.1     tls      * Registering a notify handler on the root object indicates that the
    116  1.4.20.1     tls      * caller wishes to receive notifications for all objects. Note that
    117  1.4.20.1     tls      * only one global handler can be registered per notify type.
    118  1.4.20.1     tls      * Ensure that a handler is not already installed.
    119  1.4.20.1     tls      */
    120  1.4.20.1     tls     if (Device == ACPI_ROOT_OBJECT)
    121  1.4.20.1     tls     {
    122  1.4.20.1     tls         for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++)
    123  1.4.20.1     tls         {
    124  1.4.20.1     tls             if (HandlerType & (i+1))
    125  1.4.20.1     tls             {
    126  1.4.20.1     tls                 if (AcpiGbl_GlobalNotify[i].Handler)
    127  1.4.20.1     tls                 {
    128  1.4.20.1     tls                     Status = AE_ALREADY_EXISTS;
    129  1.4.20.1     tls                     goto UnlockAndExit;
    130  1.4.20.1     tls                 }
    131  1.4.20.1     tls 
    132  1.4.20.1     tls                 AcpiGbl_GlobalNotify[i].Handler = Handler;
    133  1.4.20.1     tls                 AcpiGbl_GlobalNotify[i].Context = Context;
    134  1.4.20.1     tls             }
    135  1.4.20.1     tls         }
    136  1.4.20.1     tls 
    137  1.4.20.1     tls         goto UnlockAndExit; /* Global notify handler installed, all done */
    138  1.4.20.1     tls     }
    139  1.4.20.1     tls 
    140  1.4.20.1     tls     /*
    141  1.4.20.1     tls      * All Other Objects:
    142  1.4.20.1     tls      * Caller will only receive notifications specific to the target
    143  1.4.20.1     tls      * object. Note that only certain object types are allowed to
    144  1.4.20.1     tls      * receive notifications.
    145  1.4.20.1     tls      */
    146  1.4.20.1     tls 
    147  1.4.20.1     tls     /* Are Notifies allowed on this object? */
    148  1.4.20.1     tls 
    149  1.4.20.1     tls     if (!AcpiEvIsNotifyObject (Node))
    150  1.4.20.1     tls     {
    151  1.4.20.1     tls         Status = AE_TYPE;
    152  1.4.20.1     tls         goto UnlockAndExit;
    153  1.4.20.1     tls     }
    154  1.4.20.1     tls 
    155  1.4.20.1     tls     /* Check for an existing internal object, might not exist */
    156  1.4.20.1     tls 
    157  1.4.20.1     tls     ObjDesc = AcpiNsGetAttachedObject (Node);
    158  1.4.20.1     tls     if (!ObjDesc)
    159  1.4.20.1     tls     {
    160  1.4.20.1     tls         /* Create a new object */
    161  1.4.20.1     tls 
    162  1.4.20.1     tls         ObjDesc = AcpiUtCreateInternalObject (Node->Type);
    163  1.4.20.1     tls         if (!ObjDesc)
    164  1.4.20.1     tls         {
    165  1.4.20.1     tls             Status = AE_NO_MEMORY;
    166  1.4.20.1     tls             goto UnlockAndExit;
    167  1.4.20.1     tls         }
    168  1.4.20.1     tls 
    169  1.4.20.1     tls         /* Attach new object to the Node, remove local reference */
    170  1.4.20.1     tls 
    171  1.4.20.1     tls         Status = AcpiNsAttachObject (Device, ObjDesc, Node->Type);
    172  1.4.20.1     tls         AcpiUtRemoveReference (ObjDesc);
    173  1.4.20.1     tls         if (ACPI_FAILURE (Status))
    174  1.4.20.1     tls         {
    175  1.4.20.1     tls             goto UnlockAndExit;
    176  1.4.20.1     tls         }
    177  1.4.20.1     tls     }
    178  1.4.20.1     tls 
    179  1.4.20.1     tls     /* Ensure that the handler is not already installed in the lists */
    180  1.4.20.1     tls 
    181  1.4.20.1     tls     for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++)
    182  1.4.20.1     tls     {
    183  1.4.20.1     tls         if (HandlerType & (i+1))
    184  1.4.20.1     tls         {
    185  1.4.20.1     tls             HandlerObj = ObjDesc->CommonNotify.NotifyList[i];
    186  1.4.20.1     tls             while (HandlerObj)
    187  1.4.20.1     tls             {
    188  1.4.20.1     tls                 if (HandlerObj->Notify.Handler == Handler)
    189  1.4.20.1     tls                 {
    190  1.4.20.1     tls                     Status = AE_ALREADY_EXISTS;
    191  1.4.20.1     tls                     goto UnlockAndExit;
    192  1.4.20.1     tls                 }
    193  1.4.20.1     tls 
    194  1.4.20.1     tls                 HandlerObj = HandlerObj->Notify.Next[i];
    195  1.4.20.1     tls             }
    196  1.4.20.1     tls         }
    197  1.4.20.1     tls     }
    198  1.4.20.1     tls 
    199  1.4.20.1     tls     /* Create and populate a new notify handler object */
    200  1.4.20.1     tls 
    201  1.4.20.1     tls     HandlerObj = AcpiUtCreateInternalObject (ACPI_TYPE_LOCAL_NOTIFY);
    202  1.4.20.1     tls     if (!HandlerObj)
    203  1.4.20.1     tls     {
    204  1.4.20.1     tls         Status = AE_NO_MEMORY;
    205  1.4.20.1     tls         goto UnlockAndExit;
    206  1.4.20.1     tls     }
    207  1.4.20.1     tls 
    208  1.4.20.1     tls     HandlerObj->Notify.Node = Node;
    209  1.4.20.1     tls     HandlerObj->Notify.HandlerType = HandlerType;
    210  1.4.20.1     tls     HandlerObj->Notify.Handler = Handler;
    211  1.4.20.1     tls     HandlerObj->Notify.Context = Context;
    212  1.4.20.1     tls 
    213  1.4.20.1     tls     /* Install the handler at the list head(s) */
    214  1.4.20.1     tls 
    215  1.4.20.1     tls     for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++)
    216  1.4.20.1     tls     {
    217  1.4.20.1     tls         if (HandlerType & (i+1))
    218  1.4.20.1     tls         {
    219  1.4.20.1     tls             HandlerObj->Notify.Next[i] =
    220  1.4.20.1     tls                 ObjDesc->CommonNotify.NotifyList[i];
    221  1.4.20.1     tls 
    222  1.4.20.1     tls             ObjDesc->CommonNotify.NotifyList[i] = HandlerObj;
    223  1.4.20.1     tls         }
    224  1.4.20.1     tls     }
    225  1.4.20.1     tls 
    226  1.4.20.1     tls     /* Add an extra reference if handler was installed in both lists */
    227  1.4.20.1     tls 
    228  1.4.20.1     tls     if (HandlerType == ACPI_ALL_NOTIFY)
    229  1.4.20.1     tls     {
    230  1.4.20.1     tls         AcpiUtAddReference (HandlerObj);
    231  1.4.20.1     tls     }
    232  1.4.20.1     tls 
    233  1.4.20.1     tls 
    234  1.4.20.1     tls UnlockAndExit:
    235  1.4.20.1     tls     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
    236  1.4.20.1     tls     return_ACPI_STATUS (Status);
    237  1.4.20.1     tls }
    238  1.4.20.1     tls 
    239  1.4.20.1     tls ACPI_EXPORT_SYMBOL (AcpiInstallNotifyHandler)
    240  1.4.20.1     tls 
    241  1.4.20.1     tls 
    242  1.4.20.1     tls /*******************************************************************************
    243  1.4.20.1     tls  *
    244  1.4.20.1     tls  * FUNCTION:    AcpiRemoveNotifyHandler
    245  1.4.20.1     tls  *
    246  1.4.20.1     tls  * PARAMETERS:  Device          - The device for which the handler is installed
    247  1.4.20.1     tls  *              HandlerType     - The type of handler:
    248  1.4.20.1     tls  *                                  ACPI_SYSTEM_NOTIFY: System Handler (00-7F)
    249  1.4.20.1     tls  *                                  ACPI_DEVICE_NOTIFY: Device Handler (80-FF)
    250  1.4.20.1     tls  *                                  ACPI_ALL_NOTIFY:    Both System and Device
    251  1.4.20.1     tls  *              Handler         - Address of the handler
    252  1.4.20.1     tls  *
    253  1.4.20.1     tls  * RETURN:      Status
    254  1.4.20.1     tls  *
    255  1.4.20.1     tls  * DESCRIPTION: Remove a handler for notifies on an ACPI device
    256  1.4.20.1     tls  *
    257  1.4.20.1     tls  ******************************************************************************/
    258  1.4.20.1     tls 
    259  1.4.20.1     tls ACPI_STATUS
    260  1.4.20.1     tls AcpiRemoveNotifyHandler (
    261  1.4.20.1     tls     ACPI_HANDLE             Device,
    262  1.4.20.1     tls     UINT32                  HandlerType,
    263  1.4.20.1     tls     ACPI_NOTIFY_HANDLER     Handler)
    264  1.4.20.1     tls {
    265  1.4.20.1     tls     ACPI_NAMESPACE_NODE     *Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Device);
    266  1.4.20.1     tls     ACPI_OPERAND_OBJECT     *ObjDesc;
    267  1.4.20.1     tls     ACPI_OPERAND_OBJECT     *HandlerObj;
    268  1.4.20.1     tls     ACPI_OPERAND_OBJECT     *PreviousHandlerObj;
    269  1.4.20.1     tls     ACPI_STATUS             Status;
    270  1.4.20.1     tls     UINT32                  i;
    271  1.4.20.1     tls 
    272  1.4.20.1     tls 
    273  1.4.20.1     tls     ACPI_FUNCTION_TRACE (AcpiRemoveNotifyHandler);
    274  1.4.20.1     tls 
    275  1.4.20.1     tls 
    276  1.4.20.1     tls     /* Parameter validation */
    277  1.4.20.1     tls 
    278  1.4.20.1     tls     if ((!Device) || (!Handler) || (!HandlerType) ||
    279  1.4.20.1     tls         (HandlerType > ACPI_MAX_NOTIFY_HANDLER_TYPE))
    280  1.4.20.1     tls     {
    281  1.4.20.1     tls         return_ACPI_STATUS (AE_BAD_PARAMETER);
    282  1.4.20.1     tls     }
    283  1.4.20.1     tls 
    284  1.4.20.1     tls     /* Make sure all deferred notify tasks are completed */
    285  1.4.20.1     tls 
    286  1.4.20.1     tls     AcpiOsWaitEventsComplete ();
    287  1.4.20.1     tls 
    288  1.4.20.1     tls     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
    289  1.4.20.1     tls     if (ACPI_FAILURE (Status))
    290  1.4.20.1     tls     {
    291  1.4.20.1     tls         return_ACPI_STATUS (Status);
    292  1.4.20.1     tls     }
    293  1.4.20.1     tls 
    294  1.4.20.1     tls     /* Root Object. Global handlers are removed here */
    295  1.4.20.1     tls 
    296  1.4.20.1     tls     if (Device == ACPI_ROOT_OBJECT)
    297  1.4.20.1     tls     {
    298  1.4.20.1     tls         for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++)
    299  1.4.20.1     tls         {
    300  1.4.20.1     tls             if (HandlerType & (i+1))
    301  1.4.20.1     tls             {
    302  1.4.20.1     tls                 if (!AcpiGbl_GlobalNotify[i].Handler ||
    303  1.4.20.1     tls                     (AcpiGbl_GlobalNotify[i].Handler != Handler))
    304  1.4.20.1     tls                 {
    305  1.4.20.1     tls                     Status = AE_NOT_EXIST;
    306  1.4.20.1     tls                     goto UnlockAndExit;
    307  1.4.20.1     tls                 }
    308  1.4.20.1     tls 
    309  1.4.20.1     tls                 ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
    310  1.4.20.1     tls                     "Removing global notify handler\n"));
    311  1.4.20.1     tls 
    312  1.4.20.1     tls                 AcpiGbl_GlobalNotify[i].Handler = NULL;
    313  1.4.20.1     tls                 AcpiGbl_GlobalNotify[i].Context = NULL;
    314  1.4.20.1     tls             }
    315  1.4.20.1     tls         }
    316  1.4.20.1     tls 
    317  1.4.20.1     tls         goto UnlockAndExit;
    318  1.4.20.1     tls     }
    319  1.4.20.1     tls 
    320  1.4.20.1     tls     /* All other objects: Are Notifies allowed on this object? */
    321  1.4.20.1     tls 
    322  1.4.20.1     tls     if (!AcpiEvIsNotifyObject (Node))
    323  1.4.20.1     tls     {
    324  1.4.20.1     tls         Status = AE_TYPE;
    325  1.4.20.1     tls         goto UnlockAndExit;
    326  1.4.20.1     tls     }
    327  1.4.20.1     tls 
    328  1.4.20.1     tls     /* Must have an existing internal object */
    329  1.4.20.1     tls 
    330  1.4.20.1     tls     ObjDesc = AcpiNsGetAttachedObject (Node);
    331  1.4.20.1     tls     if (!ObjDesc)
    332  1.4.20.1     tls     {
    333  1.4.20.1     tls         Status = AE_NOT_EXIST;
    334  1.4.20.1     tls         goto UnlockAndExit;
    335  1.4.20.1     tls     }
    336  1.4.20.1     tls 
    337  1.4.20.1     tls     /* Internal object exists. Find the handler and remove it */
    338  1.4.20.1     tls 
    339  1.4.20.1     tls     for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++)
    340  1.4.20.1     tls     {
    341  1.4.20.1     tls         if (HandlerType & (i+1))
    342  1.4.20.1     tls         {
    343  1.4.20.1     tls             HandlerObj = ObjDesc->CommonNotify.NotifyList[i];
    344  1.4.20.1     tls             PreviousHandlerObj = NULL;
    345  1.4.20.1     tls 
    346  1.4.20.1     tls             /* Attempt to find the handler in the handler list */
    347  1.4.20.1     tls 
    348  1.4.20.1     tls             while (HandlerObj &&
    349  1.4.20.1     tls                   (HandlerObj->Notify.Handler != Handler))
    350  1.4.20.1     tls             {
    351  1.4.20.1     tls                 PreviousHandlerObj = HandlerObj;
    352  1.4.20.1     tls                 HandlerObj = HandlerObj->Notify.Next[i];
    353  1.4.20.1     tls             }
    354  1.4.20.1     tls 
    355  1.4.20.1     tls             if (!HandlerObj)
    356  1.4.20.1     tls             {
    357  1.4.20.1     tls                 Status = AE_NOT_EXIST;
    358  1.4.20.1     tls                 goto UnlockAndExit;
    359  1.4.20.1     tls             }
    360  1.4.20.1     tls 
    361  1.4.20.1     tls             /* Remove the handler object from the list */
    362  1.4.20.1     tls 
    363  1.4.20.1     tls             if (PreviousHandlerObj) /* Handler is not at the list head */
    364  1.4.20.1     tls             {
    365  1.4.20.1     tls                 PreviousHandlerObj->Notify.Next[i] =
    366  1.4.20.1     tls                     HandlerObj->Notify.Next[i];
    367  1.4.20.1     tls             }
    368  1.4.20.1     tls             else /* Handler is at the list head */
    369  1.4.20.1     tls             {
    370  1.4.20.1     tls                 ObjDesc->CommonNotify.NotifyList[i] =
    371  1.4.20.1     tls                     HandlerObj->Notify.Next[i];
    372  1.4.20.1     tls             }
    373  1.4.20.1     tls 
    374  1.4.20.1     tls             AcpiUtRemoveReference (HandlerObj);
    375  1.4.20.1     tls         }
    376  1.4.20.1     tls     }
    377  1.4.20.1     tls 
    378  1.4.20.1     tls 
    379  1.4.20.1     tls UnlockAndExit:
    380  1.4.20.1     tls     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
    381  1.4.20.1     tls     return_ACPI_STATUS (Status);
    382  1.4.20.1     tls }
    383  1.4.20.1     tls 
    384  1.4.20.1     tls ACPI_EXPORT_SYMBOL (AcpiRemoveNotifyHandler)
    385  1.4.20.1     tls 
    386  1.4.20.1     tls 
    387  1.4.20.1     tls /*******************************************************************************
    388  1.4.20.1     tls  *
    389       1.1  jruoho  * FUNCTION:    AcpiInstallExceptionHandler
    390       1.1  jruoho  *
    391       1.1  jruoho  * PARAMETERS:  Handler         - Pointer to the handler function for the
    392       1.1  jruoho  *                                event
    393       1.1  jruoho  *
    394       1.1  jruoho  * RETURN:      Status
    395       1.1  jruoho  *
    396       1.1  jruoho  * DESCRIPTION: Saves the pointer to the handler function
    397       1.1  jruoho  *
    398       1.1  jruoho  ******************************************************************************/
    399       1.1  jruoho 
    400       1.1  jruoho ACPI_STATUS
    401       1.1  jruoho AcpiInstallExceptionHandler (
    402       1.1  jruoho     ACPI_EXCEPTION_HANDLER  Handler)
    403       1.1  jruoho {
    404       1.1  jruoho     ACPI_STATUS             Status;
    405       1.1  jruoho 
    406       1.1  jruoho 
    407       1.1  jruoho     ACPI_FUNCTION_TRACE (AcpiInstallExceptionHandler);
    408       1.1  jruoho 
    409       1.1  jruoho 
    410       1.1  jruoho     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
    411       1.1  jruoho     if (ACPI_FAILURE (Status))
    412       1.1  jruoho     {
    413       1.1  jruoho         return_ACPI_STATUS (Status);
    414       1.1  jruoho     }
    415       1.1  jruoho 
    416       1.1  jruoho     /* Don't allow two handlers. */
    417       1.1  jruoho 
    418  1.4.20.1     tls     if (AcpiGbl_ExceptionHandler)
    419  1.4.20.1     tls     {
    420  1.4.20.1     tls         Status = AE_ALREADY_EXISTS;
    421  1.4.20.1     tls         goto Cleanup;
    422  1.4.20.1     tls     }
    423  1.4.20.1     tls 
    424  1.4.20.1     tls     /* Install the handler */
    425  1.4.20.1     tls 
    426  1.4.20.1     tls     AcpiGbl_ExceptionHandler = Handler;
    427  1.4.20.1     tls 
    428  1.4.20.1     tls Cleanup:
    429  1.4.20.1     tls     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
    430  1.4.20.1     tls     return_ACPI_STATUS (Status);
    431  1.4.20.1     tls }
    432  1.4.20.1     tls 
    433  1.4.20.1     tls ACPI_EXPORT_SYMBOL (AcpiInstallExceptionHandler)
    434  1.4.20.1     tls 
    435  1.4.20.1     tls 
    436  1.4.20.1     tls #if (!ACPI_REDUCED_HARDWARE)
    437  1.4.20.1     tls /*******************************************************************************
    438  1.4.20.1     tls  *
    439  1.4.20.1     tls  * FUNCTION:    AcpiInstallSciHandler
    440  1.4.20.1     tls  *
    441  1.4.20.1     tls  * PARAMETERS:  Address             - Address of the handler
    442  1.4.20.1     tls  *              Context             - Value passed to the handler on each SCI
    443  1.4.20.1     tls  *
    444  1.4.20.1     tls  * RETURN:      Status
    445  1.4.20.1     tls  *
    446  1.4.20.1     tls  * DESCRIPTION: Install a handler for a System Control Interrupt.
    447  1.4.20.1     tls  *
    448  1.4.20.1     tls  ******************************************************************************/
    449  1.4.20.1     tls 
    450  1.4.20.1     tls ACPI_STATUS
    451  1.4.20.1     tls AcpiInstallSciHandler (
    452  1.4.20.1     tls     ACPI_SCI_HANDLER        Address,
    453  1.4.20.1     tls     void                    *Context)
    454  1.4.20.1     tls {
    455  1.4.20.1     tls     ACPI_SCI_HANDLER_INFO   *NewSciHandler;
    456  1.4.20.1     tls     ACPI_SCI_HANDLER_INFO   *SciHandler;
    457  1.4.20.1     tls     ACPI_CPU_FLAGS          Flags;
    458  1.4.20.1     tls     ACPI_STATUS             Status;
    459  1.4.20.1     tls 
    460  1.4.20.1     tls 
    461  1.4.20.1     tls     ACPI_FUNCTION_TRACE (AcpiInstallSciHandler);
    462  1.4.20.1     tls 
    463  1.4.20.1     tls 
    464  1.4.20.1     tls     if (!Address)
    465  1.4.20.1     tls     {
    466  1.4.20.1     tls         return_ACPI_STATUS (AE_BAD_PARAMETER);
    467  1.4.20.1     tls     }
    468  1.4.20.1     tls 
    469  1.4.20.1     tls     /* Allocate and init a handler object */
    470  1.4.20.1     tls 
    471  1.4.20.1     tls     NewSciHandler = ACPI_ALLOCATE (sizeof (ACPI_SCI_HANDLER_INFO));
    472  1.4.20.1     tls     if (!NewSciHandler)
    473  1.4.20.1     tls     {
    474  1.4.20.1     tls         return_ACPI_STATUS (AE_NO_MEMORY);
    475  1.4.20.1     tls     }
    476  1.4.20.1     tls 
    477  1.4.20.1     tls     NewSciHandler->Address = Address;
    478  1.4.20.1     tls     NewSciHandler->Context = Context;
    479  1.4.20.1     tls 
    480  1.4.20.1     tls     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
    481  1.4.20.1     tls     if (ACPI_FAILURE (Status))
    482  1.4.20.1     tls     {
    483  1.4.20.1     tls         goto Exit;
    484  1.4.20.1     tls     }
    485  1.4.20.1     tls 
    486  1.4.20.1     tls     /* Lock list during installation */
    487  1.4.20.1     tls 
    488  1.4.20.1     tls     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
    489  1.4.20.1     tls     SciHandler = AcpiGbl_SciHandlerList;
    490  1.4.20.1     tls 
    491  1.4.20.1     tls     /* Ensure handler does not already exist */
    492  1.4.20.1     tls 
    493  1.4.20.1     tls     while (SciHandler)
    494  1.4.20.1     tls     {
    495  1.4.20.1     tls         if (Address == SciHandler->Address)
    496  1.4.20.1     tls         {
    497  1.4.20.1     tls             Status = AE_ALREADY_EXISTS;
    498  1.4.20.1     tls             goto UnlockAndExit;
    499  1.4.20.1     tls         }
    500  1.4.20.1     tls 
    501  1.4.20.1     tls         SciHandler = SciHandler->Next;
    502  1.4.20.1     tls     }
    503  1.4.20.1     tls 
    504  1.4.20.1     tls     /* Install the new handler into the global list (at head) */
    505  1.4.20.1     tls 
    506  1.4.20.1     tls     NewSciHandler->Next = AcpiGbl_SciHandlerList;
    507  1.4.20.1     tls     AcpiGbl_SciHandlerList = NewSciHandler;
    508  1.4.20.1     tls 
    509  1.4.20.1     tls 
    510  1.4.20.1     tls UnlockAndExit:
    511  1.4.20.1     tls 
    512  1.4.20.1     tls     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
    513  1.4.20.1     tls     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
    514  1.4.20.1     tls 
    515  1.4.20.1     tls Exit:
    516  1.4.20.1     tls     if (ACPI_FAILURE (Status))
    517  1.4.20.1     tls     {
    518  1.4.20.1     tls         ACPI_FREE (NewSciHandler);
    519  1.4.20.1     tls     }
    520  1.4.20.1     tls     return_ACPI_STATUS (Status);
    521  1.4.20.1     tls }
    522  1.4.20.1     tls 
    523  1.4.20.1     tls 
    524  1.4.20.1     tls /*******************************************************************************
    525  1.4.20.1     tls  *
    526  1.4.20.1     tls  * FUNCTION:    AcpiRemoveSciHandler
    527  1.4.20.1     tls  *
    528  1.4.20.1     tls  * PARAMETERS:  Address             - Address of the handler
    529  1.4.20.1     tls  *
    530  1.4.20.1     tls  * RETURN:      Status
    531  1.4.20.1     tls  *
    532  1.4.20.1     tls  * DESCRIPTION: Remove a handler for a System Control Interrupt.
    533  1.4.20.1     tls  *
    534  1.4.20.1     tls  ******************************************************************************/
    535  1.4.20.1     tls 
    536  1.4.20.1     tls ACPI_STATUS
    537  1.4.20.1     tls AcpiRemoveSciHandler (
    538  1.4.20.1     tls     ACPI_SCI_HANDLER        Address)
    539  1.4.20.1     tls {
    540  1.4.20.1     tls     ACPI_SCI_HANDLER_INFO   *PrevSciHandler;
    541  1.4.20.1     tls     ACPI_SCI_HANDLER_INFO   *NextSciHandler;
    542  1.4.20.1     tls     ACPI_CPU_FLAGS          Flags;
    543  1.4.20.1     tls     ACPI_STATUS             Status;
    544  1.4.20.1     tls 
    545  1.4.20.1     tls 
    546  1.4.20.1     tls     ACPI_FUNCTION_TRACE (AcpiRemoveSciHandler);
    547  1.4.20.1     tls 
    548  1.4.20.1     tls 
    549  1.4.20.1     tls     if (!Address)
    550  1.4.20.1     tls     {
    551  1.4.20.1     tls         return_ACPI_STATUS (AE_BAD_PARAMETER);
    552  1.4.20.1     tls     }
    553  1.4.20.1     tls 
    554  1.4.20.1     tls     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
    555  1.4.20.1     tls     if (ACPI_FAILURE (Status))
    556  1.4.20.1     tls     {
    557  1.4.20.1     tls         return_ACPI_STATUS (Status);
    558  1.4.20.1     tls     }
    559  1.4.20.1     tls 
    560  1.4.20.1     tls     /* Remove the SCI handler with lock */
    561  1.4.20.1     tls 
    562  1.4.20.1     tls     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
    563  1.4.20.1     tls 
    564  1.4.20.1     tls     PrevSciHandler = NULL;
    565  1.4.20.1     tls     NextSciHandler = AcpiGbl_SciHandlerList;
    566  1.4.20.1     tls     while (NextSciHandler)
    567  1.4.20.1     tls     {
    568  1.4.20.1     tls         if (NextSciHandler->Address == Address)
    569  1.4.20.1     tls         {
    570  1.4.20.1     tls             /* Unlink and free the SCI handler info block */
    571  1.4.20.1     tls 
    572  1.4.20.1     tls             if (PrevSciHandler)
    573  1.4.20.1     tls             {
    574  1.4.20.1     tls                 PrevSciHandler->Next = NextSciHandler->Next;
    575  1.4.20.1     tls             }
    576  1.4.20.1     tls             else
    577  1.4.20.1     tls             {
    578  1.4.20.1     tls                 AcpiGbl_SciHandlerList = NextSciHandler->Next;
    579  1.4.20.1     tls             }
    580  1.4.20.1     tls 
    581  1.4.20.1     tls             AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
    582  1.4.20.1     tls             ACPI_FREE (NextSciHandler);
    583  1.4.20.1     tls             goto UnlockAndExit;
    584  1.4.20.1     tls         }
    585  1.4.20.1     tls 
    586  1.4.20.1     tls         PrevSciHandler = NextSciHandler;
    587  1.4.20.1     tls         NextSciHandler = NextSciHandler->Next;
    588       1.1  jruoho     }
    589       1.1  jruoho 
    590  1.4.20.1     tls     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
    591  1.4.20.1     tls     Status = AE_NOT_EXIST;
    592       1.1  jruoho 
    593       1.1  jruoho 
    594  1.4.20.1     tls UnlockAndExit:
    595       1.1  jruoho     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
    596       1.1  jruoho     return_ACPI_STATUS (Status);
    597       1.1  jruoho }
    598       1.1  jruoho 
    599       1.1  jruoho 
    600       1.1  jruoho /*******************************************************************************
    601       1.1  jruoho  *
    602       1.4  jruoho  * FUNCTION:    AcpiInstallGlobalEventHandler
    603       1.4  jruoho  *
    604       1.4  jruoho  * PARAMETERS:  Handler         - Pointer to the global event handler function
    605       1.4  jruoho  *              Context         - Value passed to the handler on each event
    606       1.4  jruoho  *
    607       1.4  jruoho  * RETURN:      Status
    608       1.4  jruoho  *
    609       1.4  jruoho  * DESCRIPTION: Saves the pointer to the handler function. The global handler
    610       1.4  jruoho  *              is invoked upon each incoming GPE and Fixed Event. It is
    611       1.4  jruoho  *              invoked at interrupt level at the time of the event dispatch.
    612       1.4  jruoho  *              Can be used to update event counters, etc.
    613       1.4  jruoho  *
    614       1.4  jruoho  ******************************************************************************/
    615       1.4  jruoho 
    616       1.4  jruoho ACPI_STATUS
    617       1.4  jruoho AcpiInstallGlobalEventHandler (
    618       1.4  jruoho     ACPI_GBL_EVENT_HANDLER  Handler,
    619       1.4  jruoho     void                    *Context)
    620       1.4  jruoho {
    621       1.4  jruoho     ACPI_STATUS             Status;
    622       1.4  jruoho 
    623       1.4  jruoho 
    624       1.4  jruoho     ACPI_FUNCTION_TRACE (AcpiInstallGlobalEventHandler);
    625       1.4  jruoho 
    626       1.4  jruoho 
    627       1.4  jruoho     /* Parameter validation */
    628       1.4  jruoho 
    629       1.4  jruoho     if (!Handler)
    630       1.4  jruoho     {
    631       1.4  jruoho         return_ACPI_STATUS (AE_BAD_PARAMETER);
    632       1.4  jruoho     }
    633       1.4  jruoho 
    634       1.4  jruoho     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
    635       1.4  jruoho     if (ACPI_FAILURE (Status))
    636       1.4  jruoho     {
    637       1.4  jruoho         return_ACPI_STATUS (Status);
    638       1.4  jruoho     }
    639       1.4  jruoho 
    640       1.4  jruoho     /* Don't allow two handlers. */
    641       1.4  jruoho 
    642       1.4  jruoho     if (AcpiGbl_GlobalEventHandler)
    643       1.4  jruoho     {
    644       1.4  jruoho         Status = AE_ALREADY_EXISTS;
    645       1.4  jruoho         goto Cleanup;
    646       1.4  jruoho     }
    647       1.4  jruoho 
    648       1.4  jruoho     AcpiGbl_GlobalEventHandler = Handler;
    649       1.4  jruoho     AcpiGbl_GlobalEventHandlerContext = Context;
    650       1.4  jruoho 
    651       1.4  jruoho 
    652       1.4  jruoho Cleanup:
    653       1.4  jruoho     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
    654       1.4  jruoho     return_ACPI_STATUS (Status);
    655       1.4  jruoho }
    656       1.4  jruoho 
    657       1.4  jruoho ACPI_EXPORT_SYMBOL (AcpiInstallGlobalEventHandler)
    658       1.4  jruoho 
    659       1.4  jruoho 
    660       1.4  jruoho /*******************************************************************************
    661       1.4  jruoho  *
    662       1.1  jruoho  * FUNCTION:    AcpiInstallFixedEventHandler
    663       1.1  jruoho  *
    664       1.1  jruoho  * PARAMETERS:  Event           - Event type to enable.
    665       1.1  jruoho  *              Handler         - Pointer to the handler function for the
    666       1.1  jruoho  *                                event
    667       1.1  jruoho  *              Context         - Value passed to the handler on each GPE
    668       1.1  jruoho  *
    669       1.1  jruoho  * RETURN:      Status
    670       1.1  jruoho  *
    671       1.1  jruoho  * DESCRIPTION: Saves the pointer to the handler function and then enables the
    672       1.1  jruoho  *              event.
    673       1.1  jruoho  *
    674       1.1  jruoho  ******************************************************************************/
    675       1.1  jruoho 
    676       1.1  jruoho ACPI_STATUS
    677       1.1  jruoho AcpiInstallFixedEventHandler (
    678       1.1  jruoho     UINT32                  Event,
    679       1.1  jruoho     ACPI_EVENT_HANDLER      Handler,
    680       1.1  jruoho     void                    *Context)
    681       1.1  jruoho {
    682       1.1  jruoho     ACPI_STATUS             Status;
    683       1.1  jruoho 
    684       1.1  jruoho 
    685       1.1  jruoho     ACPI_FUNCTION_TRACE (AcpiInstallFixedEventHandler);
    686       1.1  jruoho 
    687       1.1  jruoho 
    688       1.1  jruoho     /* Parameter validation */
    689       1.1  jruoho 
    690       1.1  jruoho     if (Event > ACPI_EVENT_MAX)
    691       1.1  jruoho     {
    692       1.1  jruoho         return_ACPI_STATUS (AE_BAD_PARAMETER);
    693       1.1  jruoho     }
    694       1.1  jruoho 
    695       1.1  jruoho     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
    696       1.1  jruoho     if (ACPI_FAILURE (Status))
    697       1.1  jruoho     {
    698       1.1  jruoho         return_ACPI_STATUS (Status);
    699       1.1  jruoho     }
    700       1.1  jruoho 
    701  1.4.20.1     tls     /* Do not allow multiple handlers */
    702       1.1  jruoho 
    703  1.4.20.1     tls     if (AcpiGbl_FixedEventHandlers[Event].Handler)
    704       1.1  jruoho     {
    705       1.1  jruoho         Status = AE_ALREADY_EXISTS;
    706       1.1  jruoho         goto Cleanup;
    707       1.1  jruoho     }
    708       1.1  jruoho 
    709       1.1  jruoho     /* Install the handler before enabling the event */
    710       1.1  jruoho 
    711       1.1  jruoho     AcpiGbl_FixedEventHandlers[Event].Handler = Handler;
    712       1.1  jruoho     AcpiGbl_FixedEventHandlers[Event].Context = Context;
    713       1.1  jruoho 
    714       1.1  jruoho     Status = AcpiEnableEvent (Event, 0);
    715       1.1  jruoho     if (ACPI_FAILURE (Status))
    716       1.1  jruoho     {
    717  1.4.20.1     tls         ACPI_WARNING ((AE_INFO,
    718  1.4.20.1     tls             "Could not enable fixed event - %s (%u)",
    719  1.4.20.1     tls             AcpiUtGetEventName (Event), Event));
    720       1.1  jruoho 
    721       1.1  jruoho         /* Remove the handler */
    722       1.1  jruoho 
    723       1.1  jruoho         AcpiGbl_FixedEventHandlers[Event].Handler = NULL;
    724       1.1  jruoho         AcpiGbl_FixedEventHandlers[Event].Context = NULL;
    725       1.1  jruoho     }
    726       1.1  jruoho     else
    727       1.1  jruoho     {
    728       1.1  jruoho         ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
    729  1.4.20.1     tls             "Enabled fixed event %s (%X), Handler=%p\n",
    730  1.4.20.1     tls             AcpiUtGetEventName (Event), Event, Handler));
    731       1.1  jruoho     }
    732       1.1  jruoho 
    733       1.1  jruoho 
    734       1.1  jruoho Cleanup:
    735       1.1  jruoho     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
    736       1.1  jruoho     return_ACPI_STATUS (Status);
    737       1.1  jruoho }
    738       1.1  jruoho 
    739       1.1  jruoho ACPI_EXPORT_SYMBOL (AcpiInstallFixedEventHandler)
    740       1.1  jruoho 
    741       1.1  jruoho 
    742       1.1  jruoho /*******************************************************************************
    743       1.1  jruoho  *
    744       1.1  jruoho  * FUNCTION:    AcpiRemoveFixedEventHandler
    745       1.1  jruoho  *
    746       1.1  jruoho  * PARAMETERS:  Event           - Event type to disable.
    747       1.1  jruoho  *              Handler         - Address of the handler
    748       1.1  jruoho  *
    749       1.1  jruoho  * RETURN:      Status
    750       1.1  jruoho  *
    751       1.1  jruoho  * DESCRIPTION: Disables the event and unregisters the event handler.
    752       1.1  jruoho  *
    753       1.1  jruoho  ******************************************************************************/
    754       1.1  jruoho 
    755       1.1  jruoho ACPI_STATUS
    756       1.1  jruoho AcpiRemoveFixedEventHandler (
    757       1.1  jruoho     UINT32                  Event,
    758       1.1  jruoho     ACPI_EVENT_HANDLER      Handler)
    759       1.1  jruoho {
    760       1.1  jruoho     ACPI_STATUS             Status = AE_OK;
    761       1.1  jruoho 
    762       1.1  jruoho 
    763       1.1  jruoho     ACPI_FUNCTION_TRACE (AcpiRemoveFixedEventHandler);
    764       1.1  jruoho 
    765       1.1  jruoho 
    766       1.1  jruoho     /* Parameter validation */
    767       1.1  jruoho 
    768       1.1  jruoho     if (Event > ACPI_EVENT_MAX)
    769       1.1  jruoho     {
    770       1.1  jruoho         return_ACPI_STATUS (AE_BAD_PARAMETER);
    771       1.1  jruoho     }
    772       1.1  jruoho 
    773       1.1  jruoho     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
    774       1.1  jruoho     if (ACPI_FAILURE (Status))
    775       1.1  jruoho     {
    776       1.1  jruoho         return_ACPI_STATUS (Status);
    777       1.1  jruoho     }
    778       1.1  jruoho 
    779       1.1  jruoho     /* Disable the event before removing the handler */
    780       1.1  jruoho 
    781       1.1  jruoho     Status = AcpiDisableEvent (Event, 0);
    782       1.1  jruoho 
    783       1.1  jruoho     /* Always Remove the handler */
    784       1.1  jruoho 
    785       1.1  jruoho     AcpiGbl_FixedEventHandlers[Event].Handler = NULL;
    786       1.1  jruoho     AcpiGbl_FixedEventHandlers[Event].Context = NULL;
    787       1.1  jruoho 
    788       1.1  jruoho     if (ACPI_FAILURE (Status))
    789       1.1  jruoho     {
    790       1.1  jruoho         ACPI_WARNING ((AE_INFO,
    791  1.4.20.1     tls             "Could not disable fixed event - %s (%u)",
    792  1.4.20.1     tls             AcpiUtGetEventName (Event), Event));
    793       1.1  jruoho     }
    794       1.1  jruoho     else
    795       1.1  jruoho     {
    796  1.4.20.1     tls         ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
    797  1.4.20.1     tls             "Disabled fixed event - %s (%X)\n",
    798  1.4.20.1     tls             AcpiUtGetEventName (Event), Event));
    799       1.1  jruoho     }
    800       1.1  jruoho 
    801       1.1  jruoho     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
    802       1.1  jruoho     return_ACPI_STATUS (Status);
    803       1.1  jruoho }
    804       1.1  jruoho 
    805       1.1  jruoho ACPI_EXPORT_SYMBOL (AcpiRemoveFixedEventHandler)
    806       1.1  jruoho 
    807       1.1  jruoho 
    808       1.1  jruoho /*******************************************************************************
    809       1.1  jruoho  *
    810       1.1  jruoho  * FUNCTION:    AcpiInstallGpeHandler
    811       1.1  jruoho  *
    812       1.1  jruoho  * PARAMETERS:  GpeDevice       - Namespace node for the GPE (NULL for FADT
    813       1.1  jruoho  *                                defined GPEs)
    814       1.1  jruoho  *              GpeNumber       - The GPE number within the GPE block
    815       1.1  jruoho  *              Type            - Whether this GPE should be treated as an
    816       1.1  jruoho  *                                edge- or level-triggered interrupt.
    817       1.1  jruoho  *              Address         - Address of the handler
    818       1.1  jruoho  *              Context         - Value passed to the handler on each GPE
    819       1.1  jruoho  *
    820       1.1  jruoho  * RETURN:      Status
    821       1.1  jruoho  *
    822       1.1  jruoho  * DESCRIPTION: Install a handler for a General Purpose Event.
    823       1.1  jruoho  *
    824       1.1  jruoho  ******************************************************************************/
    825       1.1  jruoho 
    826       1.1  jruoho ACPI_STATUS
    827       1.1  jruoho AcpiInstallGpeHandler (
    828       1.1  jruoho     ACPI_HANDLE             GpeDevice,
    829       1.1  jruoho     UINT32                  GpeNumber,
    830       1.1  jruoho     UINT32                  Type,
    831       1.4  jruoho     ACPI_GPE_HANDLER        Address,
    832       1.1  jruoho     void                    *Context)
    833       1.1  jruoho {
    834       1.1  jruoho     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
    835       1.4  jruoho     ACPI_GPE_HANDLER_INFO   *Handler;
    836       1.1  jruoho     ACPI_STATUS             Status;
    837       1.1  jruoho     ACPI_CPU_FLAGS          Flags;
    838       1.1  jruoho 
    839       1.1  jruoho 
    840       1.1  jruoho     ACPI_FUNCTION_TRACE (AcpiInstallGpeHandler);
    841       1.1  jruoho 
    842       1.1  jruoho 
    843       1.1  jruoho     /* Parameter validation */
    844       1.1  jruoho 
    845       1.1  jruoho     if ((!Address) || (Type & ~ACPI_GPE_XRUPT_TYPE_MASK))
    846       1.1  jruoho     {
    847       1.1  jruoho         return_ACPI_STATUS (AE_BAD_PARAMETER);
    848       1.1  jruoho     }
    849       1.1  jruoho 
    850       1.1  jruoho     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
    851       1.1  jruoho     if (ACPI_FAILURE (Status))
    852       1.1  jruoho     {
    853       1.1  jruoho         return_ACPI_STATUS (Status);
    854       1.1  jruoho     }
    855       1.1  jruoho 
    856       1.4  jruoho     /* Allocate and init handler object (before lock) */
    857       1.4  jruoho 
    858       1.4  jruoho     Handler = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_GPE_HANDLER_INFO));
    859       1.4  jruoho     if (!Handler)
    860       1.4  jruoho     {
    861       1.4  jruoho         Status = AE_NO_MEMORY;
    862       1.4  jruoho         goto UnlockAndExit;
    863       1.4  jruoho     }
    864       1.4  jruoho 
    865       1.4  jruoho     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
    866       1.4  jruoho 
    867       1.1  jruoho     /* Ensure that we have a valid GPE number */
    868       1.1  jruoho 
    869       1.1  jruoho     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
    870       1.1  jruoho     if (!GpeEventInfo)
    871       1.1  jruoho     {
    872       1.1  jruoho         Status = AE_BAD_PARAMETER;
    873       1.4  jruoho         goto FreeAndExit;
    874       1.1  jruoho     }
    875       1.1  jruoho 
    876       1.1  jruoho     /* Make sure that there isn't a handler there already */
    877       1.1  jruoho 
    878       1.1  jruoho     if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) ==
    879       1.1  jruoho             ACPI_GPE_DISPATCH_HANDLER)
    880       1.1  jruoho     {
    881       1.1  jruoho         Status = AE_ALREADY_EXISTS;
    882       1.4  jruoho         goto FreeAndExit;
    883       1.1  jruoho     }
    884       1.1  jruoho 
    885       1.4  jruoho     Handler->Address = Address;
    886       1.4  jruoho     Handler->Context = Context;
    887       1.4  jruoho     Handler->MethodNode = GpeEventInfo->Dispatch.MethodNode;
    888       1.4  jruoho     Handler->OriginalFlags = (UINT8) (GpeEventInfo->Flags &
    889       1.4  jruoho         (ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK));
    890       1.1  jruoho 
    891       1.4  jruoho     /*
    892       1.4  jruoho      * If the GPE is associated with a method, it may have been enabled
    893       1.4  jruoho      * automatically during initialization, in which case it has to be
    894       1.4  jruoho      * disabled now to avoid spurious execution of the handler.
    895       1.4  jruoho      */
    896       1.4  jruoho     if (((Handler->OriginalFlags & ACPI_GPE_DISPATCH_METHOD) ||
    897       1.4  jruoho          (Handler->OriginalFlags & ACPI_GPE_DISPATCH_NOTIFY)) &&
    898       1.4  jruoho         GpeEventInfo->RuntimeCount)
    899       1.1  jruoho     {
    900       1.4  jruoho         Handler->OriginallyEnabled = TRUE;
    901       1.4  jruoho         (void) AcpiEvRemoveGpeReference (GpeEventInfo);
    902       1.1  jruoho 
    903       1.4  jruoho         /* Sanity check of original type against new type */
    904       1.1  jruoho 
    905       1.4  jruoho         if (Type != (UINT32) (GpeEventInfo->Flags & ACPI_GPE_XRUPT_TYPE_MASK))
    906       1.4  jruoho         {
    907       1.4  jruoho             ACPI_WARNING ((AE_INFO, "GPE type mismatch (level/edge)"));
    908       1.4  jruoho         }
    909       1.1  jruoho     }
    910       1.1  jruoho 
    911       1.1  jruoho     /* Install the handler */
    912       1.1  jruoho 
    913       1.1  jruoho     GpeEventInfo->Dispatch.Handler = Handler;
    914       1.1  jruoho 
    915       1.4  jruoho     /* Setup up dispatch flags to indicate handler (vs. method/notify) */
    916       1.1  jruoho 
    917       1.1  jruoho     GpeEventInfo->Flags &= ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK);
    918       1.1  jruoho     GpeEventInfo->Flags |= (UINT8) (Type | ACPI_GPE_DISPATCH_HANDLER);
    919       1.1  jruoho 
    920       1.1  jruoho     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
    921       1.1  jruoho 
    922       1.1  jruoho 
    923       1.1  jruoho UnlockAndExit:
    924       1.1  jruoho     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
    925       1.1  jruoho     return_ACPI_STATUS (Status);
    926       1.4  jruoho 
    927       1.4  jruoho FreeAndExit:
    928       1.4  jruoho     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
    929       1.4  jruoho     ACPI_FREE (Handler);
    930       1.4  jruoho     goto UnlockAndExit;
    931       1.1  jruoho }
    932       1.1  jruoho 
    933       1.1  jruoho ACPI_EXPORT_SYMBOL (AcpiInstallGpeHandler)
    934       1.1  jruoho 
    935       1.1  jruoho 
    936       1.1  jruoho /*******************************************************************************
    937       1.1  jruoho  *
    938       1.1  jruoho  * FUNCTION:    AcpiRemoveGpeHandler
    939       1.1  jruoho  *
    940       1.1  jruoho  * PARAMETERS:  GpeDevice       - Namespace node for the GPE (NULL for FADT
    941       1.1  jruoho  *                                defined GPEs)
    942       1.1  jruoho  *              GpeNumber       - The event to remove a handler
    943       1.1  jruoho  *              Address         - Address of the handler
    944       1.1  jruoho  *
    945       1.1  jruoho  * RETURN:      Status
    946       1.1  jruoho  *
    947       1.1  jruoho  * DESCRIPTION: Remove a handler for a General Purpose AcpiEvent.
    948       1.1  jruoho  *
    949       1.1  jruoho  ******************************************************************************/
    950       1.1  jruoho 
    951       1.1  jruoho ACPI_STATUS
    952       1.1  jruoho AcpiRemoveGpeHandler (
    953       1.1  jruoho     ACPI_HANDLE             GpeDevice,
    954       1.1  jruoho     UINT32                  GpeNumber,
    955       1.4  jruoho     ACPI_GPE_HANDLER        Address)
    956       1.1  jruoho {
    957       1.1  jruoho     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
    958       1.4  jruoho     ACPI_GPE_HANDLER_INFO   *Handler;
    959       1.1  jruoho     ACPI_STATUS             Status;
    960       1.1  jruoho     ACPI_CPU_FLAGS          Flags;
    961       1.1  jruoho 
    962       1.1  jruoho 
    963       1.1  jruoho     ACPI_FUNCTION_TRACE (AcpiRemoveGpeHandler);
    964       1.1  jruoho 
    965       1.1  jruoho 
    966       1.1  jruoho     /* Parameter validation */
    967       1.1  jruoho 
    968       1.1  jruoho     if (!Address)
    969       1.1  jruoho     {
    970       1.1  jruoho         return_ACPI_STATUS (AE_BAD_PARAMETER);
    971       1.1  jruoho     }
    972       1.1  jruoho 
    973  1.4.20.1     tls     /* Make sure all deferred GPE tasks are completed */
    974  1.4.20.1     tls 
    975  1.4.20.1     tls     AcpiOsWaitEventsComplete ();
    976  1.4.20.1     tls 
    977       1.1  jruoho     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
    978       1.1  jruoho     if (ACPI_FAILURE (Status))
    979       1.1  jruoho     {
    980       1.1  jruoho         return_ACPI_STATUS (Status);
    981       1.1  jruoho     }
    982       1.1  jruoho 
    983       1.4  jruoho     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
    984       1.4  jruoho 
    985       1.1  jruoho     /* Ensure that we have a valid GPE number */
    986       1.1  jruoho 
    987       1.1  jruoho     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
    988       1.1  jruoho     if (!GpeEventInfo)
    989       1.1  jruoho     {
    990       1.1  jruoho         Status = AE_BAD_PARAMETER;
    991       1.1  jruoho         goto UnlockAndExit;
    992       1.1  jruoho     }
    993       1.1  jruoho 
    994       1.1  jruoho     /* Make sure that a handler is indeed installed */
    995       1.1  jruoho 
    996       1.1  jruoho     if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) !=
    997       1.1  jruoho             ACPI_GPE_DISPATCH_HANDLER)
    998       1.1  jruoho     {
    999       1.1  jruoho         Status = AE_NOT_EXIST;
   1000       1.1  jruoho         goto UnlockAndExit;
   1001       1.1  jruoho     }
   1002       1.1  jruoho 
   1003       1.1  jruoho     /* Make sure that the installed handler is the same */
   1004       1.1  jruoho 
   1005       1.1  jruoho     if (GpeEventInfo->Dispatch.Handler->Address != Address)
   1006       1.1  jruoho     {
   1007       1.1  jruoho         Status = AE_BAD_PARAMETER;
   1008       1.1  jruoho         goto UnlockAndExit;
   1009       1.1  jruoho     }
   1010       1.1  jruoho 
   1011       1.1  jruoho     /* Remove the handler */
   1012       1.1  jruoho 
   1013       1.1  jruoho     Handler = GpeEventInfo->Dispatch.Handler;
   1014       1.1  jruoho 
   1015       1.1  jruoho     /* Restore Method node (if any), set dispatch flags */
   1016       1.1  jruoho 
   1017       1.1  jruoho     GpeEventInfo->Dispatch.MethodNode = Handler->MethodNode;
   1018       1.4  jruoho     GpeEventInfo->Flags &=
   1019       1.4  jruoho         ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK);
   1020       1.4  jruoho     GpeEventInfo->Flags |= Handler->OriginalFlags;
   1021       1.4  jruoho 
   1022       1.4  jruoho     /*
   1023       1.4  jruoho      * If the GPE was previously associated with a method and it was
   1024       1.4  jruoho      * enabled, it should be enabled at this point to restore the
   1025       1.4  jruoho      * post-initialization configuration.
   1026       1.4  jruoho      */
   1027       1.4  jruoho     if ((Handler->OriginalFlags & ACPI_GPE_DISPATCH_METHOD) &&
   1028       1.4  jruoho         Handler->OriginallyEnabled)
   1029       1.1  jruoho     {
   1030       1.4  jruoho         (void) AcpiEvAddGpeReference (GpeEventInfo);
   1031       1.1  jruoho     }
   1032       1.1  jruoho 
   1033       1.1  jruoho     /* Now we can free the handler object */
   1034       1.1  jruoho 
   1035       1.1  jruoho     ACPI_FREE (Handler);
   1036       1.1  jruoho 
   1037       1.1  jruoho 
   1038       1.1  jruoho UnlockAndExit:
   1039       1.4  jruoho     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
   1040       1.1  jruoho     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
   1041       1.1  jruoho     return_ACPI_STATUS (Status);
   1042       1.1  jruoho }
   1043       1.1  jruoho 
   1044       1.1  jruoho ACPI_EXPORT_SYMBOL (AcpiRemoveGpeHandler)
   1045       1.1  jruoho 
   1046       1.1  jruoho 
   1047       1.1  jruoho /*******************************************************************************
   1048       1.1  jruoho  *
   1049       1.1  jruoho  * FUNCTION:    AcpiAcquireGlobalLock
   1050       1.1  jruoho  *
   1051       1.1  jruoho  * PARAMETERS:  Timeout         - How long the caller is willing to wait
   1052       1.1  jruoho  *              Handle          - Where the handle to the lock is returned
   1053       1.1  jruoho  *                                (if acquired)
   1054       1.1  jruoho  *
   1055       1.1  jruoho  * RETURN:      Status
   1056       1.1  jruoho  *
   1057       1.1  jruoho  * DESCRIPTION: Acquire the ACPI Global Lock
   1058       1.1  jruoho  *
   1059       1.1  jruoho  * Note: Allows callers with the same thread ID to acquire the global lock
   1060       1.1  jruoho  * multiple times. In other words, externally, the behavior of the global lock
   1061       1.1  jruoho  * is identical to an AML mutex. On the first acquire, a new handle is
   1062       1.1  jruoho  * returned. On any subsequent calls to acquire by the same thread, the same
   1063       1.1  jruoho  * handle is returned.
   1064       1.1  jruoho  *
   1065       1.1  jruoho  ******************************************************************************/
   1066       1.1  jruoho 
   1067       1.1  jruoho ACPI_STATUS
   1068       1.1  jruoho AcpiAcquireGlobalLock (
   1069       1.1  jruoho     UINT16                  Timeout,
   1070       1.1  jruoho     UINT32                  *Handle)
   1071       1.1  jruoho {
   1072       1.1  jruoho     ACPI_STATUS             Status;
   1073       1.1  jruoho 
   1074       1.1  jruoho 
   1075       1.1  jruoho     if (!Handle)
   1076       1.1  jruoho     {
   1077       1.1  jruoho         return (AE_BAD_PARAMETER);
   1078       1.1  jruoho     }
   1079       1.1  jruoho 
   1080       1.1  jruoho     /* Must lock interpreter to prevent race conditions */
   1081       1.1  jruoho 
   1082       1.1  jruoho     AcpiExEnterInterpreter ();
   1083       1.1  jruoho 
   1084       1.1  jruoho     Status = AcpiExAcquireMutexObject (Timeout,
   1085       1.1  jruoho                 AcpiGbl_GlobalLockMutex, AcpiOsGetThreadId ());
   1086       1.1  jruoho 
   1087       1.1  jruoho     if (ACPI_SUCCESS (Status))
   1088       1.1  jruoho     {
   1089       1.1  jruoho         /* Return the global lock handle (updated in AcpiEvAcquireGlobalLock) */
   1090       1.1  jruoho 
   1091       1.1  jruoho         *Handle = AcpiGbl_GlobalLockHandle;
   1092       1.1  jruoho     }
   1093       1.1  jruoho 
   1094       1.1  jruoho     AcpiExExitInterpreter ();
   1095       1.1  jruoho     return (Status);
   1096       1.1  jruoho }
   1097       1.1  jruoho 
   1098       1.1  jruoho ACPI_EXPORT_SYMBOL (AcpiAcquireGlobalLock)
   1099       1.1  jruoho 
   1100       1.1  jruoho 
   1101       1.1  jruoho /*******************************************************************************
   1102       1.1  jruoho  *
   1103       1.1  jruoho  * FUNCTION:    AcpiReleaseGlobalLock
   1104       1.1  jruoho  *
   1105       1.1  jruoho  * PARAMETERS:  Handle      - Returned from AcpiAcquireGlobalLock
   1106       1.1  jruoho  *
   1107       1.1  jruoho  * RETURN:      Status
   1108       1.1  jruoho  *
   1109       1.1  jruoho  * DESCRIPTION: Release the ACPI Global Lock. The handle must be valid.
   1110       1.1  jruoho  *
   1111       1.1  jruoho  ******************************************************************************/
   1112       1.1  jruoho 
   1113       1.1  jruoho ACPI_STATUS
   1114       1.1  jruoho AcpiReleaseGlobalLock (
   1115       1.1  jruoho     UINT32                  Handle)
   1116       1.1  jruoho {
   1117       1.1  jruoho     ACPI_STATUS             Status;
   1118       1.1  jruoho 
   1119       1.1  jruoho 
   1120       1.1  jruoho     if (!Handle || (Handle != AcpiGbl_GlobalLockHandle))
   1121       1.1  jruoho     {
   1122       1.1  jruoho         return (AE_NOT_ACQUIRED);
   1123       1.1  jruoho     }
   1124       1.1  jruoho 
   1125       1.1  jruoho     Status = AcpiExReleaseMutexObject (AcpiGbl_GlobalLockMutex);
   1126       1.1  jruoho     return (Status);
   1127       1.1  jruoho }
   1128       1.1  jruoho 
   1129       1.1  jruoho ACPI_EXPORT_SYMBOL (AcpiReleaseGlobalLock)
   1130       1.1  jruoho 
   1131  1.4.20.1     tls #endif /* !ACPI_REDUCED_HARDWARE */
   1132