195857638SErik Schmauss // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
295b482a8SLen Brown /******************************************************************************
395b482a8SLen Brown *
495b482a8SLen Brown * Module Name: evxfevnt - External Interfaces, ACPI event disable/enable
595b482a8SLen Brown *
6*612c2932SBob Moore * Copyright (C) 2000 - 2023, Intel Corp.
795b482a8SLen Brown *
895857638SErik Schmauss *****************************************************************************/
995b482a8SLen Brown
10839e928fSLv Zheng #define EXPORT_ACPI_INTERFACES
11839e928fSLv Zheng
1295b482a8SLen Brown #include <acpi/acpi.h>
13e2f7a777SLen Brown #include "accommon.h"
14e2f7a777SLen Brown #include "actables.h"
1595b482a8SLen Brown
1695b482a8SLen Brown #define _COMPONENT ACPI_EVENTS
1795b482a8SLen Brown ACPI_MODULE_NAME("evxfevnt")
1895b482a8SLen Brown
1933620c54SBob Moore #if (!ACPI_REDUCED_HARDWARE) /* Entire module */
2095b482a8SLen Brown /*******************************************************************************
2195b482a8SLen Brown *
2295b482a8SLen Brown * FUNCTION: acpi_enable
2395b482a8SLen Brown *
2495b482a8SLen Brown * PARAMETERS: None
2595b482a8SLen Brown *
2695b482a8SLen Brown * RETURN: Status
2795b482a8SLen Brown *
2895b482a8SLen Brown * DESCRIPTION: Transfers the system into ACPI mode.
2995b482a8SLen Brown *
3095b482a8SLen Brown ******************************************************************************/
acpi_enable(void)3195b482a8SLen Brown acpi_status acpi_enable(void)
3295b482a8SLen Brown {
33b430acbdSLen Brown acpi_status status;
343d695839SLen Brown int retry;
3595b482a8SLen Brown
3695b482a8SLen Brown ACPI_FUNCTION_TRACE(acpi_enable);
3795b482a8SLen Brown
3895b482a8SLen Brown /* ACPI tables must be present */
3995b482a8SLen Brown
4062fcce91SLv Zheng if (acpi_gbl_fadt_index == ACPI_INVALID_TABLE_INDEX) {
4195b482a8SLen Brown return_ACPI_STATUS(AE_NO_ACPI_TABLES);
4295b482a8SLen Brown }
4395b482a8SLen Brown
44c39660b2SBob Moore /* If the Hardware Reduced flag is set, machine is always in acpi mode */
45c39660b2SBob Moore
46c39660b2SBob Moore if (acpi_gbl_reduced_hardware) {
47c39660b2SBob Moore return_ACPI_STATUS(AE_OK);
48c39660b2SBob Moore }
49c39660b2SBob Moore
5095b482a8SLen Brown /* Check current mode */
5195b482a8SLen Brown
5295b482a8SLen Brown if (acpi_hw_get_mode() == ACPI_SYS_MODE_ACPI) {
5395b482a8SLen Brown ACPI_DEBUG_PRINT((ACPI_DB_INIT,
5495b482a8SLen Brown "System is already in ACPI mode\n"));
55b430acbdSLen Brown return_ACPI_STATUS(AE_OK);
56b430acbdSLen Brown }
57b430acbdSLen Brown
5895b482a8SLen Brown /* Transition to ACPI mode */
5995b482a8SLen Brown
6095b482a8SLen Brown status = acpi_hw_set_mode(ACPI_SYS_MODE_ACPI);
6195b482a8SLen Brown if (ACPI_FAILURE(status)) {
6295b482a8SLen Brown ACPI_ERROR((AE_INFO,
6395b482a8SLen Brown "Could not transition to ACPI mode"));
6495b482a8SLen Brown return_ACPI_STATUS(status);
6595b482a8SLen Brown }
6695b482a8SLen Brown
67b430acbdSLen Brown /* Sanity check that transition succeeded */
68b430acbdSLen Brown
693d695839SLen Brown for (retry = 0; retry < 30000; ++retry) {
703d695839SLen Brown if (acpi_hw_get_mode() == ACPI_SYS_MODE_ACPI) {
713d695839SLen Brown if (retry != 0)
723d695839SLen Brown ACPI_WARNING((AE_INFO,
733d695839SLen Brown "Platform took > %d00 usec to enter ACPI mode", retry));
743d695839SLen Brown return_ACPI_STATUS(AE_OK);
753d695839SLen Brown }
763d695839SLen Brown acpi_os_stall(100); /* 100 usec */
7795b482a8SLen Brown }
7895b482a8SLen Brown
793d695839SLen Brown ACPI_ERROR((AE_INFO, "Hardware did not enter ACPI mode"));
803d695839SLen Brown return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE);
8195b482a8SLen Brown }
8295b482a8SLen Brown
ACPI_EXPORT_SYMBOL(acpi_enable)8395b482a8SLen Brown ACPI_EXPORT_SYMBOL(acpi_enable)
8495b482a8SLen Brown
8595b482a8SLen Brown /*******************************************************************************
8695b482a8SLen Brown *
8795b482a8SLen Brown * FUNCTION: acpi_disable
8895b482a8SLen Brown *
8995b482a8SLen Brown * PARAMETERS: None
9095b482a8SLen Brown *
9195b482a8SLen Brown * RETURN: Status
9295b482a8SLen Brown *
9395b482a8SLen Brown * DESCRIPTION: Transfers the system into LEGACY (non-ACPI) mode.
9495b482a8SLen Brown *
9595b482a8SLen Brown ******************************************************************************/
9695b482a8SLen Brown acpi_status acpi_disable(void)
9795b482a8SLen Brown {
9895b482a8SLen Brown acpi_status status = AE_OK;
9995b482a8SLen Brown
10095b482a8SLen Brown ACPI_FUNCTION_TRACE(acpi_disable);
10195b482a8SLen Brown
102c39660b2SBob Moore /* If the Hardware Reduced flag is set, machine is always in acpi mode */
103c39660b2SBob Moore
104c39660b2SBob Moore if (acpi_gbl_reduced_hardware) {
105c39660b2SBob Moore return_ACPI_STATUS(AE_OK);
106c39660b2SBob Moore }
107c39660b2SBob Moore
10895b482a8SLen Brown if (acpi_hw_get_mode() == ACPI_SYS_MODE_LEGACY) {
10995b482a8SLen Brown ACPI_DEBUG_PRINT((ACPI_DB_INIT,
11095b482a8SLen Brown "System is already in legacy (non-ACPI) mode\n"));
11195b482a8SLen Brown } else {
11295b482a8SLen Brown /* Transition to LEGACY mode */
11395b482a8SLen Brown
11495b482a8SLen Brown status = acpi_hw_set_mode(ACPI_SYS_MODE_LEGACY);
11595b482a8SLen Brown
11695b482a8SLen Brown if (ACPI_FAILURE(status)) {
11795b482a8SLen Brown ACPI_ERROR((AE_INFO,
11895b482a8SLen Brown "Could not exit ACPI mode to legacy mode"));
11995b482a8SLen Brown return_ACPI_STATUS(status);
12095b482a8SLen Brown }
12195b482a8SLen Brown
12295b482a8SLen Brown ACPI_DEBUG_PRINT((ACPI_DB_INIT, "ACPI mode disabled\n"));
12395b482a8SLen Brown }
12495b482a8SLen Brown
12595b482a8SLen Brown return_ACPI_STATUS(status);
12695b482a8SLen Brown }
12795b482a8SLen Brown
ACPI_EXPORT_SYMBOL(acpi_disable)12895b482a8SLen Brown ACPI_EXPORT_SYMBOL(acpi_disable)
12995b482a8SLen Brown
13095b482a8SLen Brown /*******************************************************************************
13195b482a8SLen Brown *
13295b482a8SLen Brown * FUNCTION: acpi_enable_event
13395b482a8SLen Brown *
134ba494beeSBob Moore * PARAMETERS: event - The fixed eventto be enabled
135ba494beeSBob Moore * flags - Reserved
13695b482a8SLen Brown *
13795b482a8SLen Brown * RETURN: Status
13895b482a8SLen Brown *
13995b482a8SLen Brown * DESCRIPTION: Enable an ACPI event (fixed)
14095b482a8SLen Brown *
14195b482a8SLen Brown ******************************************************************************/
14295b482a8SLen Brown acpi_status acpi_enable_event(u32 event, u32 flags)
14395b482a8SLen Brown {
14495b482a8SLen Brown acpi_status status = AE_OK;
14595b482a8SLen Brown u32 value;
14695b482a8SLen Brown
14795b482a8SLen Brown ACPI_FUNCTION_TRACE(acpi_enable_event);
14895b482a8SLen Brown
149861ba635SLv Zheng /* If Hardware Reduced flag is set, there are no fixed events */
150861ba635SLv Zheng
151861ba635SLv Zheng if (acpi_gbl_reduced_hardware) {
152861ba635SLv Zheng return_ACPI_STATUS(AE_OK);
153861ba635SLv Zheng }
154861ba635SLv Zheng
15595b482a8SLen Brown /* Decode the Fixed Event */
15695b482a8SLen Brown
15795b482a8SLen Brown if (event > ACPI_EVENT_MAX) {
15895b482a8SLen Brown return_ACPI_STATUS(AE_BAD_PARAMETER);
15995b482a8SLen Brown }
16095b482a8SLen Brown
16195b482a8SLen Brown /*
16295b482a8SLen Brown * Enable the requested fixed event (by writing a one to the enable
16395b482a8SLen Brown * register bit)
16495b482a8SLen Brown */
16595b482a8SLen Brown status =
16650ffba1bSBob Moore acpi_write_bit_register(acpi_gbl_fixed_event_info[event].
167768aaaf1SBob Moore enable_register_id, ACPI_ENABLE_EVENT);
16895b482a8SLen Brown if (ACPI_FAILURE(status)) {
16995b482a8SLen Brown return_ACPI_STATUS(status);
17095b482a8SLen Brown }
17195b482a8SLen Brown
17295b482a8SLen Brown /* Make sure that the hardware responded */
17395b482a8SLen Brown
17495b482a8SLen Brown status =
17550ffba1bSBob Moore acpi_read_bit_register(acpi_gbl_fixed_event_info[event].
17695b482a8SLen Brown enable_register_id, &value);
17795b482a8SLen Brown if (ACPI_FAILURE(status)) {
17895b482a8SLen Brown return_ACPI_STATUS(status);
17995b482a8SLen Brown }
18095b482a8SLen Brown
18195b482a8SLen Brown if (value != 1) {
18295b482a8SLen Brown ACPI_ERROR((AE_INFO,
18395b482a8SLen Brown "Could not enable %s event",
18495b482a8SLen Brown acpi_ut_get_event_name(event)));
18595b482a8SLen Brown return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE);
18695b482a8SLen Brown }
18795b482a8SLen Brown
18895b482a8SLen Brown return_ACPI_STATUS(status);
18995b482a8SLen Brown }
19095b482a8SLen Brown
ACPI_EXPORT_SYMBOL(acpi_enable_event)19195b482a8SLen Brown ACPI_EXPORT_SYMBOL(acpi_enable_event)
19295b482a8SLen Brown
19395b482a8SLen Brown /*******************************************************************************
19495b482a8SLen Brown *
19595b482a8SLen Brown * FUNCTION: acpi_disable_event
19695b482a8SLen Brown *
19775c8044fSLv Zheng * PARAMETERS: event - The fixed event to be disabled
19875c8044fSLv Zheng * flags - Reserved
19995b482a8SLen Brown *
20095b482a8SLen Brown * RETURN: Status
20195b482a8SLen Brown *
20295b482a8SLen Brown * DESCRIPTION: Disable an ACPI event (fixed)
20395b482a8SLen Brown *
20495b482a8SLen Brown ******************************************************************************/
20595b482a8SLen Brown acpi_status acpi_disable_event(u32 event, u32 flags)
20695b482a8SLen Brown {
20795b482a8SLen Brown acpi_status status = AE_OK;
20895b482a8SLen Brown u32 value;
20995b482a8SLen Brown
21095b482a8SLen Brown ACPI_FUNCTION_TRACE(acpi_disable_event);
21195b482a8SLen Brown
212861ba635SLv Zheng /* If Hardware Reduced flag is set, there are no fixed events */
213861ba635SLv Zheng
214861ba635SLv Zheng if (acpi_gbl_reduced_hardware) {
215861ba635SLv Zheng return_ACPI_STATUS(AE_OK);
216861ba635SLv Zheng }
217861ba635SLv Zheng
21895b482a8SLen Brown /* Decode the Fixed Event */
21995b482a8SLen Brown
22095b482a8SLen Brown if (event > ACPI_EVENT_MAX) {
22195b482a8SLen Brown return_ACPI_STATUS(AE_BAD_PARAMETER);
22295b482a8SLen Brown }
22395b482a8SLen Brown
22495b482a8SLen Brown /*
22595b482a8SLen Brown * Disable the requested fixed event (by writing a zero to the enable
22695b482a8SLen Brown * register bit)
22795b482a8SLen Brown */
22895b482a8SLen Brown status =
22950ffba1bSBob Moore acpi_write_bit_register(acpi_gbl_fixed_event_info[event].
230768aaaf1SBob Moore enable_register_id, ACPI_DISABLE_EVENT);
23195b482a8SLen Brown if (ACPI_FAILURE(status)) {
23295b482a8SLen Brown return_ACPI_STATUS(status);
23395b482a8SLen Brown }
23495b482a8SLen Brown
23595b482a8SLen Brown status =
23650ffba1bSBob Moore acpi_read_bit_register(acpi_gbl_fixed_event_info[event].
23795b482a8SLen Brown enable_register_id, &value);
23895b482a8SLen Brown if (ACPI_FAILURE(status)) {
23995b482a8SLen Brown return_ACPI_STATUS(status);
24095b482a8SLen Brown }
24195b482a8SLen Brown
24295b482a8SLen Brown if (value != 0) {
24395b482a8SLen Brown ACPI_ERROR((AE_INFO,
24495b482a8SLen Brown "Could not disable %s events",
24595b482a8SLen Brown acpi_ut_get_event_name(event)));
24695b482a8SLen Brown return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE);
24795b482a8SLen Brown }
24895b482a8SLen Brown
24995b482a8SLen Brown return_ACPI_STATUS(status);
25095b482a8SLen Brown }
25195b482a8SLen Brown
ACPI_EXPORT_SYMBOL(acpi_disable_event)25295b482a8SLen Brown ACPI_EXPORT_SYMBOL(acpi_disable_event)
25395b482a8SLen Brown
25495b482a8SLen Brown /*******************************************************************************
25595b482a8SLen Brown *
25695b482a8SLen Brown * FUNCTION: acpi_clear_event
25795b482a8SLen Brown *
258ba494beeSBob Moore * PARAMETERS: event - The fixed event to be cleared
25995b482a8SLen Brown *
26095b482a8SLen Brown * RETURN: Status
26195b482a8SLen Brown *
26295b482a8SLen Brown * DESCRIPTION: Clear an ACPI event (fixed)
26395b482a8SLen Brown *
26495b482a8SLen Brown ******************************************************************************/
26595b482a8SLen Brown acpi_status acpi_clear_event(u32 event)
26695b482a8SLen Brown {
26795b482a8SLen Brown acpi_status status = AE_OK;
26895b482a8SLen Brown
26995b482a8SLen Brown ACPI_FUNCTION_TRACE(acpi_clear_event);
27095b482a8SLen Brown
271861ba635SLv Zheng /* If Hardware Reduced flag is set, there are no fixed events */
272861ba635SLv Zheng
273861ba635SLv Zheng if (acpi_gbl_reduced_hardware) {
274861ba635SLv Zheng return_ACPI_STATUS(AE_OK);
275861ba635SLv Zheng }
276861ba635SLv Zheng
27795b482a8SLen Brown /* Decode the Fixed Event */
27895b482a8SLen Brown
27995b482a8SLen Brown if (event > ACPI_EVENT_MAX) {
28095b482a8SLen Brown return_ACPI_STATUS(AE_BAD_PARAMETER);
28195b482a8SLen Brown }
28295b482a8SLen Brown
28395b482a8SLen Brown /*
28495b482a8SLen Brown * Clear the requested fixed event (By writing a one to the status
28595b482a8SLen Brown * register bit)
28695b482a8SLen Brown */
28795b482a8SLen Brown status =
28850ffba1bSBob Moore acpi_write_bit_register(acpi_gbl_fixed_event_info[event].
289768aaaf1SBob Moore status_register_id, ACPI_CLEAR_STATUS);
29095b482a8SLen Brown
29195b482a8SLen Brown return_ACPI_STATUS(status);
29295b482a8SLen Brown }
29395b482a8SLen Brown
ACPI_EXPORT_SYMBOL(acpi_clear_event)29495b482a8SLen Brown ACPI_EXPORT_SYMBOL(acpi_clear_event)
29595b482a8SLen Brown
29695b482a8SLen Brown /*******************************************************************************
29795b482a8SLen Brown *
29895b482a8SLen Brown * FUNCTION: acpi_get_event_status
29995b482a8SLen Brown *
300ba494beeSBob Moore * PARAMETERS: event - The fixed event
30195b482a8SLen Brown * event_status - Where the current status of the event will
30295b482a8SLen Brown * be returned
30395b482a8SLen Brown *
30495b482a8SLen Brown * RETURN: Status
30595b482a8SLen Brown *
30695b482a8SLen Brown * DESCRIPTION: Obtains and returns the current status of the event
30795b482a8SLen Brown *
30895b482a8SLen Brown ******************************************************************************/
30995b482a8SLen Brown acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status)
31095b482a8SLen Brown {
311a08f813eSLv Zheng acpi_status status;
312a08f813eSLv Zheng acpi_event_status local_event_status = 0;
313a08f813eSLv Zheng u32 in_byte;
31495b482a8SLen Brown
31595b482a8SLen Brown ACPI_FUNCTION_TRACE(acpi_get_event_status);
31695b482a8SLen Brown
31795b482a8SLen Brown if (!event_status) {
31895b482a8SLen Brown return_ACPI_STATUS(AE_BAD_PARAMETER);
31995b482a8SLen Brown }
32095b482a8SLen Brown
32195b482a8SLen Brown /* Decode the Fixed Event */
32295b482a8SLen Brown
32395b482a8SLen Brown if (event > ACPI_EVENT_MAX) {
32495b482a8SLen Brown return_ACPI_STATUS(AE_BAD_PARAMETER);
32595b482a8SLen Brown }
32695b482a8SLen Brown
327a08f813eSLv Zheng /* Fixed event currently can be dispatched? */
328a08f813eSLv Zheng
329a08f813eSLv Zheng if (acpi_gbl_fixed_event_handlers[event].handler) {
3302f857234SLv Zheng local_event_status |= ACPI_EVENT_FLAG_HAS_HANDLER;
331a08f813eSLv Zheng }
332a08f813eSLv Zheng
333a08f813eSLv Zheng /* Fixed event currently enabled? */
33495b482a8SLen Brown
33595b482a8SLen Brown status =
33650ffba1bSBob Moore acpi_read_bit_register(acpi_gbl_fixed_event_info[event].
337a08f813eSLv Zheng enable_register_id, &in_byte);
338a08f813eSLv Zheng if (ACPI_FAILURE(status)) {
33995b482a8SLen Brown return_ACPI_STATUS(status);
340a08f813eSLv Zheng }
34195b482a8SLen Brown
342a08f813eSLv Zheng if (in_byte) {
34309af8e82SLv Zheng local_event_status |=
34409af8e82SLv Zheng (ACPI_EVENT_FLAG_ENABLED | ACPI_EVENT_FLAG_ENABLE_SET);
345a08f813eSLv Zheng }
346a08f813eSLv Zheng
347a08f813eSLv Zheng /* Fixed event currently active? */
34895b482a8SLen Brown
34995b482a8SLen Brown status =
35050ffba1bSBob Moore acpi_read_bit_register(acpi_gbl_fixed_event_info[event].
351a08f813eSLv Zheng status_register_id, &in_byte);
352a08f813eSLv Zheng if (ACPI_FAILURE(status)) {
35395b482a8SLen Brown return_ACPI_STATUS(status);
354a08f813eSLv Zheng }
35595b482a8SLen Brown
356a08f813eSLv Zheng if (in_byte) {
35709af8e82SLv Zheng local_event_status |= ACPI_EVENT_FLAG_STATUS_SET;
358a08f813eSLv Zheng }
35995b482a8SLen Brown
360a08f813eSLv Zheng (*event_status) = local_event_status;
361a08f813eSLv Zheng return_ACPI_STATUS(AE_OK);
36295b482a8SLen Brown }
36395b482a8SLen Brown
36495b482a8SLen Brown ACPI_EXPORT_SYMBOL(acpi_get_event_status)
36533620c54SBob Moore #endif /* !ACPI_REDUCED_HARDWARE */
366