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 - 2019, 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 ******************************************************************************/
acpi_enable(void)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
ACPI_EXPORT_SYMBOL(acpi_enable)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
ACPI_EXPORT_SYMBOL(acpi_disable)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
ACPI_EXPORT_SYMBOL(acpi_enable_event)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
ACPI_EXPORT_SYMBOL(acpi_disable_event)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
ACPI_EXPORT_SYMBOL(acpi_clear_event)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