1 /****************************************************************************** 2 * 3 * Module Name: evevent - Fixed Event handling and dispatch 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2011, 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 /* Local prototypes */ 52 53 static ACPI_STATUS 54 AcpiEvFixedEventInitialize ( 55 void); 56 57 static UINT32 58 AcpiEvFixedEventDispatch ( 59 UINT32 Event); 60 61 62 /******************************************************************************* 63 * 64 * FUNCTION: AcpiEvInitializeEvents 65 * 66 * PARAMETERS: None 67 * 68 * RETURN: Status 69 * 70 * DESCRIPTION: Initialize global data structures for ACPI events (Fixed, GPE) 71 * 72 ******************************************************************************/ 73 74 ACPI_STATUS 75 AcpiEvInitializeEvents ( 76 void) 77 { 78 ACPI_STATUS Status; 79 80 81 ACPI_FUNCTION_TRACE (EvInitializeEvents); 82 83 84 /* 85 * Initialize the Fixed and General Purpose Events. This is done prior to 86 * enabling SCIs to prevent interrupts from occurring before the handlers 87 * are installed. 88 */ 89 Status = AcpiEvFixedEventInitialize (); 90 if (ACPI_FAILURE (Status)) 91 { 92 ACPI_EXCEPTION ((AE_INFO, Status, 93 "Unable to initialize fixed events")); 94 return_ACPI_STATUS (Status); 95 } 96 97 Status = AcpiEvGpeInitialize (); 98 if (ACPI_FAILURE (Status)) 99 { 100 ACPI_EXCEPTION ((AE_INFO, Status, 101 "Unable to initialize general purpose events")); 102 return_ACPI_STATUS (Status); 103 } 104 105 return_ACPI_STATUS (Status); 106 } 107 108 109 /******************************************************************************* 110 * 111 * FUNCTION: AcpiEvInstallXruptHandlers 112 * 113 * PARAMETERS: None 114 * 115 * RETURN: Status 116 * 117 * DESCRIPTION: Install interrupt handlers for the SCI and Global Lock 118 * 119 ******************************************************************************/ 120 121 ACPI_STATUS 122 AcpiEvInstallXruptHandlers ( 123 void) 124 { 125 ACPI_STATUS Status; 126 127 128 ACPI_FUNCTION_TRACE (EvInstallXruptHandlers); 129 130 131 /* Install the SCI handler */ 132 133 Status = AcpiEvInstallSciHandler (); 134 if (ACPI_FAILURE (Status)) 135 { 136 ACPI_EXCEPTION ((AE_INFO, Status, 137 "Unable to install System Control Interrupt handler")); 138 return_ACPI_STATUS (Status); 139 } 140 141 /* Install the handler for the Global Lock */ 142 143 Status = AcpiEvInitGlobalLockHandler (); 144 if (ACPI_FAILURE (Status)) 145 { 146 ACPI_EXCEPTION ((AE_INFO, Status, 147 "Unable to initialize Global Lock handler")); 148 return_ACPI_STATUS (Status); 149 } 150 151 AcpiGbl_EventsInitialized = TRUE; 152 return_ACPI_STATUS (Status); 153 } 154 155 156 /******************************************************************************* 157 * 158 * FUNCTION: AcpiEvFixedEventInitialize 159 * 160 * PARAMETERS: None 161 * 162 * RETURN: Status 163 * 164 * DESCRIPTION: Install the fixed event handlers and disable all fixed events. 165 * 166 ******************************************************************************/ 167 168 static ACPI_STATUS 169 AcpiEvFixedEventInitialize ( 170 void) 171 { 172 UINT32 i; 173 ACPI_STATUS Status; 174 175 176 /* 177 * Initialize the structure that keeps track of fixed event handlers and 178 * enable the fixed events. 179 */ 180 for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) 181 { 182 AcpiGbl_FixedEventHandlers[i].Handler = NULL; 183 AcpiGbl_FixedEventHandlers[i].Context = NULL; 184 185 /* Disable the fixed event */ 186 187 if (AcpiGbl_FixedEventInfo[i].EnableRegisterId != 0xFF) 188 { 189 Status = AcpiWriteBitRegister ( 190 AcpiGbl_FixedEventInfo[i].EnableRegisterId, 191 ACPI_DISABLE_EVENT); 192 if (ACPI_FAILURE (Status)) 193 { 194 return (Status); 195 } 196 } 197 } 198 199 return (AE_OK); 200 } 201 202 203 /******************************************************************************* 204 * 205 * FUNCTION: AcpiEvFixedEventDetect 206 * 207 * PARAMETERS: None 208 * 209 * RETURN: INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED 210 * 211 * DESCRIPTION: Checks the PM status register for active fixed events 212 * 213 ******************************************************************************/ 214 215 UINT32 216 AcpiEvFixedEventDetect ( 217 void) 218 { 219 UINT32 IntStatus = ACPI_INTERRUPT_NOT_HANDLED; 220 UINT32 FixedStatus; 221 UINT32 FixedEnable; 222 UINT32 i; 223 224 225 ACPI_FUNCTION_NAME (EvFixedEventDetect); 226 227 228 /* 229 * Read the fixed feature status and enable registers, as all the cases 230 * depend on their values. Ignore errors here. 231 */ 232 (void) AcpiHwRegisterRead (ACPI_REGISTER_PM1_STATUS, &FixedStatus); 233 (void) AcpiHwRegisterRead (ACPI_REGISTER_PM1_ENABLE, &FixedEnable); 234 235 ACPI_DEBUG_PRINT ((ACPI_DB_INTERRUPTS, 236 "Fixed Event Block: Enable %08X Status %08X\n", 237 FixedEnable, FixedStatus)); 238 239 /* 240 * Check for all possible Fixed Events and dispatch those that are active 241 */ 242 for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) 243 { 244 /* Both the status and enable bits must be on for this event */ 245 246 if ((FixedStatus & AcpiGbl_FixedEventInfo[i].StatusBitMask) && 247 (FixedEnable & AcpiGbl_FixedEventInfo[i].EnableBitMask)) 248 { 249 /* 250 * Found an active (signalled) event. Invoke global event 251 * handler if present. 252 */ 253 AcpiFixedEventCount[i]++; 254 if (AcpiGbl_GlobalEventHandler) 255 { 256 AcpiGbl_GlobalEventHandler (ACPI_EVENT_TYPE_FIXED, NULL, 257 i, AcpiGbl_GlobalEventHandlerContext); 258 } 259 260 IntStatus |= AcpiEvFixedEventDispatch (i); 261 } 262 } 263 264 return (IntStatus); 265 } 266 267 268 /******************************************************************************* 269 * 270 * FUNCTION: AcpiEvFixedEventDispatch 271 * 272 * PARAMETERS: Event - Event type 273 * 274 * RETURN: INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED 275 * 276 * DESCRIPTION: Clears the status bit for the requested event, calls the 277 * handler that previously registered for the event. 278 * 279 ******************************************************************************/ 280 281 static UINT32 282 AcpiEvFixedEventDispatch ( 283 UINT32 Event) 284 { 285 286 ACPI_FUNCTION_ENTRY (); 287 288 289 /* Clear the status bit */ 290 291 (void) AcpiWriteBitRegister ( 292 AcpiGbl_FixedEventInfo[Event].StatusRegisterId, 293 ACPI_CLEAR_STATUS); 294 295 /* 296 * Make sure we've got a handler. If not, report an error. The event is 297 * disabled to prevent further interrupts. 298 */ 299 if (NULL == AcpiGbl_FixedEventHandlers[Event].Handler) 300 { 301 (void) AcpiWriteBitRegister ( 302 AcpiGbl_FixedEventInfo[Event].EnableRegisterId, 303 ACPI_DISABLE_EVENT); 304 305 ACPI_ERROR ((AE_INFO, 306 "No installed handler for fixed event [0x%08X]", 307 Event)); 308 309 return (ACPI_INTERRUPT_NOT_HANDLED); 310 } 311 312 /* Invoke the Fixed Event handler */ 313 314 return ((AcpiGbl_FixedEventHandlers[Event].Handler)( 315 AcpiGbl_FixedEventHandlers[Event].Context)); 316 } 317 318