root/drivers/acpi/acpica/evevent.c

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

DEFINITIONS

This source file includes following definitions.
  1. ACPI_MODULE_NAME
  2. acpi_ev_install_xrupt_handlers
  3. acpi_ev_fixed_event_initialize
  4. acpi_ev_fixed_event_detect
  5. acpi_ev_fixed_event_dispatch
  6. acpi_any_fixed_event_status_set

   1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
   2 /******************************************************************************
   3  *
   4  * Module Name: evevent - Fixed Event handling and dispatch
   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 
  14 #define _COMPONENT          ACPI_EVENTS
  15 ACPI_MODULE_NAME("evevent")
  16 #if (!ACPI_REDUCED_HARDWARE)    /* Entire module */
  17 /* Local prototypes */
  18 static acpi_status acpi_ev_fixed_event_initialize(void);
  19 
  20 static u32 acpi_ev_fixed_event_dispatch(u32 event);
  21 
  22 /*******************************************************************************
  23  *
  24  * FUNCTION:    acpi_ev_initialize_events
  25  *
  26  * PARAMETERS:  None
  27  *
  28  * RETURN:      Status
  29  *
  30  * DESCRIPTION: Initialize global data structures for ACPI events (Fixed, GPE)
  31  *
  32  ******************************************************************************/
  33 
  34 acpi_status acpi_ev_initialize_events(void)
  35 {
  36         acpi_status status;
  37 
  38         ACPI_FUNCTION_TRACE(ev_initialize_events);
  39 
  40         /* If Hardware Reduced flag is set, there are no fixed events */
  41 
  42         if (acpi_gbl_reduced_hardware) {
  43                 return_ACPI_STATUS(AE_OK);
  44         }
  45 
  46         /*
  47          * Initialize the Fixed and General Purpose Events. This is done prior to
  48          * enabling SCIs to prevent interrupts from occurring before the handlers
  49          * are installed.
  50          */
  51         status = acpi_ev_fixed_event_initialize();
  52         if (ACPI_FAILURE(status)) {
  53                 ACPI_EXCEPTION((AE_INFO, status,
  54                                 "Unable to initialize fixed events"));
  55                 return_ACPI_STATUS(status);
  56         }
  57 
  58         status = acpi_ev_gpe_initialize();
  59         if (ACPI_FAILURE(status)) {
  60                 ACPI_EXCEPTION((AE_INFO, status,
  61                                 "Unable to initialize general purpose events"));
  62                 return_ACPI_STATUS(status);
  63         }
  64 
  65         return_ACPI_STATUS(status);
  66 }
  67 
  68 /*******************************************************************************
  69  *
  70  * FUNCTION:    acpi_ev_install_xrupt_handlers
  71  *
  72  * PARAMETERS:  None
  73  *
  74  * RETURN:      Status
  75  *
  76  * DESCRIPTION: Install interrupt handlers for the SCI and Global Lock
  77  *
  78  ******************************************************************************/
  79 
  80 acpi_status acpi_ev_install_xrupt_handlers(void)
  81 {
  82         acpi_status status;
  83 
  84         ACPI_FUNCTION_TRACE(ev_install_xrupt_handlers);
  85 
  86         /* If Hardware Reduced flag is set, there is no ACPI h/w */
  87 
  88         if (acpi_gbl_reduced_hardware) {
  89                 return_ACPI_STATUS(AE_OK);
  90         }
  91 
  92         /* Install the SCI handler */
  93 
  94         status = acpi_ev_install_sci_handler();
  95         if (ACPI_FAILURE(status)) {
  96                 ACPI_EXCEPTION((AE_INFO, status,
  97                                 "Unable to install System Control Interrupt handler"));
  98                 return_ACPI_STATUS(status);
  99         }
 100 
 101         /* Install the handler for the Global Lock */
 102 
 103         status = acpi_ev_init_global_lock_handler();
 104         if (ACPI_FAILURE(status)) {
 105                 ACPI_EXCEPTION((AE_INFO, status,
 106                                 "Unable to initialize Global Lock handler"));
 107                 return_ACPI_STATUS(status);
 108         }
 109 
 110         acpi_gbl_events_initialized = TRUE;
 111         return_ACPI_STATUS(status);
 112 }
 113 
 114 /*******************************************************************************
 115  *
 116  * FUNCTION:    acpi_ev_fixed_event_initialize
 117  *
 118  * PARAMETERS:  None
 119  *
 120  * RETURN:      Status
 121  *
 122  * DESCRIPTION: Install the fixed event handlers and disable all fixed events.
 123  *
 124  ******************************************************************************/
 125 
 126 static acpi_status acpi_ev_fixed_event_initialize(void)
 127 {
 128         u32 i;
 129         acpi_status status;
 130 
 131         /*
 132          * Initialize the structure that keeps track of fixed event handlers and
 133          * enable the fixed events.
 134          */
 135         for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) {
 136                 acpi_gbl_fixed_event_handlers[i].handler = NULL;
 137                 acpi_gbl_fixed_event_handlers[i].context = NULL;
 138 
 139                 /* Disable the fixed event */
 140 
 141                 if (acpi_gbl_fixed_event_info[i].enable_register_id != 0xFF) {
 142                         status =
 143                             acpi_write_bit_register(acpi_gbl_fixed_event_info
 144                                                     [i].enable_register_id,
 145                                                     ACPI_DISABLE_EVENT);
 146                         if (ACPI_FAILURE(status)) {
 147                                 return (status);
 148                         }
 149                 }
 150         }
 151 
 152         return (AE_OK);
 153 }
 154 
 155 /*******************************************************************************
 156  *
 157  * FUNCTION:    acpi_ev_fixed_event_detect
 158  *
 159  * PARAMETERS:  None
 160  *
 161  * RETURN:      INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED
 162  *
 163  * DESCRIPTION: Checks the PM status register for active fixed events
 164  *
 165  ******************************************************************************/
 166 
 167 u32 acpi_ev_fixed_event_detect(void)
 168 {
 169         u32 int_status = ACPI_INTERRUPT_NOT_HANDLED;
 170         u32 fixed_status;
 171         u32 fixed_enable;
 172         u32 i;
 173         acpi_status status;
 174 
 175         ACPI_FUNCTION_NAME(ev_fixed_event_detect);
 176 
 177         /*
 178          * Read the fixed feature status and enable registers, as all the cases
 179          * depend on their values. Ignore errors here.
 180          */
 181         status = acpi_hw_register_read(ACPI_REGISTER_PM1_STATUS, &fixed_status);
 182         status |=
 183             acpi_hw_register_read(ACPI_REGISTER_PM1_ENABLE, &fixed_enable);
 184         if (ACPI_FAILURE(status)) {
 185                 return (int_status);
 186         }
 187 
 188         ACPI_DEBUG_PRINT((ACPI_DB_INTERRUPTS,
 189                           "Fixed Event Block: Enable %08X Status %08X\n",
 190                           fixed_enable, fixed_status));
 191 
 192         /*
 193          * Check for all possible Fixed Events and dispatch those that are active
 194          */
 195         for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) {
 196 
 197                 /* Both the status and enable bits must be on for this event */
 198 
 199                 if ((fixed_status & acpi_gbl_fixed_event_info[i].
 200                      status_bit_mask)
 201                     && (fixed_enable & acpi_gbl_fixed_event_info[i].
 202                         enable_bit_mask)) {
 203                         /*
 204                          * Found an active (signalled) event. Invoke global event
 205                          * handler if present.
 206                          */
 207                         acpi_fixed_event_count[i]++;
 208                         if (acpi_gbl_global_event_handler) {
 209                                 acpi_gbl_global_event_handler
 210                                     (ACPI_EVENT_TYPE_FIXED, NULL, i,
 211                                      acpi_gbl_global_event_handler_context);
 212                         }
 213 
 214                         int_status |= acpi_ev_fixed_event_dispatch(i);
 215                 }
 216         }
 217 
 218         return (int_status);
 219 }
 220 
 221 /*******************************************************************************
 222  *
 223  * FUNCTION:    acpi_ev_fixed_event_dispatch
 224  *
 225  * PARAMETERS:  event               - Event type
 226  *
 227  * RETURN:      INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED
 228  *
 229  * DESCRIPTION: Clears the status bit for the requested event, calls the
 230  *              handler that previously registered for the event.
 231  *              NOTE: If there is no handler for the event, the event is
 232  *              disabled to prevent further interrupts.
 233  *
 234  ******************************************************************************/
 235 
 236 static u32 acpi_ev_fixed_event_dispatch(u32 event)
 237 {
 238 
 239         ACPI_FUNCTION_ENTRY();
 240 
 241         /* Clear the status bit */
 242 
 243         (void)acpi_write_bit_register(acpi_gbl_fixed_event_info[event].
 244                                       status_register_id, ACPI_CLEAR_STATUS);
 245 
 246         /*
 247          * Make sure that a handler exists. If not, report an error
 248          * and disable the event to prevent further interrupts.
 249          */
 250         if (!acpi_gbl_fixed_event_handlers[event].handler) {
 251                 (void)acpi_write_bit_register(acpi_gbl_fixed_event_info[event].
 252                                               enable_register_id,
 253                                               ACPI_DISABLE_EVENT);
 254 
 255                 ACPI_ERROR((AE_INFO,
 256                             "No installed handler for fixed event - %s (%u), disabling",
 257                             acpi_ut_get_event_name(event), event));
 258 
 259                 return (ACPI_INTERRUPT_NOT_HANDLED);
 260         }
 261 
 262         /* Invoke the Fixed Event handler */
 263 
 264         return ((acpi_gbl_fixed_event_handlers[event].
 265                  handler) (acpi_gbl_fixed_event_handlers[event].context));
 266 }
 267 
 268 /*******************************************************************************
 269  *
 270  * FUNCTION:    acpi_any_fixed_event_status_set
 271  *
 272  * PARAMETERS:  None
 273  *
 274  * RETURN:      TRUE or FALSE
 275  *
 276  * DESCRIPTION: Checks the PM status register for active fixed events
 277  *
 278  ******************************************************************************/
 279 
 280 u32 acpi_any_fixed_event_status_set(void)
 281 {
 282         acpi_status status;
 283         u32 in_status;
 284         u32 in_enable;
 285         u32 i;
 286 
 287         status = acpi_hw_register_read(ACPI_REGISTER_PM1_ENABLE, &in_enable);
 288         if (ACPI_FAILURE(status)) {
 289                 return (FALSE);
 290         }
 291 
 292         status = acpi_hw_register_read(ACPI_REGISTER_PM1_STATUS, &in_status);
 293         if (ACPI_FAILURE(status)) {
 294                 return (FALSE);
 295         }
 296 
 297         /*
 298          * Check for all possible Fixed Events and dispatch those that are active
 299          */
 300         for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) {
 301 
 302                 /* Both the status and enable bits must be on for this event */
 303 
 304                 if ((in_status & acpi_gbl_fixed_event_info[i].status_bit_mask) &&
 305                     (in_enable & acpi_gbl_fixed_event_info[i].enable_bit_mask)) {
 306                         return (TRUE);
 307                 }
 308         }
 309 
 310         return (FALSE);
 311 }
 312 
 313 #endif                          /* !ACPI_REDUCED_HARDWARE */

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