1 /******************************************************************************* 2 * 3 * Module Name: evsci - System Control Interrupt configuration and 4 * legacy to ACPI mode state transition functions 5 * 6 ******************************************************************************/ 7 8 /* 9 * Copyright (C) 2000 - 2017, Intel Corp. 10 * All rights reserved. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions, and the following disclaimer, 17 * without modification. 18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 19 * substantially similar to the "NO WARRANTY" disclaimer below 20 * ("Disclaimer") and any redistribution must be conditioned upon 21 * including a substantially similar Disclaimer requirement for further 22 * binary redistribution. 23 * 3. Neither the names of the above-listed copyright holders nor the names 24 * of any contributors may be used to endorse or promote products derived 25 * from this software without specific prior written permission. 26 * 27 * Alternatively, this software may be distributed under the terms of the 28 * GNU General Public License ("GPL") version 2 as published by the Free 29 * Software Foundation. 30 * 31 * NO WARRANTY 32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 42 * POSSIBILITY OF SUCH DAMAGES. 43 */ 44 45 #include "acpi.h" 46 #include "accommon.h" 47 #include "acevents.h" 48 49 50 #define _COMPONENT ACPI_EVENTS 51 ACPI_MODULE_NAME ("evsci") 52 53 #if (!ACPI_REDUCED_HARDWARE) /* Entire module */ 54 55 /* Local prototypes */ 56 57 static UINT32 ACPI_SYSTEM_XFACE 58 AcpiEvSciXruptHandler ( 59 void *Context); 60 61 62 /******************************************************************************* 63 * 64 * FUNCTION: AcpiEvSciDispatch 65 * 66 * PARAMETERS: None 67 * 68 * RETURN: Status code indicates whether interrupt was handled. 69 * 70 * DESCRIPTION: Dispatch the SCI to all host-installed SCI handlers. 71 * 72 ******************************************************************************/ 73 74 UINT32 75 AcpiEvSciDispatch ( 76 void) 77 { 78 ACPI_SCI_HANDLER_INFO *SciHandler; 79 ACPI_CPU_FLAGS Flags; 80 UINT32 IntStatus = ACPI_INTERRUPT_NOT_HANDLED; 81 82 83 ACPI_FUNCTION_NAME (EvSciDispatch); 84 85 86 /* Are there any host-installed SCI handlers? */ 87 88 if (!AcpiGbl_SciHandlerList) 89 { 90 return (IntStatus); 91 } 92 93 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 94 95 /* Invoke all host-installed SCI handlers */ 96 97 SciHandler = AcpiGbl_SciHandlerList; 98 while (SciHandler) 99 { 100 /* Invoke the installed handler (at interrupt level) */ 101 102 IntStatus |= SciHandler->Address ( 103 SciHandler->Context); 104 105 SciHandler = SciHandler->Next; 106 } 107 108 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 109 return (IntStatus); 110 } 111 112 113 /******************************************************************************* 114 * 115 * FUNCTION: AcpiEvSciXruptHandler 116 * 117 * PARAMETERS: Context - Calling Context 118 * 119 * RETURN: Status code indicates whether interrupt was handled. 120 * 121 * DESCRIPTION: Interrupt handler that will figure out what function or 122 * control method to call to deal with a SCI. 123 * 124 ******************************************************************************/ 125 126 static UINT32 ACPI_SYSTEM_XFACE 127 AcpiEvSciXruptHandler ( 128 void *Context) 129 { 130 ACPI_GPE_XRUPT_INFO *GpeXruptList = Context; 131 UINT32 InterruptHandled = ACPI_INTERRUPT_NOT_HANDLED; 132 133 134 ACPI_FUNCTION_TRACE (EvSciXruptHandler); 135 136 137 /* 138 * We are guaranteed by the ACPICA initialization/shutdown code that 139 * if this interrupt handler is installed, ACPI is enabled. 140 */ 141 142 /* 143 * Fixed Events: 144 * Check for and dispatch any Fixed Events that have occurred 145 */ 146 InterruptHandled |= AcpiEvFixedEventDetect (); 147 148 /* 149 * General Purpose Events: 150 * Check for and dispatch any GPEs that have occurred 151 */ 152 InterruptHandled |= AcpiEvGpeDetect (GpeXruptList); 153 154 /* Invoke all host-installed SCI handlers */ 155 156 InterruptHandled |= AcpiEvSciDispatch (); 157 158 AcpiSciCount++; 159 return_UINT32 (InterruptHandled); 160 } 161 162 163 /******************************************************************************* 164 * 165 * FUNCTION: AcpiEvGpeXruptHandler 166 * 167 * PARAMETERS: Context - Calling Context 168 * 169 * RETURN: Status code indicates whether interrupt was handled. 170 * 171 * DESCRIPTION: Handler for GPE Block Device interrupts 172 * 173 ******************************************************************************/ 174 175 UINT32 ACPI_SYSTEM_XFACE 176 AcpiEvGpeXruptHandler ( 177 void *Context) 178 { 179 ACPI_GPE_XRUPT_INFO *GpeXruptList = Context; 180 UINT32 InterruptHandled = ACPI_INTERRUPT_NOT_HANDLED; 181 182 183 ACPI_FUNCTION_TRACE (EvGpeXruptHandler); 184 185 186 /* 187 * We are guaranteed by the ACPICA initialization/shutdown code that 188 * if this interrupt handler is installed, ACPI is enabled. 189 */ 190 191 /* GPEs: Check for and dispatch any GPEs that have occurred */ 192 193 InterruptHandled |= AcpiEvGpeDetect (GpeXruptList); 194 return_UINT32 (InterruptHandled); 195 } 196 197 198 /****************************************************************************** 199 * 200 * FUNCTION: AcpiEvInstallSciHandler 201 * 202 * PARAMETERS: none 203 * 204 * RETURN: Status 205 * 206 * DESCRIPTION: Installs SCI handler. 207 * 208 ******************************************************************************/ 209 210 UINT32 211 AcpiEvInstallSciHandler ( 212 void) 213 { 214 UINT32 Status = AE_OK; 215 216 217 ACPI_FUNCTION_TRACE (EvInstallSciHandler); 218 219 220 Status = AcpiOsInstallInterruptHandler ((UINT32) AcpiGbl_FADT.SciInterrupt, 221 AcpiEvSciXruptHandler, AcpiGbl_GpeXruptListHead); 222 return_ACPI_STATUS (Status); 223 } 224 225 226 /****************************************************************************** 227 * 228 * FUNCTION: AcpiEvRemoveAllSciHandlers 229 * 230 * PARAMETERS: none 231 * 232 * RETURN: AE_OK if handler uninstalled, AE_ERROR if handler was not 233 * installed to begin with 234 * 235 * DESCRIPTION: Remove the SCI interrupt handler. No further SCIs will be 236 * taken. Remove all host-installed SCI handlers. 237 * 238 * Note: It doesn't seem important to disable all events or set the event 239 * enable registers to their original values. The OS should disable 240 * the SCI interrupt level when the handler is removed, so no more 241 * events will come in. 242 * 243 ******************************************************************************/ 244 245 ACPI_STATUS 246 AcpiEvRemoveAllSciHandlers ( 247 void) 248 { 249 ACPI_SCI_HANDLER_INFO *SciHandler; 250 ACPI_CPU_FLAGS Flags; 251 ACPI_STATUS Status; 252 253 254 ACPI_FUNCTION_TRACE (EvRemoveAllSciHandlers); 255 256 257 /* Just let the OS remove the handler and disable the level */ 258 259 Status = AcpiOsRemoveInterruptHandler ((UINT32) AcpiGbl_FADT.SciInterrupt, 260 AcpiEvSciXruptHandler); 261 262 if (!AcpiGbl_SciHandlerList) 263 { 264 return (Status); 265 } 266 267 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 268 269 /* Free all host-installed SCI handlers */ 270 271 while (AcpiGbl_SciHandlerList) 272 { 273 SciHandler = AcpiGbl_SciHandlerList; 274 AcpiGbl_SciHandlerList = SciHandler->Next; 275 ACPI_FREE (SciHandler); 276 } 277 278 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 279 return_ACPI_STATUS (Status); 280 } 281 282 #endif /* !ACPI_REDUCED_HARDWARE */ 283