1 | // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 |
2 | /****************************************************************************** |
3 | * |
4 | * Module Name: evxfevnt - External Interfaces, ACPI event disable/enable |
5 | * |
6 | * Copyright (C) 2000 - 2023, Intel Corp. |
7 | * |
8 | *****************************************************************************/ |
9 | |
10 | #define EXPORT_ACPI_INTERFACES |
11 | |
12 | #include <acpi/acpi.h> |
13 | #include "accommon.h" |
14 | #include "actables.h" |
15 | |
16 | #define _COMPONENT ACPI_EVENTS |
17 | ACPI_MODULE_NAME("evxfevnt" ) |
18 | |
19 | #if (!ACPI_REDUCED_HARDWARE) /* Entire module */ |
20 | /******************************************************************************* |
21 | * |
22 | * FUNCTION: acpi_enable |
23 | * |
24 | * PARAMETERS: None |
25 | * |
26 | * RETURN: Status |
27 | * |
28 | * DESCRIPTION: Transfers the system into ACPI mode. |
29 | * |
30 | ******************************************************************************/ |
31 | acpi_status acpi_enable(void) |
32 | { |
33 | acpi_status status; |
34 | int retry; |
35 | |
36 | ACPI_FUNCTION_TRACE(acpi_enable); |
37 | |
38 | /* ACPI tables must be present */ |
39 | |
40 | if (acpi_gbl_fadt_index == ACPI_INVALID_TABLE_INDEX) { |
41 | return_ACPI_STATUS(AE_NO_ACPI_TABLES); |
42 | } |
43 | |
44 | /* If the Hardware Reduced flag is set, machine is always in acpi mode */ |
45 | |
46 | if (acpi_gbl_reduced_hardware) { |
47 | return_ACPI_STATUS(AE_OK); |
48 | } |
49 | |
50 | /* Check current mode */ |
51 | |
52 | if (acpi_hw_get_mode() == ACPI_SYS_MODE_ACPI) { |
53 | ACPI_DEBUG_PRINT((ACPI_DB_INIT, |
54 | "System is already in ACPI mode\n" )); |
55 | return_ACPI_STATUS(AE_OK); |
56 | } |
57 | |
58 | /* Transition to ACPI mode */ |
59 | |
60 | status = acpi_hw_set_mode(ACPI_SYS_MODE_ACPI); |
61 | if (ACPI_FAILURE(status)) { |
62 | ACPI_ERROR((AE_INFO, |
63 | "Could not transition to ACPI mode" )); |
64 | return_ACPI_STATUS(status); |
65 | } |
66 | |
67 | /* Sanity check that transition succeeded */ |
68 | |
69 | for (retry = 0; retry < 30000; ++retry) { |
70 | if (acpi_hw_get_mode() == ACPI_SYS_MODE_ACPI) { |
71 | if (retry != 0) |
72 | ACPI_WARNING((AE_INFO, |
73 | "Platform took > %d00 usec to enter ACPI mode" , retry)); |
74 | return_ACPI_STATUS(AE_OK); |
75 | } |
76 | acpi_os_stall(100); /* 100 usec */ |
77 | } |
78 | |
79 | ACPI_ERROR((AE_INFO, "Hardware did not enter ACPI mode" )); |
80 | return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE); |
81 | } |
82 | |
83 | ACPI_EXPORT_SYMBOL(acpi_enable) |
84 | |
85 | /******************************************************************************* |
86 | * |
87 | * FUNCTION: acpi_disable |
88 | * |
89 | * PARAMETERS: None |
90 | * |
91 | * RETURN: Status |
92 | * |
93 | * DESCRIPTION: Transfers the system into LEGACY (non-ACPI) mode. |
94 | * |
95 | ******************************************************************************/ |
96 | acpi_status acpi_disable(void) |
97 | { |
98 | acpi_status status = AE_OK; |
99 | |
100 | ACPI_FUNCTION_TRACE(acpi_disable); |
101 | |
102 | /* If the Hardware Reduced flag is set, machine is always in acpi mode */ |
103 | |
104 | if (acpi_gbl_reduced_hardware) { |
105 | return_ACPI_STATUS(AE_OK); |
106 | } |
107 | |
108 | if (acpi_hw_get_mode() == ACPI_SYS_MODE_LEGACY) { |
109 | ACPI_DEBUG_PRINT((ACPI_DB_INIT, |
110 | "System is already in legacy (non-ACPI) mode\n" )); |
111 | } else { |
112 | /* Transition to LEGACY mode */ |
113 | |
114 | status = acpi_hw_set_mode(ACPI_SYS_MODE_LEGACY); |
115 | |
116 | if (ACPI_FAILURE(status)) { |
117 | ACPI_ERROR((AE_INFO, |
118 | "Could not exit ACPI mode to legacy mode" )); |
119 | return_ACPI_STATUS(status); |
120 | } |
121 | |
122 | ACPI_DEBUG_PRINT((ACPI_DB_INIT, "ACPI mode disabled\n" )); |
123 | } |
124 | |
125 | return_ACPI_STATUS(status); |
126 | } |
127 | |
128 | ACPI_EXPORT_SYMBOL(acpi_disable) |
129 | |
130 | /******************************************************************************* |
131 | * |
132 | * FUNCTION: acpi_enable_event |
133 | * |
134 | * PARAMETERS: event - The fixed eventto be enabled |
135 | * flags - Reserved |
136 | * |
137 | * RETURN: Status |
138 | * |
139 | * DESCRIPTION: Enable an ACPI event (fixed) |
140 | * |
141 | ******************************************************************************/ |
142 | acpi_status acpi_enable_event(u32 event, u32 flags) |
143 | { |
144 | acpi_status status = AE_OK; |
145 | u32 value; |
146 | |
147 | ACPI_FUNCTION_TRACE(acpi_enable_event); |
148 | |
149 | /* If Hardware Reduced flag is set, there are no fixed events */ |
150 | |
151 | if (acpi_gbl_reduced_hardware) { |
152 | return_ACPI_STATUS(AE_OK); |
153 | } |
154 | |
155 | /* Decode the Fixed Event */ |
156 | |
157 | if (event > ACPI_EVENT_MAX) { |
158 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
159 | } |
160 | |
161 | /* |
162 | * Enable the requested fixed event (by writing a one to the enable |
163 | * register bit) |
164 | */ |
165 | status = |
166 | acpi_write_bit_register(acpi_gbl_fixed_event_info[event]. |
167 | enable_register_id, ACPI_ENABLE_EVENT); |
168 | if (ACPI_FAILURE(status)) { |
169 | return_ACPI_STATUS(status); |
170 | } |
171 | |
172 | /* Make sure that the hardware responded */ |
173 | |
174 | status = |
175 | acpi_read_bit_register(acpi_gbl_fixed_event_info[event]. |
176 | enable_register_id, &value); |
177 | if (ACPI_FAILURE(status)) { |
178 | return_ACPI_STATUS(status); |
179 | } |
180 | |
181 | if (value != 1) { |
182 | ACPI_ERROR((AE_INFO, |
183 | "Could not enable %s event" , |
184 | acpi_ut_get_event_name(event))); |
185 | return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE); |
186 | } |
187 | |
188 | return_ACPI_STATUS(status); |
189 | } |
190 | |
191 | ACPI_EXPORT_SYMBOL(acpi_enable_event) |
192 | |
193 | /******************************************************************************* |
194 | * |
195 | * FUNCTION: acpi_disable_event |
196 | * |
197 | * PARAMETERS: event - The fixed event to be disabled |
198 | * flags - Reserved |
199 | * |
200 | * RETURN: Status |
201 | * |
202 | * DESCRIPTION: Disable an ACPI event (fixed) |
203 | * |
204 | ******************************************************************************/ |
205 | acpi_status acpi_disable_event(u32 event, u32 flags) |
206 | { |
207 | acpi_status status = AE_OK; |
208 | u32 value; |
209 | |
210 | ACPI_FUNCTION_TRACE(acpi_disable_event); |
211 | |
212 | /* If Hardware Reduced flag is set, there are no fixed events */ |
213 | |
214 | if (acpi_gbl_reduced_hardware) { |
215 | return_ACPI_STATUS(AE_OK); |
216 | } |
217 | |
218 | /* Decode the Fixed Event */ |
219 | |
220 | if (event > ACPI_EVENT_MAX) { |
221 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
222 | } |
223 | |
224 | /* |
225 | * Disable the requested fixed event (by writing a zero to the enable |
226 | * register bit) |
227 | */ |
228 | status = |
229 | acpi_write_bit_register(acpi_gbl_fixed_event_info[event]. |
230 | enable_register_id, ACPI_DISABLE_EVENT); |
231 | if (ACPI_FAILURE(status)) { |
232 | return_ACPI_STATUS(status); |
233 | } |
234 | |
235 | status = |
236 | acpi_read_bit_register(acpi_gbl_fixed_event_info[event]. |
237 | enable_register_id, &value); |
238 | if (ACPI_FAILURE(status)) { |
239 | return_ACPI_STATUS(status); |
240 | } |
241 | |
242 | if (value != 0) { |
243 | ACPI_ERROR((AE_INFO, |
244 | "Could not disable %s events" , |
245 | acpi_ut_get_event_name(event))); |
246 | return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE); |
247 | } |
248 | |
249 | return_ACPI_STATUS(status); |
250 | } |
251 | |
252 | ACPI_EXPORT_SYMBOL(acpi_disable_event) |
253 | |
254 | /******************************************************************************* |
255 | * |
256 | * FUNCTION: acpi_clear_event |
257 | * |
258 | * PARAMETERS: event - The fixed event to be cleared |
259 | * |
260 | * RETURN: Status |
261 | * |
262 | * DESCRIPTION: Clear an ACPI event (fixed) |
263 | * |
264 | ******************************************************************************/ |
265 | acpi_status acpi_clear_event(u32 event) |
266 | { |
267 | acpi_status status = AE_OK; |
268 | |
269 | ACPI_FUNCTION_TRACE(acpi_clear_event); |
270 | |
271 | /* If Hardware Reduced flag is set, there are no fixed events */ |
272 | |
273 | if (acpi_gbl_reduced_hardware) { |
274 | return_ACPI_STATUS(AE_OK); |
275 | } |
276 | |
277 | /* Decode the Fixed Event */ |
278 | |
279 | if (event > ACPI_EVENT_MAX) { |
280 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
281 | } |
282 | |
283 | /* |
284 | * Clear the requested fixed event (By writing a one to the status |
285 | * register bit) |
286 | */ |
287 | status = |
288 | acpi_write_bit_register(acpi_gbl_fixed_event_info[event]. |
289 | status_register_id, ACPI_CLEAR_STATUS); |
290 | |
291 | return_ACPI_STATUS(status); |
292 | } |
293 | |
294 | ACPI_EXPORT_SYMBOL(acpi_clear_event) |
295 | |
296 | /******************************************************************************* |
297 | * |
298 | * FUNCTION: acpi_get_event_status |
299 | * |
300 | * PARAMETERS: event - The fixed event |
301 | * event_status - Where the current status of the event will |
302 | * be returned |
303 | * |
304 | * RETURN: Status |
305 | * |
306 | * DESCRIPTION: Obtains and returns the current status of the event |
307 | * |
308 | ******************************************************************************/ |
309 | acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status) |
310 | { |
311 | acpi_status status; |
312 | acpi_event_status local_event_status = 0; |
313 | u32 in_byte; |
314 | |
315 | ACPI_FUNCTION_TRACE(acpi_get_event_status); |
316 | |
317 | if (!event_status) { |
318 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
319 | } |
320 | |
321 | /* Decode the Fixed Event */ |
322 | |
323 | if (event > ACPI_EVENT_MAX) { |
324 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
325 | } |
326 | |
327 | /* Fixed event currently can be dispatched? */ |
328 | |
329 | if (acpi_gbl_fixed_event_handlers[event].handler) { |
330 | local_event_status |= ACPI_EVENT_FLAG_HAS_HANDLER; |
331 | } |
332 | |
333 | /* Fixed event currently enabled? */ |
334 | |
335 | status = |
336 | acpi_read_bit_register(acpi_gbl_fixed_event_info[event]. |
337 | enable_register_id, &in_byte); |
338 | if (ACPI_FAILURE(status)) { |
339 | return_ACPI_STATUS(status); |
340 | } |
341 | |
342 | if (in_byte) { |
343 | local_event_status |= |
344 | (ACPI_EVENT_FLAG_ENABLED | ACPI_EVENT_FLAG_ENABLE_SET); |
345 | } |
346 | |
347 | /* Fixed event currently active? */ |
348 | |
349 | status = |
350 | acpi_read_bit_register(acpi_gbl_fixed_event_info[event]. |
351 | status_register_id, &in_byte); |
352 | if (ACPI_FAILURE(status)) { |
353 | return_ACPI_STATUS(status); |
354 | } |
355 | |
356 | if (in_byte) { |
357 | local_event_status |= ACPI_EVENT_FLAG_STATUS_SET; |
358 | } |
359 | |
360 | (*event_status) = local_event_status; |
361 | return_ACPI_STATUS(AE_OK); |
362 | } |
363 | |
364 | ACPI_EXPORT_SYMBOL(acpi_get_event_status) |
365 | #endif /* !ACPI_REDUCED_HARDWARE */ |
366 | |