root/drivers/acpi/acpica/evmisc.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ACPI_MODULE_NAME
  2. acpi_ev_queue_notify_request
  3. acpi_ev_notify_dispatch
  4. acpi_ev_terminate

   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 - 2019, 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 u8 acpi_ev_is_notify_object(struct acpi_namespace_node *node)
  36 {
  37 
  38         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         default:
  48 
  49                 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 acpi_ev_queue_notify_request(struct acpi_namespace_node *node, u32 notify_value)
  69 {
  70         union acpi_operand_object *obj_desc;
  71         union acpi_operand_object *handler_list_head = NULL;
  72         union acpi_generic_state *info;
  73         u8 handler_list_id = 0;
  74         acpi_status status = AE_OK;
  75 
  76         ACPI_FUNCTION_NAME(ev_queue_notify_request);
  77 
  78         /* Are Notifies allowed on this object? */
  79 
  80         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         if (notify_value <= ACPI_MAX_SYS_NOTIFY) {
  87                 handler_list_id = ACPI_SYSTEM_HANDLER_LIST;
  88         } else {
  89                 handler_list_id = ACPI_DEVICE_HANDLER_LIST;
  90         }
  91 
  92         /* Get the notify object attached to the namespace Node */
  93 
  94         obj_desc = acpi_ns_get_attached_object(node);
  95         if (obj_desc) {
  96 
  97                 /* We have an attached object, Get the correct handler list */
  98 
  99                 handler_list_head =
 100                     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         if (!acpi_gbl_global_notify[handler_list_id].handler
 108             && !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         info = acpi_ut_create_generic_state();
 120         if (!info) {
 121                 return (AE_NO_MEMORY);
 122         }
 123 
 124         info->common.descriptor_type = ACPI_DESC_TYPE_STATE_NOTIFY;
 125 
 126         info->notify.node = node;
 127         info->notify.value = (u16)notify_value;
 128         info->notify.handler_list_id = handler_list_id;
 129         info->notify.handler_list_head = handler_list_head;
 130         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                           node));
 138 
 139         status = acpi_os_execute(OSL_NOTIFY_HANDLER,
 140                                  acpi_ev_notify_dispatch, info);
 141         if (ACPI_FAILURE(status)) {
 142                 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 static void ACPI_SYSTEM_XFACE acpi_ev_notify_dispatch(void *context)
 162 {
 163         union acpi_generic_state *info = (union acpi_generic_state *)context;
 164         union acpi_operand_object *handler_obj;
 165 
 166         ACPI_FUNCTION_ENTRY();
 167 
 168         /* Invoke a global notify handler if installed */
 169 
 170         if (info->notify.global->handler) {
 171                 info->notify.global->handler(info->notify.node,
 172                                              info->notify.value,
 173                                              info->notify.global->context);
 174         }
 175 
 176         /* Now invoke the local notify handler(s) if any are installed */
 177 
 178         handler_obj = info->notify.handler_list_head;
 179         while (handler_obj) {
 180                 handler_obj->notify.handler(info->notify.node,
 181                                             info->notify.value,
 182                                             handler_obj->notify.context);
 183 
 184                 handler_obj =
 185                     handler_obj->notify.next[info->notify.handler_list_id];
 186         }
 187 
 188         /* All done with the info object */
 189 
 190         acpi_ut_delete_generic_state(info);
 191 }
 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 void acpi_ev_terminate(void)
 207 {
 208         u32 i;
 209         acpi_status status;
 210 
 211         ACPI_FUNCTION_TRACE(ev_terminate);
 212 
 213         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                 for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) {
 222                         status = acpi_disable_event(i, 0);
 223                         if (ACPI_FAILURE(status)) {
 224                                 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                 status = acpi_ev_walk_gpe_list(acpi_hw_disable_gpe_block, NULL);
 233 
 234                 status = acpi_ev_remove_global_lock_handler();
 235                 if (ACPI_FAILURE(status)) {
 236                         ACPI_ERROR((AE_INFO,
 237                                     "Could not remove Global Lock handler"));
 238                 }
 239 
 240                 acpi_gbl_events_initialized = FALSE;
 241         }
 242 
 243         /* Remove SCI handlers */
 244 
 245         status = acpi_ev_remove_all_sci_handlers();
 246         if (ACPI_FAILURE(status)) {
 247                 ACPI_ERROR((AE_INFO, "Could not remove SCI handler"));
 248         }
 249 
 250         /* Deallocate all handler objects installed within GPE info structs */
 251 
 252         status = acpi_ev_walk_gpe_list(acpi_ev_delete_gpe_handlers, NULL);
 253 
 254         /* Return to original mode if necessary */
 255 
 256         if (acpi_gbl_original_mode == ACPI_SYS_MODE_LEGACY) {
 257                 status = acpi_disable();
 258                 if (ACPI_FAILURE(status)) {
 259                         ACPI_WARNING((AE_INFO, "AcpiDisable failed"));
 260                 }
 261         }
 262         return_VOID;
 263 }
 264 
 265 #endif                          /* !ACPI_REDUCED_HARDWARE */

/* [<][>][^][v][top][bottom][index][help] */