Linux-libre 5.4.47-gnu
[librecmc/linux-libre.git] / drivers / acpi / acpica / evxfevnt.c
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  ******************************************************************************/
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 */