LCOV - code coverage report
Current view: top level - drivers/acpi/acpica - evmisc.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 2 74 2.7 %
Date: 2022-04-01 14:58:12 Functions: 1 4 25.0 %
Branches: 1 38 2.6 %

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
       2                 :            : /******************************************************************************
       3                 :            :  *
       4                 :            :  * Module Name: evmisc - Miscellaneous event manager support functions
       5                 :            :  *
       6                 :            :  * Copyright (C) 2000 - 2020, Intel Corp.
       7                 :            :  *
       8                 :            :  *****************************************************************************/
       9                 :            : 
      10                 :            : #include <acpi/acpi.h>
      11                 :            : #include "accommon.h"
      12                 :            : #include "acevents.h"
      13                 :            : #include "acnamesp.h"
      14                 :            : 
      15                 :            : #define _COMPONENT          ACPI_EVENTS
      16                 :            : ACPI_MODULE_NAME("evmisc")
      17                 :            : 
      18                 :            : /* Local prototypes */
      19                 :            : static void ACPI_SYSTEM_XFACE acpi_ev_notify_dispatch(void *context);
      20                 :            : 
      21                 :            : /*******************************************************************************
      22                 :            :  *
      23                 :            :  * FUNCTION:    acpi_ev_is_notify_object
      24                 :            :  *
      25                 :            :  * PARAMETERS:  node            - Node to check
      26                 :            :  *
      27                 :            :  * RETURN:      TRUE if notifies allowed on this object
      28                 :            :  *
      29                 :            :  * DESCRIPTION: Check type of node for a object that supports notifies.
      30                 :            :  *
      31                 :            :  *              TBD: This could be replaced by a flag bit in the node.
      32                 :            :  *
      33                 :            :  ******************************************************************************/
      34                 :            : 
      35                 :         27 : u8 acpi_ev_is_notify_object(struct acpi_namespace_node *node)
      36                 :            : {
      37                 :            : 
      38         [ -  + ]:         27 :         switch (node->type) {
      39                 :            :         case ACPI_TYPE_DEVICE:
      40                 :            :         case ACPI_TYPE_PROCESSOR:
      41                 :            :         case ACPI_TYPE_THERMAL:
      42                 :            :                 /*
      43                 :            :                  * These are the ONLY objects that can receive ACPI notifications
      44                 :            :                  */
      45                 :            :                 return (TRUE);
      46                 :            : 
      47                 :          0 :         default:
      48                 :            : 
      49                 :          0 :                 return (FALSE);
      50                 :            :         }
      51                 :            : }
      52                 :            : 
      53                 :            : /*******************************************************************************
      54                 :            :  *
      55                 :            :  * FUNCTION:    acpi_ev_queue_notify_request
      56                 :            :  *
      57                 :            :  * PARAMETERS:  node            - NS node for the notified object
      58                 :            :  *              notify_value    - Value from the Notify() request
      59                 :            :  *
      60                 :            :  * RETURN:      Status
      61                 :            :  *
      62                 :            :  * DESCRIPTION: Dispatch a device notification event to a previously
      63                 :            :  *              installed handler.
      64                 :            :  *
      65                 :            :  ******************************************************************************/
      66                 :            : 
      67                 :            : acpi_status
      68                 :          0 : acpi_ev_queue_notify_request(struct acpi_namespace_node *node, u32 notify_value)
      69                 :            : {
      70                 :          0 :         union acpi_operand_object *obj_desc;
      71                 :          0 :         union acpi_operand_object *handler_list_head = NULL;
      72                 :          0 :         union acpi_generic_state *info;
      73                 :          0 :         u8 handler_list_id = 0;
      74                 :          0 :         acpi_status status = AE_OK;
      75                 :            : 
      76                 :          0 :         ACPI_FUNCTION_NAME(ev_queue_notify_request);
      77                 :            : 
      78                 :            :         /* Are Notifies allowed on this object? */
      79                 :            : 
      80         [ #  # ]:          0 :         if (!acpi_ev_is_notify_object(node)) {
      81                 :            :                 return (AE_TYPE);
      82                 :            :         }
      83                 :            : 
      84                 :            :         /* Get the correct notify list type (System or Device) */
      85                 :            : 
      86         [ #  # ]:          0 :         if (notify_value <= ACPI_MAX_SYS_NOTIFY) {
      87                 :            :                 handler_list_id = ACPI_SYSTEM_HANDLER_LIST;
      88                 :            :         } else {
      89                 :          0 :                 handler_list_id = ACPI_DEVICE_HANDLER_LIST;
      90                 :            :         }
      91                 :            : 
      92                 :            :         /* Get the notify object attached to the namespace Node */
      93                 :            : 
      94                 :          0 :         obj_desc = acpi_ns_get_attached_object(node);
      95         [ #  # ]:          0 :         if (obj_desc) {
      96                 :            : 
      97                 :            :                 /* We have an attached object, Get the correct handler list */
      98                 :            : 
      99                 :          0 :                 handler_list_head =
     100                 :          0 :                     obj_desc->common_notify.notify_list[handler_list_id];
     101                 :            :         }
     102                 :            : 
     103                 :            :         /*
     104                 :            :          * If there is no notify handler (Global or Local)
     105                 :            :          * for this object, just ignore the notify
     106                 :            :          */
     107         [ #  # ]:          0 :         if (!acpi_gbl_global_notify[handler_list_id].handler
     108         [ #  # ]:          0 :             && !handler_list_head) {
     109                 :            :                 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
     110                 :            :                                   "No notify handler for Notify, ignoring (%4.4s, %X) node %p\n",
     111                 :            :                                   acpi_ut_get_node_name(node), notify_value,
     112                 :            :                                   node));
     113                 :            : 
     114                 :            :                 return (AE_OK);
     115                 :            :         }
     116                 :            : 
     117                 :            :         /* Setup notify info and schedule the notify dispatcher */
     118                 :            : 
     119                 :          0 :         info = acpi_ut_create_generic_state();
     120         [ #  # ]:          0 :         if (!info) {
     121                 :            :                 return (AE_NO_MEMORY);
     122                 :            :         }
     123                 :            : 
     124                 :          0 :         info->common.descriptor_type = ACPI_DESC_TYPE_STATE_NOTIFY;
     125                 :            : 
     126                 :          0 :         info->notify.node = node;
     127                 :          0 :         info->notify.value = (u16)notify_value;
     128                 :          0 :         info->notify.handler_list_id = handler_list_id;
     129                 :          0 :         info->notify.handler_list_head = handler_list_head;
     130                 :          0 :         info->notify.global = &acpi_gbl_global_notify[handler_list_id];
     131                 :            : 
     132                 :            :         ACPI_DEBUG_PRINT((ACPI_DB_INFO,
     133                 :            :                           "Dispatching Notify on [%4.4s] (%s) Value 0x%2.2X (%s) Node %p\n",
     134                 :            :                           acpi_ut_get_node_name(node),
     135                 :            :                           acpi_ut_get_type_name(node->type), notify_value,
     136                 :            :                           acpi_ut_get_notify_name(notify_value, ACPI_TYPE_ANY),
     137                 :          0 :                           node));
     138                 :            : 
     139                 :          0 :         status = acpi_os_execute(OSL_NOTIFY_HANDLER,
     140                 :            :                                  acpi_ev_notify_dispatch, info);
     141         [ #  # ]:          0 :         if (ACPI_FAILURE(status)) {
     142                 :          0 :                 acpi_ut_delete_generic_state(info);
     143                 :            :         }
     144                 :            : 
     145                 :            :         return (status);
     146                 :            : }
     147                 :            : 
     148                 :            : /*******************************************************************************
     149                 :            :  *
     150                 :            :  * FUNCTION:    acpi_ev_notify_dispatch
     151                 :            :  *
     152                 :            :  * PARAMETERS:  context         - To be passed to the notify handler
     153                 :            :  *
     154                 :            :  * RETURN:      None.
     155                 :            :  *
     156                 :            :  * DESCRIPTION: Dispatch a device notification event to a previously
     157                 :            :  *              installed handler.
     158                 :            :  *
     159                 :            :  ******************************************************************************/
     160                 :            : 
     161                 :          0 : static void ACPI_SYSTEM_XFACE acpi_ev_notify_dispatch(void *context)
     162                 :            : {
     163                 :          0 :         union acpi_generic_state *info = (union acpi_generic_state *)context;
     164                 :          0 :         union acpi_operand_object *handler_obj;
     165                 :            : 
     166                 :          0 :         ACPI_FUNCTION_ENTRY();
     167                 :            : 
     168                 :            :         /* Invoke a global notify handler if installed */
     169                 :            : 
     170         [ #  # ]:          0 :         if (info->notify.global->handler) {
     171                 :          0 :                 info->notify.global->handler(info->notify.node,
     172                 :          0 :                                              info->notify.value,
     173                 :            :                                              info->notify.global->context);
     174                 :            :         }
     175                 :            : 
     176                 :            :         /* Now invoke the local notify handler(s) if any are installed */
     177                 :            : 
     178                 :          0 :         handler_obj = info->notify.handler_list_head;
     179         [ #  # ]:          0 :         while (handler_obj) {
     180                 :          0 :                 handler_obj->notify.handler(info->notify.node,
     181                 :          0 :                                             info->notify.value,
     182                 :            :                                             handler_obj->notify.context);
     183                 :            : 
     184                 :          0 :                 handler_obj =
     185                 :          0 :                     handler_obj->notify.next[info->notify.handler_list_id];
     186                 :            :         }
     187                 :            : 
     188                 :            :         /* All done with the info object */
     189                 :            : 
     190                 :          0 :         acpi_ut_delete_generic_state(info);
     191                 :          0 : }
     192                 :            : 
     193                 :            : #if (!ACPI_REDUCED_HARDWARE)
     194                 :            : /******************************************************************************
     195                 :            :  *
     196                 :            :  * FUNCTION:    acpi_ev_terminate
     197                 :            :  *
     198                 :            :  * PARAMETERS:  none
     199                 :            :  *
     200                 :            :  * RETURN:      none
     201                 :            :  *
     202                 :            :  * DESCRIPTION: Disable events and free memory allocated for table storage.
     203                 :            :  *
     204                 :            :  ******************************************************************************/
     205                 :            : 
     206                 :          0 : void acpi_ev_terminate(void)
     207                 :            : {
     208                 :          0 :         u32 i;
     209                 :          0 :         acpi_status status;
     210                 :            : 
     211                 :          0 :         ACPI_FUNCTION_TRACE(ev_terminate);
     212                 :            : 
     213         [ #  # ]:          0 :         if (acpi_gbl_events_initialized) {
     214                 :            :                 /*
     215                 :            :                  * Disable all event-related functionality. In all cases, on error,
     216                 :            :                  * print a message but obviously we don't abort.
     217                 :            :                  */
     218                 :            : 
     219                 :            :                 /* Disable all fixed events */
     220                 :            : 
     221         [ #  # ]:          0 :                 for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) {
     222                 :          0 :                         status = acpi_disable_event(i, 0);
     223         [ #  # ]:          0 :                         if (ACPI_FAILURE(status)) {
     224                 :          0 :                                 ACPI_ERROR((AE_INFO,
     225                 :            :                                             "Could not disable fixed event %u",
     226                 :            :                                             (u32) i));
     227                 :            :                         }
     228                 :            :                 }
     229                 :            : 
     230                 :            :                 /* Disable all GPEs in all GPE blocks */
     231                 :            : 
     232                 :          0 :                 status = acpi_ev_walk_gpe_list(acpi_hw_disable_gpe_block, NULL);
     233         [ #  # ]:          0 :                 if (ACPI_FAILURE(status)) {
     234                 :          0 :                         ACPI_EXCEPTION((AE_INFO, status,
     235                 :            :                                         "Could not disable GPEs in GPE block"));
     236                 :            :                 }
     237                 :            : 
     238                 :          0 :                 status = acpi_ev_remove_global_lock_handler();
     239         [ #  # ]:          0 :                 if (ACPI_FAILURE(status)) {
     240                 :          0 :                         ACPI_EXCEPTION((AE_INFO, status,
     241                 :            :                                         "Could not remove Global Lock handler"));
     242                 :            :                 }
     243                 :            : 
     244                 :          0 :                 acpi_gbl_events_initialized = FALSE;
     245                 :            :         }
     246                 :            : 
     247                 :            :         /* Remove SCI handlers */
     248                 :            : 
     249                 :          0 :         status = acpi_ev_remove_all_sci_handlers();
     250         [ #  # ]:          0 :         if (ACPI_FAILURE(status)) {
     251                 :          0 :                 ACPI_ERROR((AE_INFO, "Could not remove SCI handler"));
     252                 :            :         }
     253                 :            : 
     254                 :            :         /* Deallocate all handler objects installed within GPE info structs */
     255                 :            : 
     256                 :          0 :         status = acpi_ev_walk_gpe_list(acpi_ev_delete_gpe_handlers, NULL);
     257         [ #  # ]:          0 :         if (ACPI_FAILURE(status)) {
     258                 :          0 :                 ACPI_EXCEPTION((AE_INFO, status,
     259                 :            :                                 "Could not delete GPE handlers"));
     260                 :            :         }
     261                 :            : 
     262                 :            :         /* Return to original mode if necessary */
     263                 :            : 
     264         [ #  # ]:          0 :         if (acpi_gbl_original_mode == ACPI_SYS_MODE_LEGACY) {
     265                 :          0 :                 status = acpi_disable();
     266         [ #  # ]:          0 :                 if (ACPI_FAILURE(status)) {
     267                 :          0 :                         ACPI_WARNING((AE_INFO, "AcpiDisable failed"));
     268                 :            :                 }
     269                 :            :         }
     270                 :          0 :         return_VOID;
     271                 :            : }
     272                 :            : 
     273                 :            : #endif                          /* !ACPI_REDUCED_HARDWARE */

Generated by: LCOV version 1.14