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 - 2016, 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 | |