1 /****************************************************************************** 2 * 3 * Module Name: evevent - Fixed Event handling and dispatch 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2016, Intel Corp. 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions, and the following disclaimer, 16 * without modification. 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18 * substantially similar to the "NO WARRANTY" disclaimer below 19 * ("Disclaimer") and any redistribution must be conditioned upon 20 * including a substantially similar Disclaimer requirement for further 21 * binary redistribution. 22 * 3. Neither the names of the above-listed copyright holders nor the names 23 * of any contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * Alternatively, this software may be distributed under the terms of the 27 * GNU General Public License ("GPL") version 2 as published by the Free 28 * Software Foundation. 29 * 30 * NO WARRANTY 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41 * POSSIBILITY OF SUCH DAMAGES. 42 */ 43 44 #include "acpi.h" 45 #include "accommon.h" 46 #include "acevents.h" 47 48 #define _COMPONENT ACPI_EVENTS 49 ACPI_MODULE_NAME ("evevent") 50 51 #if (!ACPI_REDUCED_HARDWARE) /* Entire module */ 52 53 /* Local prototypes */ 54 55 static ACPI_STATUS 56 AcpiEvFixedEventInitialize ( 57 void); 58 59 static UINT32 60 AcpiEvFixedEventDispatch ( 61 UINT32 Event); 62 63 64 /******************************************************************************* 65 * 66 * FUNCTION: AcpiEvInitializeEvents 67 * 68 * PARAMETERS: None 69 * 70 * RETURN: Status 71 * 72 * DESCRIPTION: Initialize global data structures for ACPI events (Fixed, GPE) 73 * 74 ******************************************************************************/ 75 76 ACPI_STATUS 77 AcpiEvInitializeEvents ( 78 void) 79 { 80 ACPI_STATUS Status; 81 82 83 ACPI_FUNCTION_TRACE (EvInitializeEvents); 84 85 86 /* If Hardware Reduced flag is set, there are no fixed events */ 87 88 if (AcpiGbl_ReducedHardware) 89 { 90 return_ACPI_STATUS (AE_OK); 91 } 92 93 /* 94 * Initialize the Fixed and General Purpose Events. This is done prior to 95 * enabling SCIs to prevent interrupts from occurring before the handlers 96 * are installed. 97 */ 98 Status = AcpiEvFixedEventInitialize (); 99 if (ACPI_FAILURE (Status)) 100 { 101 ACPI_EXCEPTION ((AE_INFO, Status, 102 "Unable to initialize fixed events")); 103 return_ACPI_STATUS (Status); 104 } 105 106 Status = AcpiEvGpeInitialize (); 107 if (ACPI_FAILURE (Status)) 108 { 109 ACPI_EXCEPTION ((AE_INFO, Status, 110 "Unable to initialize general purpose events")); 111 return_ACPI_STATUS (Status); 112 } 113 114 return_ACPI_STATUS (Status); 115 } 116 117 118 /******************************************************************************* 119 * 120 * FUNCTION: AcpiEvInstallXruptHandlers 121 * 122 * PARAMETERS: None 123 * 124 * RETURN: Status 125 * 126 * DESCRIPTION: Install interrupt handlers for the SCI and Global Lock 127 * 128 ******************************************************************************/ 129 130 ACPI_STATUS 131 AcpiEvInstallXruptHandlers ( 132 void) 133 { 134 ACPI_STATUS Status; 135 136 137 ACPI_FUNCTION_TRACE (EvInstallXruptHandlers); 138 139 140 /* If Hardware Reduced flag is set, there is no ACPI h/w */ 141 142 if (AcpiGbl_ReducedHardware) 143 { 144 return_ACPI_STATUS (AE_OK); 145 } 146 147 /* Install the SCI handler */ 148 149 Status = AcpiEvInstallSciHandler (); 150 if (ACPI_FAILURE (Status)) 151 { 152 ACPI_EXCEPTION ((AE_INFO, Status, 153 "Unable to install System Control Interrupt handler")); 154 return_ACPI_STATUS (Status); 155 } 156 157 /* Install the handler for the Global Lock */ 158 159 Status = AcpiEvInitGlobalLockHandler (); 160 if (ACPI_FAILURE (Status)) 161 { 162 ACPI_EXCEPTION ((AE_INFO, Status, 163 "Unable to initialize Global Lock handler")); 164 return_ACPI_STATUS (Status); 165 } 166 167 AcpiGbl_EventsInitialized = TRUE; 168 return_ACPI_STATUS (Status); 169 } 170 171 172 /******************************************************************************* 173 * 174 * FUNCTION: AcpiEvFixedEventInitialize 175 * 176 * PARAMETERS: None 177 * 178 * RETURN: Status 179 * 180 * DESCRIPTION: Install the fixed event handlers and disable all fixed events. 181 * 182 ******************************************************************************/ 183 184 static ACPI_STATUS 185 AcpiEvFixedEventInitialize ( 186 void) 187 { 188 UINT32 i; 189 ACPI_STATUS Status; 190 191 192 /* 193 * Initialize the structure that keeps track of fixed event handlers and 194 * enable the fixed events. 195 */ 196 for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) 197 { 198 AcpiGbl_FixedEventHandlers[i].Handler = NULL; 199 AcpiGbl_FixedEventHandlers[i].Context = NULL; 200 201 /* Disable the fixed event */ 202 203 if (AcpiGbl_FixedEventInfo[i].EnableRegisterId != 0xFF) 204 { 205 Status = AcpiWriteBitRegister ( 206 AcpiGbl_FixedEventInfo[i].EnableRegisterId, 207 ACPI_DISABLE_EVENT); 208 if (ACPI_FAILURE (Status)) 209 { 210 return (Status); 211 } 212 } 213 } 214 215 return (AE_OK); 216 } 217 218 219 /******************************************************************************* 220 * 221 * FUNCTION: AcpiEvFixedEventDetect 222 * 223 * PARAMETERS: None 224 * 225 * RETURN: INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED 226 * 227 * DESCRIPTION: Checks the PM status register for active fixed events 228 * 229 ******************************************************************************/ 230 231 UINT32 232 AcpiEvFixedEventDetect ( 233 void) 234 { 235 UINT32 IntStatus = ACPI_INTERRUPT_NOT_HANDLED; 236 UINT32 FixedStatus; 237 UINT32 FixedEnable; 238 UINT32 i; 239 240 241 ACPI_FUNCTION_NAME (EvFixedEventDetect); 242 243 244 /* 245 * Read the fixed feature status and enable registers, as all the cases 246 * depend on their values. Ignore errors here. 247 */ 248 (void) AcpiHwRegisterRead (ACPI_REGISTER_PM1_STATUS, &FixedStatus); 249 (void) AcpiHwRegisterRead (ACPI_REGISTER_PM1_ENABLE, &FixedEnable); 250 251 ACPI_DEBUG_PRINT ((ACPI_DB_INTERRUPTS, 252 "Fixed Event Block: Enable %08X Status %08X\n", 253 FixedEnable, FixedStatus)); 254 255 /* 256 * Check for all possible Fixed Events and dispatch those that are active 257 */ 258 for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) 259 { 260 /* Both the status and enable bits must be on for this event */ 261 262 if ((FixedStatus & AcpiGbl_FixedEventInfo[i].StatusBitMask) && 263 (FixedEnable & AcpiGbl_FixedEventInfo[i].EnableBitMask)) 264 { 265 /* 266 * Found an active (signalled) event. Invoke global event 267 * handler if present. 268 */ 269 AcpiFixedEventCount[i]++; 270 if (AcpiGbl_GlobalEventHandler) 271 { 272 AcpiGbl_GlobalEventHandler (ACPI_EVENT_TYPE_FIXED, NULL, 273 i, AcpiGbl_GlobalEventHandlerContext); 274 } 275 276 IntStatus |= AcpiEvFixedEventDispatch (i); 277 } 278 } 279 280 return (IntStatus); 281 } 282 283 284 /******************************************************************************* 285 * 286 * FUNCTION: AcpiEvFixedEventDispatch 287 * 288 * PARAMETERS: Event - Event type 289 * 290 * RETURN: INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED 291 * 292 * DESCRIPTION: Clears the status bit for the requested event, calls the 293 * handler that previously registered for the event. 294 * NOTE: If there is no handler for the event, the event is 295 * disabled to prevent further interrupts. 296 * 297 ******************************************************************************/ 298 299 static UINT32 300 AcpiEvFixedEventDispatch ( 301 UINT32 Event) 302 { 303 304 ACPI_FUNCTION_ENTRY (); 305 306 307 /* Clear the status bit */ 308 309 (void) AcpiWriteBitRegister ( 310 AcpiGbl_FixedEventInfo[Event].StatusRegisterId, 311 ACPI_CLEAR_STATUS); 312 313 /* 314 * Make sure that a handler exists. If not, report an error 315 * and disable the event to prevent further interrupts. 316 */ 317 if (!AcpiGbl_FixedEventHandlers[Event].Handler) 318 { 319 (void) AcpiWriteBitRegister ( 320 AcpiGbl_FixedEventInfo[Event].EnableRegisterId, 321 ACPI_DISABLE_EVENT); 322 323 ACPI_ERROR ((AE_INFO, 324 "No installed handler for fixed event - %s (%u), disabling", 325 AcpiUtGetEventName (Event), Event)); 326 327 return (ACPI_INTERRUPT_NOT_HANDLED); 328 } 329 330 /* Invoke the Fixed Event handler */ 331 332 return ((AcpiGbl_FixedEventHandlers[Event].Handler)( 333 AcpiGbl_FixedEventHandlers[Event].Context)); 334 } 335 336 #endif /* !ACPI_REDUCED_HARDWARE */ 337