LCOV - code coverage report
Current view: top level - drivers/acpi/acpica - evxface.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 73 330 22.1 %
Date: 2022-04-01 14:17:54 Functions: 3 13 23.1 %
Branches: 34 162 21.0 %

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
       2                 :            : /******************************************************************************
       3                 :            :  *
       4                 :            :  * Module Name: evxface - External interfaces for ACPI events
       5                 :            :  *
       6                 :            :  * Copyright (C) 2000 - 2020, Intel Corp.
       7                 :            :  *
       8                 :            :  *****************************************************************************/
       9                 :            : 
      10                 :            : #define EXPORT_ACPI_INTERFACES
      11                 :            : 
      12                 :            : #include <acpi/acpi.h>
      13                 :            : #include "accommon.h"
      14                 :            : #include "acnamesp.h"
      15                 :            : #include "acevents.h"
      16                 :            : #include "acinterp.h"
      17                 :            : 
      18                 :            : #define _COMPONENT          ACPI_EVENTS
      19                 :            : ACPI_MODULE_NAME("evxface")
      20                 :            : #if (!ACPI_REDUCED_HARDWARE)
      21                 :            : /* Local prototypes */
      22                 :            : static acpi_status
      23                 :            : acpi_ev_install_gpe_handler(acpi_handle gpe_device,
      24                 :            :                             u32 gpe_number,
      25                 :            :                             u32 type,
      26                 :            :                             u8 is_raw_handler,
      27                 :            :                             acpi_gpe_handler address, void *context);
      28                 :            : 
      29                 :            : #endif
      30                 :            : 
      31                 :            : 
      32                 :            : /*******************************************************************************
      33                 :            :  *
      34                 :            :  * FUNCTION:    acpi_install_notify_handler
      35                 :            :  *
      36                 :            :  * PARAMETERS:  device          - The device for which notifies will be handled
      37                 :            :  *              handler_type    - The type of handler:
      38                 :            :  *                                  ACPI_SYSTEM_NOTIFY: System Handler (00-7F)
      39                 :            :  *                                  ACPI_DEVICE_NOTIFY: Device Handler (80-FF)
      40                 :            :  *                                  ACPI_ALL_NOTIFY:    Both System and Device
      41                 :            :  *              handler         - Address of the handler
      42                 :            :  *              context         - Value passed to the handler on each GPE
      43                 :            :  *
      44                 :            :  * RETURN:      Status
      45                 :            :  *
      46                 :            :  * DESCRIPTION: Install a handler for notifications on an ACPI Device,
      47                 :            :  *              thermal_zone, or Processor object.
      48                 :            :  *
      49                 :            :  * NOTES:       The Root namespace object may have only one handler for each
      50                 :            :  *              type of notify (System/Device). Device/Thermal/Processor objects
      51                 :            :  *              may have one device notify handler, and multiple system notify
      52                 :            :  *              handlers.
      53                 :            :  *
      54                 :            :  ******************************************************************************/
      55                 :            : 
      56                 :            : acpi_status
      57                 :        110 : acpi_install_notify_handler(acpi_handle device,
      58                 :            :                             u32 handler_type,
      59                 :            :                             acpi_notify_handler handler, void *context)
      60                 :            : {
      61                 :        110 :         struct acpi_namespace_node *node =
      62                 :            :             ACPI_CAST_PTR(struct acpi_namespace_node, device);
      63                 :        110 :         union acpi_operand_object *obj_desc;
      64                 :        110 :         union acpi_operand_object *handler_obj;
      65                 :        110 :         acpi_status status;
      66                 :        110 :         u32 i;
      67                 :            : 
      68                 :        110 :         ACPI_FUNCTION_TRACE(acpi_install_notify_handler);
      69                 :            : 
      70                 :            :         /* Parameter validation */
      71                 :            : 
      72   [ +  -  +  - ]:        110 :         if ((!device) || (!handler) || (!handler_type) ||
      73                 :            :             (handler_type > ACPI_MAX_NOTIFY_HANDLER_TYPE)) {
      74                 :            :                 return_ACPI_STATUS(AE_BAD_PARAMETER);
      75                 :            :         }
      76                 :            : 
      77                 :        110 :         status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
      78         [ +  - ]:        110 :         if (ACPI_FAILURE(status)) {
      79                 :            :                 return_ACPI_STATUS(status);
      80                 :            :         }
      81                 :            : 
      82                 :            :         /*
      83                 :            :          * Root Object:
      84                 :            :          * Registering a notify handler on the root object indicates that the
      85                 :            :          * caller wishes to receive notifications for all objects. Note that
      86                 :            :          * only one global handler can be registered per notify type.
      87                 :            :          * Ensure that a handler is not already installed.
      88                 :            :          */
      89         [ +  + ]:        110 :         if (device == ACPI_ROOT_OBJECT) {
      90         [ +  + ]:         33 :                 for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) {
      91         [ +  + ]:         22 :                         if (handler_type & (i + 1)) {
      92         [ -  + ]:         11 :                                 if (acpi_gbl_global_notify[i].handler) {
      93                 :          0 :                                         status = AE_ALREADY_EXISTS;
      94                 :          0 :                                         goto unlock_and_exit;
      95                 :            :                                 }
      96                 :            : 
      97                 :         11 :                                 acpi_gbl_global_notify[i].handler = handler;
      98                 :         11 :                                 acpi_gbl_global_notify[i].context = context;
      99                 :            :                         }
     100                 :            :                 }
     101                 :            : 
     102                 :         11 :                 goto unlock_and_exit;   /* Global notify handler installed, all done */
     103                 :            :         }
     104                 :            : 
     105                 :            :         /*
     106                 :            :          * All Other Objects:
     107                 :            :          * Caller will only receive notifications specific to the target
     108                 :            :          * object. Note that only certain object types are allowed to
     109                 :            :          * receive notifications.
     110                 :            :          */
     111                 :            : 
     112                 :            :         /* Are Notifies allowed on this object? */
     113                 :            : 
     114         [ -  + ]:         99 :         if (!acpi_ev_is_notify_object(node)) {
     115                 :          0 :                 status = AE_TYPE;
     116                 :          0 :                 goto unlock_and_exit;
     117                 :            :         }
     118                 :            : 
     119                 :            :         /* Check for an existing internal object, might not exist */
     120                 :            : 
     121                 :         99 :         obj_desc = acpi_ns_get_attached_object(node);
     122         [ +  + ]:         99 :         if (!obj_desc) {
     123                 :            : 
     124                 :            :                 /* Create a new object */
     125                 :            : 
     126                 :         77 :                 obj_desc = acpi_ut_create_internal_object(node->type);
     127         [ -  + ]:         77 :                 if (!obj_desc) {
     128                 :          0 :                         status = AE_NO_MEMORY;
     129                 :          0 :                         goto unlock_and_exit;
     130                 :            :                 }
     131                 :            : 
     132                 :            :                 /* Attach new object to the Node, remove local reference */
     133                 :            : 
     134                 :         77 :                 status = acpi_ns_attach_object(device, obj_desc, node->type);
     135                 :         77 :                 acpi_ut_remove_reference(obj_desc);
     136         [ -  + ]:         77 :                 if (ACPI_FAILURE(status)) {
     137                 :          0 :                         goto unlock_and_exit;
     138                 :            :                 }
     139                 :            :         }
     140                 :            : 
     141                 :            :         /* Ensure that the handler is not already installed in the lists */
     142                 :            : 
     143         [ +  + ]:        297 :         for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) {
     144         [ +  + ]:        198 :                 if (handler_type & (i + 1)) {
     145                 :         99 :                         handler_obj = obj_desc->common_notify.notify_list[i];
     146         [ -  + ]:         99 :                         while (handler_obj) {
     147         [ #  # ]:          0 :                                 if (handler_obj->notify.handler == handler) {
     148                 :          0 :                                         status = AE_ALREADY_EXISTS;
     149                 :          0 :                                         goto unlock_and_exit;
     150                 :            :                                 }
     151                 :            : 
     152                 :          0 :                                 handler_obj = handler_obj->notify.next[i];
     153                 :            :                         }
     154                 :            :                 }
     155                 :            :         }
     156                 :            : 
     157                 :            :         /* Create and populate a new notify handler object */
     158                 :            : 
     159                 :         99 :         handler_obj = acpi_ut_create_internal_object(ACPI_TYPE_LOCAL_NOTIFY);
     160         [ -  + ]:         99 :         if (!handler_obj) {
     161                 :          0 :                 status = AE_NO_MEMORY;
     162                 :          0 :                 goto unlock_and_exit;
     163                 :            :         }
     164                 :            : 
     165                 :         99 :         handler_obj->notify.node = node;
     166                 :         99 :         handler_obj->notify.handler_type = handler_type;
     167                 :         99 :         handler_obj->notify.handler = handler;
     168                 :         99 :         handler_obj->notify.context = context;
     169                 :            : 
     170                 :            :         /* Install the handler at the list head(s) */
     171                 :            : 
     172         [ +  + ]:        297 :         for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) {
     173         [ +  + ]:        198 :                 if (handler_type & (i + 1)) {
     174                 :         99 :                         handler_obj->notify.next[i] =
     175                 :         99 :                             obj_desc->common_notify.notify_list[i];
     176                 :            : 
     177                 :         99 :                         obj_desc->common_notify.notify_list[i] = handler_obj;
     178                 :            :                 }
     179                 :            :         }
     180                 :            : 
     181                 :            :         /* Add an extra reference if handler was installed in both lists */
     182                 :            : 
     183         [ +  - ]:         99 :         if (handler_type == ACPI_ALL_NOTIFY) {
     184                 :          0 :                 acpi_ut_add_reference(handler_obj);
     185                 :            :         }
     186                 :            : 
     187                 :         99 : unlock_and_exit:
     188                 :        110 :         (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
     189                 :        110 :         return_ACPI_STATUS(status);
     190                 :            : }
     191                 :            : 
     192                 :            : ACPI_EXPORT_SYMBOL(acpi_install_notify_handler)
     193                 :            : 
     194                 :            : /*******************************************************************************
     195                 :            :  *
     196                 :            :  * FUNCTION:    acpi_remove_notify_handler
     197                 :            :  *
     198                 :            :  * PARAMETERS:  device          - The device for which the handler is installed
     199                 :            :  *              handler_type    - The type of handler:
     200                 :            :  *                                  ACPI_SYSTEM_NOTIFY: System Handler (00-7F)
     201                 :            :  *                                  ACPI_DEVICE_NOTIFY: Device Handler (80-FF)
     202                 :            :  *                                  ACPI_ALL_NOTIFY:    Both System and Device
     203                 :            :  *              handler         - Address of the handler
     204                 :            :  *
     205                 :            :  * RETURN:      Status
     206                 :            :  *
     207                 :            :  * DESCRIPTION: Remove a handler for notifies on an ACPI device
     208                 :            :  *
     209                 :            :  ******************************************************************************/
     210                 :            : acpi_status
     211                 :          0 : acpi_remove_notify_handler(acpi_handle device,
     212                 :            :                            u32 handler_type, acpi_notify_handler handler)
     213                 :            : {
     214                 :          0 :         struct acpi_namespace_node *node =
     215                 :            :             ACPI_CAST_PTR(struct acpi_namespace_node, device);
     216                 :          0 :         union acpi_operand_object *obj_desc;
     217                 :          0 :         union acpi_operand_object *handler_obj;
     218                 :          0 :         union acpi_operand_object *previous_handler_obj;
     219                 :          0 :         acpi_status status = AE_OK;
     220                 :          0 :         u32 i;
     221                 :            : 
     222                 :          0 :         ACPI_FUNCTION_TRACE(acpi_remove_notify_handler);
     223                 :            : 
     224                 :            :         /* Parameter validation */
     225                 :            : 
     226   [ #  #  #  # ]:          0 :         if ((!device) || (!handler) || (!handler_type) ||
     227                 :            :             (handler_type > ACPI_MAX_NOTIFY_HANDLER_TYPE)) {
     228                 :            :                 return_ACPI_STATUS(AE_BAD_PARAMETER);
     229                 :            :         }
     230                 :            : 
     231                 :            :         /* Root Object. Global handlers are removed here */
     232                 :            : 
     233         [ #  # ]:          0 :         if (device == ACPI_ROOT_OBJECT) {
     234         [ #  # ]:          0 :                 for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) {
     235         [ #  # ]:          0 :                         if (handler_type & (i + 1)) {
     236                 :          0 :                                 status =
     237                 :          0 :                                     acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
     238         [ #  # ]:          0 :                                 if (ACPI_FAILURE(status)) {
     239                 :          0 :                                         return_ACPI_STATUS(status);
     240                 :            :                                 }
     241                 :            : 
     242   [ #  #  #  # ]:          0 :                                 if (!acpi_gbl_global_notify[i].handler ||
     243                 :            :                                     (acpi_gbl_global_notify[i].handler !=
     244                 :            :                                      handler)) {
     245                 :          0 :                                         status = AE_NOT_EXIST;
     246                 :          0 :                                         goto unlock_and_exit;
     247                 :            :                                 }
     248                 :            : 
     249                 :            :                                 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
     250                 :          0 :                                                   "Removing global notify handler\n"));
     251                 :            : 
     252                 :          0 :                                 acpi_gbl_global_notify[i].handler = NULL;
     253                 :          0 :                                 acpi_gbl_global_notify[i].context = NULL;
     254                 :            : 
     255                 :          0 :                                 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
     256                 :            : 
     257                 :            :                                 /* Make sure all deferred notify tasks are completed */
     258                 :            : 
     259                 :          0 :                                 acpi_os_wait_events_complete();
     260                 :            :                         }
     261                 :            :                 }
     262                 :            : 
     263                 :            :                 return_ACPI_STATUS(AE_OK);
     264                 :            :         }
     265                 :            : 
     266                 :            :         /* All other objects: Are Notifies allowed on this object? */
     267                 :            : 
     268         [ #  # ]:          0 :         if (!acpi_ev_is_notify_object(node)) {
     269                 :            :                 return_ACPI_STATUS(AE_TYPE);
     270                 :            :         }
     271                 :            : 
     272                 :            :         /* Must have an existing internal object */
     273                 :            : 
     274                 :          0 :         obj_desc = acpi_ns_get_attached_object(node);
     275         [ #  # ]:          0 :         if (!obj_desc) {
     276                 :            :                 return_ACPI_STATUS(AE_NOT_EXIST);
     277                 :            :         }
     278                 :            : 
     279                 :            :         /* Internal object exists. Find the handler and remove it */
     280                 :            : 
     281         [ #  # ]:          0 :         for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) {
     282         [ #  # ]:          0 :                 if (handler_type & (i + 1)) {
     283                 :          0 :                         status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
     284         [ #  # ]:          0 :                         if (ACPI_FAILURE(status)) {
     285                 :          0 :                                 return_ACPI_STATUS(status);
     286                 :            :                         }
     287                 :            : 
     288                 :          0 :                         handler_obj = obj_desc->common_notify.notify_list[i];
     289                 :          0 :                         previous_handler_obj = NULL;
     290                 :            : 
     291                 :            :                         /* Attempt to find the handler in the handler list */
     292                 :            : 
     293         [ #  # ]:          0 :                         while (handler_obj &&
     294         [ #  # ]:          0 :                                (handler_obj->notify.handler != handler)) {
     295                 :          0 :                                 previous_handler_obj = handler_obj;
     296                 :          0 :                                 handler_obj = handler_obj->notify.next[i];
     297                 :            :                         }
     298                 :            : 
     299         [ #  # ]:          0 :                         if (!handler_obj) {
     300                 :          0 :                                 status = AE_NOT_EXIST;
     301                 :          0 :                                 goto unlock_and_exit;
     302                 :            :                         }
     303                 :            : 
     304                 :            :                         /* Remove the handler object from the list */
     305                 :            : 
     306         [ #  # ]:          0 :                         if (previous_handler_obj) {     /* Handler is not at the list head */
     307                 :          0 :                                 previous_handler_obj->notify.next[i] =
     308                 :          0 :                                     handler_obj->notify.next[i];
     309                 :            :                         } else {        /* Handler is at the list head */
     310                 :            : 
     311                 :          0 :                                 obj_desc->common_notify.notify_list[i] =
     312                 :          0 :                                     handler_obj->notify.next[i];
     313                 :            :                         }
     314                 :            : 
     315                 :          0 :                         (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
     316                 :            : 
     317                 :            :                         /* Make sure all deferred notify tasks are completed */
     318                 :            : 
     319                 :          0 :                         acpi_os_wait_events_complete();
     320                 :          0 :                         acpi_ut_remove_reference(handler_obj);
     321                 :            :                 }
     322                 :            :         }
     323                 :            : 
     324                 :            :         return_ACPI_STATUS(status);
     325                 :            : 
     326                 :          0 : unlock_and_exit:
     327                 :          0 :         (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
     328                 :          0 :         return_ACPI_STATUS(status);
     329                 :            : }
     330                 :            : 
     331                 :            : ACPI_EXPORT_SYMBOL(acpi_remove_notify_handler)
     332                 :            : 
     333                 :            : /*******************************************************************************
     334                 :            :  *
     335                 :            :  * FUNCTION:    acpi_install_exception_handler
     336                 :            :  *
     337                 :            :  * PARAMETERS:  handler         - Pointer to the handler function for the
     338                 :            :  *                                event
     339                 :            :  *
     340                 :            :  * RETURN:      Status
     341                 :            :  *
     342                 :            :  * DESCRIPTION: Saves the pointer to the handler function
     343                 :            :  *
     344                 :            :  ******************************************************************************/
     345                 :            : #ifdef ACPI_FUTURE_USAGE
     346                 :            : acpi_status acpi_install_exception_handler(acpi_exception_handler handler)
     347                 :            : {
     348                 :            :         acpi_status status;
     349                 :            : 
     350                 :            :         ACPI_FUNCTION_TRACE(acpi_install_exception_handler);
     351                 :            : 
     352                 :            :         status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
     353                 :            :         if (ACPI_FAILURE(status)) {
     354                 :            :                 return_ACPI_STATUS(status);
     355                 :            :         }
     356                 :            : 
     357                 :            :         /* Don't allow two handlers. */
     358                 :            : 
     359                 :            :         if (acpi_gbl_exception_handler) {
     360                 :            :                 status = AE_ALREADY_EXISTS;
     361                 :            :                 goto cleanup;
     362                 :            :         }
     363                 :            : 
     364                 :            :         /* Install the handler */
     365                 :            : 
     366                 :            :         acpi_gbl_exception_handler = handler;
     367                 :            : 
     368                 :            : cleanup:
     369                 :            :         (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
     370                 :            :         return_ACPI_STATUS(status);
     371                 :            : }
     372                 :            : 
     373                 :            : ACPI_EXPORT_SYMBOL(acpi_install_exception_handler)
     374                 :            : #endif
     375                 :            : 
     376                 :            : #if (!ACPI_REDUCED_HARDWARE)
     377                 :            : /*******************************************************************************
     378                 :            :  *
     379                 :            :  * FUNCTION:    acpi_install_sci_handler
     380                 :            :  *
     381                 :            :  * PARAMETERS:  address             - Address of the handler
     382                 :            :  *              context             - Value passed to the handler on each SCI
     383                 :            :  *
     384                 :            :  * RETURN:      Status
     385                 :            :  *
     386                 :            :  * DESCRIPTION: Install a handler for a System Control Interrupt.
     387                 :            :  *
     388                 :            :  ******************************************************************************/
     389                 :          0 : acpi_status acpi_install_sci_handler(acpi_sci_handler address, void *context)
     390                 :            : {
     391                 :          0 :         struct acpi_sci_handler_info *new_sci_handler;
     392                 :          0 :         struct acpi_sci_handler_info *sci_handler;
     393                 :          0 :         acpi_cpu_flags flags;
     394                 :          0 :         acpi_status status;
     395                 :            : 
     396                 :          0 :         ACPI_FUNCTION_TRACE(acpi_install_sci_handler);
     397                 :            : 
     398         [ #  # ]:          0 :         if (!address) {
     399                 :            :                 return_ACPI_STATUS(AE_BAD_PARAMETER);
     400                 :            :         }
     401                 :            : 
     402                 :            :         /* Allocate and init a handler object */
     403                 :            : 
     404                 :          0 :         new_sci_handler = ACPI_ALLOCATE(sizeof(struct acpi_sci_handler_info));
     405         [ #  # ]:          0 :         if (!new_sci_handler) {
     406                 :            :                 return_ACPI_STATUS(AE_NO_MEMORY);
     407                 :            :         }
     408                 :            : 
     409                 :          0 :         new_sci_handler->address = address;
     410                 :          0 :         new_sci_handler->context = context;
     411                 :            : 
     412                 :          0 :         status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
     413         [ #  # ]:          0 :         if (ACPI_FAILURE(status)) {
     414                 :          0 :                 goto exit;
     415                 :            :         }
     416                 :            : 
     417                 :            :         /* Lock list during installation */
     418                 :            : 
     419                 :          0 :         flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
     420                 :          0 :         sci_handler = acpi_gbl_sci_handler_list;
     421                 :            : 
     422                 :            :         /* Ensure handler does not already exist */
     423                 :            : 
     424         [ #  # ]:          0 :         while (sci_handler) {
     425         [ #  # ]:          0 :                 if (address == sci_handler->address) {
     426                 :          0 :                         status = AE_ALREADY_EXISTS;
     427                 :          0 :                         goto unlock_and_exit;
     428                 :            :                 }
     429                 :            : 
     430                 :          0 :                 sci_handler = sci_handler->next;
     431                 :            :         }
     432                 :            : 
     433                 :            :         /* Install the new handler into the global list (at head) */
     434                 :            : 
     435                 :          0 :         new_sci_handler->next = acpi_gbl_sci_handler_list;
     436                 :          0 :         acpi_gbl_sci_handler_list = new_sci_handler;
     437                 :            : 
     438                 :          0 : unlock_and_exit:
     439                 :            : 
     440                 :          0 :         acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
     441                 :          0 :         (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
     442                 :            : 
     443                 :          0 : exit:
     444         [ #  # ]:          0 :         if (ACPI_FAILURE(status)) {
     445                 :          0 :                 ACPI_FREE(new_sci_handler);
     446                 :            :         }
     447                 :            :         return_ACPI_STATUS(status);
     448                 :            : }
     449                 :            : 
     450                 :            : ACPI_EXPORT_SYMBOL(acpi_install_sci_handler)
     451                 :            : 
     452                 :            : /*******************************************************************************
     453                 :            :  *
     454                 :            :  * FUNCTION:    acpi_remove_sci_handler
     455                 :            :  *
     456                 :            :  * PARAMETERS:  address             - Address of the handler
     457                 :            :  *
     458                 :            :  * RETURN:      Status
     459                 :            :  *
     460                 :            :  * DESCRIPTION: Remove a handler for a System Control Interrupt.
     461                 :            :  *
     462                 :            :  ******************************************************************************/
     463                 :          0 : acpi_status acpi_remove_sci_handler(acpi_sci_handler address)
     464                 :            : {
     465                 :          0 :         struct acpi_sci_handler_info *prev_sci_handler;
     466                 :          0 :         struct acpi_sci_handler_info *next_sci_handler;
     467                 :          0 :         acpi_cpu_flags flags;
     468                 :          0 :         acpi_status status;
     469                 :            : 
     470                 :          0 :         ACPI_FUNCTION_TRACE(acpi_remove_sci_handler);
     471                 :            : 
     472         [ #  # ]:          0 :         if (!address) {
     473                 :            :                 return_ACPI_STATUS(AE_BAD_PARAMETER);
     474                 :            :         }
     475                 :            : 
     476                 :          0 :         status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
     477         [ #  # ]:          0 :         if (ACPI_FAILURE(status)) {
     478                 :            :                 return_ACPI_STATUS(status);
     479                 :            :         }
     480                 :            : 
     481                 :            :         /* Remove the SCI handler with lock */
     482                 :            : 
     483                 :          0 :         flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
     484                 :            : 
     485                 :          0 :         prev_sci_handler = NULL;
     486                 :          0 :         next_sci_handler = acpi_gbl_sci_handler_list;
     487         [ #  # ]:          0 :         while (next_sci_handler) {
     488         [ #  # ]:          0 :                 if (next_sci_handler->address == address) {
     489                 :            : 
     490                 :            :                         /* Unlink and free the SCI handler info block */
     491                 :            : 
     492         [ #  # ]:          0 :                         if (prev_sci_handler) {
     493                 :          0 :                                 prev_sci_handler->next = next_sci_handler->next;
     494                 :            :                         } else {
     495                 :          0 :                                 acpi_gbl_sci_handler_list =
     496                 :          0 :                                     next_sci_handler->next;
     497                 :            :                         }
     498                 :            : 
     499                 :          0 :                         acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
     500                 :          0 :                         ACPI_FREE(next_sci_handler);
     501                 :          0 :                         goto unlock_and_exit;
     502                 :            :                 }
     503                 :            : 
     504                 :          0 :                 prev_sci_handler = next_sci_handler;
     505                 :          0 :                 next_sci_handler = next_sci_handler->next;
     506                 :            :         }
     507                 :            : 
     508                 :          0 :         acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
     509                 :          0 :         status = AE_NOT_EXIST;
     510                 :            : 
     511                 :          0 : unlock_and_exit:
     512                 :          0 :         (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
     513                 :          0 :         return_ACPI_STATUS(status);
     514                 :            : }
     515                 :            : 
     516                 :            : ACPI_EXPORT_SYMBOL(acpi_remove_sci_handler)
     517                 :            : 
     518                 :            : /*******************************************************************************
     519                 :            :  *
     520                 :            :  * FUNCTION:    acpi_install_global_event_handler
     521                 :            :  *
     522                 :            :  * PARAMETERS:  handler         - Pointer to the global event handler function
     523                 :            :  *              context         - Value passed to the handler on each event
     524                 :            :  *
     525                 :            :  * RETURN:      Status
     526                 :            :  *
     527                 :            :  * DESCRIPTION: Saves the pointer to the handler function. The global handler
     528                 :            :  *              is invoked upon each incoming GPE and Fixed Event. It is
     529                 :            :  *              invoked at interrupt level at the time of the event dispatch.
     530                 :            :  *              Can be used to update event counters, etc.
     531                 :            :  *
     532                 :            :  ******************************************************************************/
     533                 :            : acpi_status
     534                 :         11 : acpi_install_global_event_handler(acpi_gbl_event_handler handler, void *context)
     535                 :            : {
     536                 :         11 :         acpi_status status;
     537                 :            : 
     538                 :         11 :         ACPI_FUNCTION_TRACE(acpi_install_global_event_handler);
     539                 :            : 
     540                 :            :         /* Parameter validation */
     541                 :            : 
     542         [ +  - ]:         11 :         if (!handler) {
     543                 :            :                 return_ACPI_STATUS(AE_BAD_PARAMETER);
     544                 :            :         }
     545                 :            : 
     546                 :         11 :         status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
     547         [ +  - ]:         11 :         if (ACPI_FAILURE(status)) {
     548                 :            :                 return_ACPI_STATUS(status);
     549                 :            :         }
     550                 :            : 
     551                 :            :         /* Don't allow two handlers. */
     552                 :            : 
     553         [ -  + ]:         11 :         if (acpi_gbl_global_event_handler) {
     554                 :          0 :                 status = AE_ALREADY_EXISTS;
     555                 :          0 :                 goto cleanup;
     556                 :            :         }
     557                 :            : 
     558                 :         11 :         acpi_gbl_global_event_handler = handler;
     559                 :         11 :         acpi_gbl_global_event_handler_context = context;
     560                 :            : 
     561                 :         11 : cleanup:
     562                 :         11 :         (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
     563                 :         11 :         return_ACPI_STATUS(status);
     564                 :            : }
     565                 :            : 
     566                 :            : ACPI_EXPORT_SYMBOL(acpi_install_global_event_handler)
     567                 :            : 
     568                 :            : /*******************************************************************************
     569                 :            :  *
     570                 :            :  * FUNCTION:    acpi_install_fixed_event_handler
     571                 :            :  *
     572                 :            :  * PARAMETERS:  event           - Event type to enable.
     573                 :            :  *              handler         - Pointer to the handler function for the
     574                 :            :  *                                event
     575                 :            :  *              context         - Value passed to the handler on each GPE
     576                 :            :  *
     577                 :            :  * RETURN:      Status
     578                 :            :  *
     579                 :            :  * DESCRIPTION: Saves the pointer to the handler function and then enables the
     580                 :            :  *              event.
     581                 :            :  *
     582                 :            :  ******************************************************************************/
     583                 :            : acpi_status
     584                 :         33 : acpi_install_fixed_event_handler(u32 event,
     585                 :            :                                  acpi_event_handler handler, void *context)
     586                 :            : {
     587                 :         33 :         acpi_status status;
     588                 :            : 
     589                 :         33 :         ACPI_FUNCTION_TRACE(acpi_install_fixed_event_handler);
     590                 :            : 
     591                 :            :         /* Parameter validation */
     592                 :            : 
     593         [ +  - ]:         33 :         if (event > ACPI_EVENT_MAX) {
     594                 :            :                 return_ACPI_STATUS(AE_BAD_PARAMETER);
     595                 :            :         }
     596                 :            : 
     597                 :         33 :         status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
     598         [ +  - ]:         33 :         if (ACPI_FAILURE(status)) {
     599                 :            :                 return_ACPI_STATUS(status);
     600                 :            :         }
     601                 :            : 
     602                 :            :         /* Do not allow multiple handlers */
     603                 :            : 
     604         [ -  + ]:         33 :         if (acpi_gbl_fixed_event_handlers[event].handler) {
     605                 :          0 :                 status = AE_ALREADY_EXISTS;
     606                 :          0 :                 goto cleanup;
     607                 :            :         }
     608                 :            : 
     609                 :            :         /* Install the handler before enabling the event */
     610                 :            : 
     611                 :         33 :         acpi_gbl_fixed_event_handlers[event].handler = handler;
     612                 :         33 :         acpi_gbl_fixed_event_handlers[event].context = context;
     613                 :            : 
     614                 :         33 :         status = acpi_clear_event(event);
     615         [ +  - ]:         33 :         if (ACPI_SUCCESS(status))
     616                 :         33 :                 status = acpi_enable_event(event, 0);
     617         [ +  - ]:         33 :         if (ACPI_FAILURE(status)) {
     618                 :          0 :                 ACPI_WARNING((AE_INFO,
     619                 :            :                               "Could not enable fixed event - %s (%u)",
     620                 :            :                               acpi_ut_get_event_name(event), event));
     621                 :            : 
     622                 :            :                 /* Remove the handler */
     623                 :            : 
     624                 :          0 :                 acpi_gbl_fixed_event_handlers[event].handler = NULL;
     625                 :          0 :                 acpi_gbl_fixed_event_handlers[event].context = NULL;
     626                 :            :         } else {
     627                 :            :                 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
     628                 :            :                                   "Enabled fixed event %s (%X), Handler=%p\n",
     629                 :            :                                   acpi_ut_get_event_name(event), event,
     630                 :         33 :                                   handler));
     631                 :            :         }
     632                 :            : 
     633                 :         33 : cleanup:
     634                 :         33 :         (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
     635                 :         33 :         return_ACPI_STATUS(status);
     636                 :            : }
     637                 :            : 
     638                 :            : ACPI_EXPORT_SYMBOL(acpi_install_fixed_event_handler)
     639                 :            : 
     640                 :            : /*******************************************************************************
     641                 :            :  *
     642                 :            :  * FUNCTION:    acpi_remove_fixed_event_handler
     643                 :            :  *
     644                 :            :  * PARAMETERS:  event           - Event type to disable.
     645                 :            :  *              handler         - Address of the handler
     646                 :            :  *
     647                 :            :  * RETURN:      Status
     648                 :            :  *
     649                 :            :  * DESCRIPTION: Disables the event and unregisters the event handler.
     650                 :            :  *
     651                 :            :  ******************************************************************************/
     652                 :            : acpi_status
     653                 :          0 : acpi_remove_fixed_event_handler(u32 event, acpi_event_handler handler)
     654                 :            : {
     655                 :          0 :         acpi_status status = AE_OK;
     656                 :            : 
     657                 :          0 :         ACPI_FUNCTION_TRACE(acpi_remove_fixed_event_handler);
     658                 :            : 
     659                 :            :         /* Parameter validation */
     660                 :            : 
     661         [ #  # ]:          0 :         if (event > ACPI_EVENT_MAX) {
     662                 :            :                 return_ACPI_STATUS(AE_BAD_PARAMETER);
     663                 :            :         }
     664                 :            : 
     665                 :          0 :         status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
     666         [ #  # ]:          0 :         if (ACPI_FAILURE(status)) {
     667                 :            :                 return_ACPI_STATUS(status);
     668                 :            :         }
     669                 :            : 
     670                 :            :         /* Disable the event before removing the handler */
     671                 :            : 
     672                 :          0 :         status = acpi_disable_event(event, 0);
     673                 :            : 
     674                 :            :         /* Always Remove the handler */
     675                 :            : 
     676                 :          0 :         acpi_gbl_fixed_event_handlers[event].handler = NULL;
     677                 :          0 :         acpi_gbl_fixed_event_handlers[event].context = NULL;
     678                 :            : 
     679         [ #  # ]:          0 :         if (ACPI_FAILURE(status)) {
     680                 :          0 :                 ACPI_WARNING((AE_INFO,
     681                 :            :                               "Could not disable fixed event - %s (%u)",
     682                 :            :                               acpi_ut_get_event_name(event), event));
     683                 :            :         } else {
     684                 :            :                 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
     685                 :            :                                   "Disabled fixed event - %s (%X)\n",
     686                 :          0 :                                   acpi_ut_get_event_name(event), event));
     687                 :            :         }
     688                 :            : 
     689                 :          0 :         (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
     690                 :          0 :         return_ACPI_STATUS(status);
     691                 :            : }
     692                 :            : 
     693                 :            : ACPI_EXPORT_SYMBOL(acpi_remove_fixed_event_handler)
     694                 :            : 
     695                 :            : /*******************************************************************************
     696                 :            :  *
     697                 :            :  * FUNCTION:    acpi_ev_install_gpe_handler
     698                 :            :  *
     699                 :            :  * PARAMETERS:  gpe_device      - Namespace node for the GPE (NULL for FADT
     700                 :            :  *                                defined GPEs)
     701                 :            :  *              gpe_number      - The GPE number within the GPE block
     702                 :            :  *              type            - Whether this GPE should be treated as an
     703                 :            :  *                                edge- or level-triggered interrupt.
     704                 :            :  *              is_raw_handler  - Whether this GPE should be handled using
     705                 :            :  *                                the special GPE handler mode.
     706                 :            :  *              address         - Address of the handler
     707                 :            :  *              context         - Value passed to the handler on each GPE
     708                 :            :  *
     709                 :            :  * RETURN:      Status
     710                 :            :  *
     711                 :            :  * DESCRIPTION: Internal function to install a handler for a General Purpose
     712                 :            :  *              Event.
     713                 :            :  *
     714                 :            :  ******************************************************************************/
     715                 :            : static acpi_status
     716                 :          0 : acpi_ev_install_gpe_handler(acpi_handle gpe_device,
     717                 :            :                             u32 gpe_number,
     718                 :            :                             u32 type,
     719                 :            :                             u8 is_raw_handler,
     720                 :            :                             acpi_gpe_handler address, void *context)
     721                 :            : {
     722                 :          0 :         struct acpi_gpe_event_info *gpe_event_info;
     723                 :          0 :         struct acpi_gpe_handler_info *handler;
     724                 :          0 :         acpi_status status;
     725                 :          0 :         acpi_cpu_flags flags;
     726                 :            : 
     727                 :          0 :         ACPI_FUNCTION_TRACE(ev_install_gpe_handler);
     728                 :            : 
     729                 :            :         /* Parameter validation */
     730                 :            : 
     731   [ #  #  #  # ]:          0 :         if ((!address) || (type & ~ACPI_GPE_XRUPT_TYPE_MASK)) {
     732                 :            :                 return_ACPI_STATUS(AE_BAD_PARAMETER);
     733                 :            :         }
     734                 :            : 
     735                 :          0 :         status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
     736         [ #  # ]:          0 :         if (ACPI_FAILURE(status)) {
     737                 :            :                 return_ACPI_STATUS(status);
     738                 :            :         }
     739                 :            : 
     740                 :            :         /* Allocate and init handler object (before lock) */
     741                 :            : 
     742                 :          0 :         handler = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_gpe_handler_info));
     743         [ #  # ]:          0 :         if (!handler) {
     744                 :          0 :                 status = AE_NO_MEMORY;
     745                 :          0 :                 goto unlock_and_exit;
     746                 :            :         }
     747                 :            : 
     748                 :          0 :         flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
     749                 :            : 
     750                 :            :         /* Ensure that we have a valid GPE number */
     751                 :            : 
     752                 :          0 :         gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
     753         [ #  # ]:          0 :         if (!gpe_event_info) {
     754                 :          0 :                 status = AE_BAD_PARAMETER;
     755                 :          0 :                 goto free_and_exit;
     756                 :            :         }
     757                 :            : 
     758                 :            :         /* Make sure that there isn't a handler there already */
     759                 :            : 
     760                 :          0 :         if ((ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) ==
     761         [ #  # ]:          0 :              ACPI_GPE_DISPATCH_HANDLER) ||
     762                 :            :             (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) ==
     763                 :            :              ACPI_GPE_DISPATCH_RAW_HANDLER)) {
     764                 :          0 :                 status = AE_ALREADY_EXISTS;
     765                 :          0 :                 goto free_and_exit;
     766                 :            :         }
     767                 :            : 
     768                 :          0 :         handler->address = address;
     769                 :          0 :         handler->context = context;
     770                 :          0 :         handler->method_node = gpe_event_info->dispatch.method_node;
     771                 :          0 :         handler->original_flags = (u8)(gpe_event_info->flags &
     772                 :            :                                        (ACPI_GPE_XRUPT_TYPE_MASK |
     773                 :            :                                         ACPI_GPE_DISPATCH_MASK));
     774                 :            : 
     775                 :            :         /*
     776                 :            :          * If the GPE is associated with a method, it may have been enabled
     777                 :            :          * automatically during initialization, in which case it has to be
     778                 :            :          * disabled now to avoid spurious execution of the handler.
     779                 :            :          */
     780                 :          0 :         if (((ACPI_GPE_DISPATCH_TYPE(handler->original_flags) ==
     781         [ #  # ]:          0 :               ACPI_GPE_DISPATCH_METHOD) ||
     782                 :            :              (ACPI_GPE_DISPATCH_TYPE(handler->original_flags) ==
     783         [ #  # ]:          0 :               ACPI_GPE_DISPATCH_NOTIFY)) && gpe_event_info->runtime_count) {
     784                 :          0 :                 handler->originally_enabled = TRUE;
     785                 :          0 :                 (void)acpi_ev_remove_gpe_reference(gpe_event_info);
     786                 :            : 
     787                 :            :                 /* Sanity check of original type against new type */
     788                 :            : 
     789                 :          0 :                 if (type !=
     790         [ #  # ]:          0 :                     (u32)(gpe_event_info->flags & ACPI_GPE_XRUPT_TYPE_MASK)) {
     791                 :          0 :                         ACPI_WARNING((AE_INFO,
     792                 :            :                                       "GPE type mismatch (level/edge)"));
     793                 :            :                 }
     794                 :            :         }
     795                 :            : 
     796                 :            :         /* Install the handler */
     797                 :            : 
     798                 :          0 :         gpe_event_info->dispatch.handler = handler;
     799                 :            : 
     800                 :            :         /* Setup up dispatch flags to indicate handler (vs. method/notify) */
     801                 :            : 
     802                 :          0 :         gpe_event_info->flags &=
     803                 :            :             ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK);
     804                 :          0 :         gpe_event_info->flags |=
     805         [ #  # ]:          0 :             (u8)(type |
     806                 :            :                  (is_raw_handler ? ACPI_GPE_DISPATCH_RAW_HANDLER :
     807                 :            :                   ACPI_GPE_DISPATCH_HANDLER));
     808                 :            : 
     809                 :          0 :         acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
     810                 :            : 
     811                 :          0 : unlock_and_exit:
     812                 :          0 :         (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
     813                 :          0 :         return_ACPI_STATUS(status);
     814                 :            : 
     815                 :          0 : free_and_exit:
     816                 :          0 :         acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
     817                 :          0 :         ACPI_FREE(handler);
     818                 :          0 :         goto unlock_and_exit;
     819                 :            : }
     820                 :            : 
     821                 :            : /*******************************************************************************
     822                 :            :  *
     823                 :            :  * FUNCTION:    acpi_install_gpe_handler
     824                 :            :  *
     825                 :            :  * PARAMETERS:  gpe_device      - Namespace node for the GPE (NULL for FADT
     826                 :            :  *                                defined GPEs)
     827                 :            :  *              gpe_number      - The GPE number within the GPE block
     828                 :            :  *              type            - Whether this GPE should be treated as an
     829                 :            :  *                                edge- or level-triggered interrupt.
     830                 :            :  *              address         - Address of the handler
     831                 :            :  *              context         - Value passed to the handler on each GPE
     832                 :            :  *
     833                 :            :  * RETURN:      Status
     834                 :            :  *
     835                 :            :  * DESCRIPTION: Install a handler for a General Purpose Event.
     836                 :            :  *
     837                 :            :  ******************************************************************************/
     838                 :            : 
     839                 :            : acpi_status
     840                 :          0 : acpi_install_gpe_handler(acpi_handle gpe_device,
     841                 :            :                          u32 gpe_number,
     842                 :            :                          u32 type, acpi_gpe_handler address, void *context)
     843                 :            : {
     844                 :          0 :         acpi_status status;
     845                 :            : 
     846                 :          0 :         ACPI_FUNCTION_TRACE(acpi_install_gpe_handler);
     847                 :            : 
     848                 :          0 :         status = acpi_ev_install_gpe_handler(gpe_device, gpe_number, type,
     849                 :            :                                              FALSE, address, context);
     850                 :            : 
     851                 :          0 :         return_ACPI_STATUS(status);
     852                 :            : }
     853                 :            : 
     854                 :            : ACPI_EXPORT_SYMBOL(acpi_install_gpe_handler)
     855                 :            : 
     856                 :            : /*******************************************************************************
     857                 :            :  *
     858                 :            :  * FUNCTION:    acpi_install_gpe_raw_handler
     859                 :            :  *
     860                 :            :  * PARAMETERS:  gpe_device      - Namespace node for the GPE (NULL for FADT
     861                 :            :  *                                defined GPEs)
     862                 :            :  *              gpe_number      - The GPE number within the GPE block
     863                 :            :  *              type            - Whether this GPE should be treated as an
     864                 :            :  *                                edge- or level-triggered interrupt.
     865                 :            :  *              address         - Address of the handler
     866                 :            :  *              context         - Value passed to the handler on each GPE
     867                 :            :  *
     868                 :            :  * RETURN:      Status
     869                 :            :  *
     870                 :            :  * DESCRIPTION: Install a handler for a General Purpose Event.
     871                 :            :  *
     872                 :            :  ******************************************************************************/
     873                 :            : acpi_status
     874                 :          0 : acpi_install_gpe_raw_handler(acpi_handle gpe_device,
     875                 :            :                              u32 gpe_number,
     876                 :            :                              u32 type, acpi_gpe_handler address, void *context)
     877                 :            : {
     878                 :          0 :         acpi_status status;
     879                 :            : 
     880                 :          0 :         ACPI_FUNCTION_TRACE(acpi_install_gpe_raw_handler);
     881                 :            : 
     882                 :          0 :         status = acpi_ev_install_gpe_handler(gpe_device, gpe_number, type,
     883                 :            :                                              TRUE, address, context);
     884                 :            : 
     885                 :          0 :         return_ACPI_STATUS(status);
     886                 :            : }
     887                 :            : 
     888                 :            : ACPI_EXPORT_SYMBOL(acpi_install_gpe_raw_handler)
     889                 :            : 
     890                 :            : /*******************************************************************************
     891                 :            :  *
     892                 :            :  * FUNCTION:    acpi_remove_gpe_handler
     893                 :            :  *
     894                 :            :  * PARAMETERS:  gpe_device      - Namespace node for the GPE (NULL for FADT
     895                 :            :  *                                defined GPEs)
     896                 :            :  *              gpe_number      - The event to remove a handler
     897                 :            :  *              address         - Address of the handler
     898                 :            :  *
     899                 :            :  * RETURN:      Status
     900                 :            :  *
     901                 :            :  * DESCRIPTION: Remove a handler for a General Purpose acpi_event.
     902                 :            :  *
     903                 :            :  ******************************************************************************/
     904                 :            : acpi_status
     905                 :          0 : acpi_remove_gpe_handler(acpi_handle gpe_device,
     906                 :            :                         u32 gpe_number, acpi_gpe_handler address)
     907                 :            : {
     908                 :          0 :         struct acpi_gpe_event_info *gpe_event_info;
     909                 :          0 :         struct acpi_gpe_handler_info *handler;
     910                 :          0 :         acpi_status status;
     911                 :          0 :         acpi_cpu_flags flags;
     912                 :            : 
     913                 :          0 :         ACPI_FUNCTION_TRACE(acpi_remove_gpe_handler);
     914                 :            : 
     915                 :            :         /* Parameter validation */
     916                 :            : 
     917         [ #  # ]:          0 :         if (!address) {
     918                 :            :                 return_ACPI_STATUS(AE_BAD_PARAMETER);
     919                 :            :         }
     920                 :            : 
     921                 :          0 :         status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
     922         [ #  # ]:          0 :         if (ACPI_FAILURE(status)) {
     923                 :            :                 return_ACPI_STATUS(status);
     924                 :            :         }
     925                 :            : 
     926                 :          0 :         flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
     927                 :            : 
     928                 :            :         /* Ensure that we have a valid GPE number */
     929                 :            : 
     930                 :          0 :         gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
     931         [ #  # ]:          0 :         if (!gpe_event_info) {
     932                 :          0 :                 status = AE_BAD_PARAMETER;
     933                 :          0 :                 goto unlock_and_exit;
     934                 :            :         }
     935                 :            : 
     936                 :            :         /* Make sure that a handler is indeed installed */
     937                 :            : 
     938                 :          0 :         if ((ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) !=
     939         [ #  # ]:          0 :              ACPI_GPE_DISPATCH_HANDLER) &&
     940                 :            :             (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) !=
     941                 :            :              ACPI_GPE_DISPATCH_RAW_HANDLER)) {
     942                 :          0 :                 status = AE_NOT_EXIST;
     943                 :          0 :                 goto unlock_and_exit;
     944                 :            :         }
     945                 :            : 
     946                 :            :         /* Make sure that the installed handler is the same */
     947                 :            : 
     948         [ #  # ]:          0 :         if (gpe_event_info->dispatch.handler->address != address) {
     949                 :          0 :                 status = AE_BAD_PARAMETER;
     950                 :          0 :                 goto unlock_and_exit;
     951                 :            :         }
     952                 :            : 
     953                 :            :         /* Remove the handler */
     954                 :            : 
     955                 :          0 :         handler = gpe_event_info->dispatch.handler;
     956                 :          0 :         gpe_event_info->dispatch.handler = NULL;
     957                 :            : 
     958                 :            :         /* Restore Method node (if any), set dispatch flags */
     959                 :            : 
     960                 :          0 :         gpe_event_info->dispatch.method_node = handler->method_node;
     961                 :          0 :         gpe_event_info->flags &=
     962                 :            :             ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK);
     963                 :          0 :         gpe_event_info->flags |= handler->original_flags;
     964                 :            : 
     965                 :            :         /*
     966                 :            :          * If the GPE was previously associated with a method and it was
     967                 :            :          * enabled, it should be enabled at this point to restore the
     968                 :            :          * post-initialization configuration.
     969                 :            :          */
     970                 :          0 :         if (((ACPI_GPE_DISPATCH_TYPE(handler->original_flags) ==
     971         [ #  # ]:          0 :               ACPI_GPE_DISPATCH_METHOD) ||
     972                 :            :              (ACPI_GPE_DISPATCH_TYPE(handler->original_flags) ==
     973         [ #  # ]:          0 :               ACPI_GPE_DISPATCH_NOTIFY)) && handler->originally_enabled) {
     974                 :          0 :                 (void)acpi_ev_add_gpe_reference(gpe_event_info, FALSE);
     975   [ #  #  #  # ]:          0 :                 if (ACPI_GPE_IS_POLLING_NEEDED(gpe_event_info)) {
     976                 :            : 
     977                 :            :                         /* Poll edge triggered GPEs to handle existing events */
     978                 :            : 
     979                 :          0 :                         acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
     980                 :          0 :                         (void)acpi_ev_detect_gpe(gpe_device, gpe_event_info,
     981                 :            :                                                  gpe_number);
     982                 :          0 :                         flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
     983                 :            :                 }
     984                 :            :         }
     985                 :            : 
     986                 :          0 :         acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
     987                 :          0 :         (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
     988                 :            : 
     989                 :            :         /* Make sure all deferred GPE tasks are completed */
     990                 :            : 
     991                 :          0 :         acpi_os_wait_events_complete();
     992                 :            : 
     993                 :            :         /* Now we can free the handler object */
     994                 :            : 
     995                 :          0 :         ACPI_FREE(handler);
     996                 :          0 :         return_ACPI_STATUS(status);
     997                 :            : 
     998                 :          0 : unlock_and_exit:
     999                 :          0 :         acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
    1000                 :            : 
    1001                 :          0 :         (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
    1002                 :          0 :         return_ACPI_STATUS(status);
    1003                 :            : }
    1004                 :            : 
    1005                 :            : ACPI_EXPORT_SYMBOL(acpi_remove_gpe_handler)
    1006                 :            : 
    1007                 :            : /*******************************************************************************
    1008                 :            :  *
    1009                 :            :  * FUNCTION:    acpi_acquire_global_lock
    1010                 :            :  *
    1011                 :            :  * PARAMETERS:  timeout         - How long the caller is willing to wait
    1012                 :            :  *              handle          - Where the handle to the lock is returned
    1013                 :            :  *                                (if acquired)
    1014                 :            :  *
    1015                 :            :  * RETURN:      Status
    1016                 :            :  *
    1017                 :            :  * DESCRIPTION: Acquire the ACPI Global Lock
    1018                 :            :  *
    1019                 :            :  * Note: Allows callers with the same thread ID to acquire the global lock
    1020                 :            :  * multiple times. In other words, externally, the behavior of the global lock
    1021                 :            :  * is identical to an AML mutex. On the first acquire, a new handle is
    1022                 :            :  * returned. On any subsequent calls to acquire by the same thread, the same
    1023                 :            :  * handle is returned.
    1024                 :            :  *
    1025                 :            :  ******************************************************************************/
    1026                 :          0 : acpi_status acpi_acquire_global_lock(u16 timeout, u32 *handle)
    1027                 :            : {
    1028                 :          0 :         acpi_status status;
    1029                 :            : 
    1030         [ #  # ]:          0 :         if (!handle) {
    1031                 :            :                 return (AE_BAD_PARAMETER);
    1032                 :            :         }
    1033                 :            : 
    1034                 :            :         /* Must lock interpreter to prevent race conditions */
    1035                 :            : 
    1036                 :          0 :         acpi_ex_enter_interpreter();
    1037                 :            : 
    1038                 :          0 :         status = acpi_ex_acquire_mutex_object(timeout,
    1039                 :            :                                               acpi_gbl_global_lock_mutex,
    1040                 :            :                                               acpi_os_get_thread_id());
    1041                 :            : 
    1042         [ #  # ]:          0 :         if (ACPI_SUCCESS(status)) {
    1043                 :            : 
    1044                 :            :                 /* Return the global lock handle (updated in acpi_ev_acquire_global_lock) */
    1045                 :            : 
    1046                 :          0 :                 *handle = acpi_gbl_global_lock_handle;
    1047                 :            :         }
    1048                 :            : 
    1049                 :          0 :         acpi_ex_exit_interpreter();
    1050                 :          0 :         return (status);
    1051                 :            : }
    1052                 :            : 
    1053                 :            : ACPI_EXPORT_SYMBOL(acpi_acquire_global_lock)
    1054                 :            : 
    1055                 :            : /*******************************************************************************
    1056                 :            :  *
    1057                 :            :  * FUNCTION:    acpi_release_global_lock
    1058                 :            :  *
    1059                 :            :  * PARAMETERS:  handle      - Returned from acpi_acquire_global_lock
    1060                 :            :  *
    1061                 :            :  * RETURN:      Status
    1062                 :            :  *
    1063                 :            :  * DESCRIPTION: Release the ACPI Global Lock. The handle must be valid.
    1064                 :            :  *
    1065                 :            :  ******************************************************************************/
    1066                 :          0 : acpi_status acpi_release_global_lock(u32 handle)
    1067                 :            : {
    1068                 :          0 :         acpi_status status;
    1069                 :            : 
    1070   [ #  #  #  # ]:          0 :         if (!handle || (handle != acpi_gbl_global_lock_handle)) {
    1071                 :            :                 return (AE_NOT_ACQUIRED);
    1072                 :            :         }
    1073                 :            : 
    1074                 :          0 :         status = acpi_ex_release_mutex_object(acpi_gbl_global_lock_mutex);
    1075                 :          0 :         return (status);
    1076                 :            : }
    1077                 :            : 
    1078                 :            : ACPI_EXPORT_SYMBOL(acpi_release_global_lock)
    1079                 :            : #endif                          /* !ACPI_REDUCED_HARDWARE */

Generated by: LCOV version 1.14