xref: /openbmc/linux/drivers/acpi/acpica/evxfevnt.c (revision 2f857234)
195b482a8SLen Brown /******************************************************************************
295b482a8SLen Brown  *
395b482a8SLen Brown  * Module Name: evxfevnt - External Interfaces, ACPI event disable/enable
495b482a8SLen Brown  *
595b482a8SLen Brown  *****************************************************************************/
695b482a8SLen Brown 
795b482a8SLen Brown /*
8fbb7a2dcSBob Moore  * Copyright (C) 2000 - 2014, Intel Corp.
995b482a8SLen Brown  * All rights reserved.
1095b482a8SLen Brown  *
1195b482a8SLen Brown  * Redistribution and use in source and binary forms, with or without
1295b482a8SLen Brown  * modification, are permitted provided that the following conditions
1395b482a8SLen Brown  * are met:
1495b482a8SLen Brown  * 1. Redistributions of source code must retain the above copyright
1595b482a8SLen Brown  *    notice, this list of conditions, and the following disclaimer,
1695b482a8SLen Brown  *    without modification.
1795b482a8SLen Brown  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
1895b482a8SLen Brown  *    substantially similar to the "NO WARRANTY" disclaimer below
1995b482a8SLen Brown  *    ("Disclaimer") and any redistribution must be conditioned upon
2095b482a8SLen Brown  *    including a substantially similar Disclaimer requirement for further
2195b482a8SLen Brown  *    binary redistribution.
2295b482a8SLen Brown  * 3. Neither the names of the above-listed copyright holders nor the names
2395b482a8SLen Brown  *    of any contributors may be used to endorse or promote products derived
2495b482a8SLen Brown  *    from this software without specific prior written permission.
2595b482a8SLen Brown  *
2695b482a8SLen Brown  * Alternatively, this software may be distributed under the terms of the
2795b482a8SLen Brown  * GNU General Public License ("GPL") version 2 as published by the Free
2895b482a8SLen Brown  * Software Foundation.
2995b482a8SLen Brown  *
3095b482a8SLen Brown  * NO WARRANTY
3195b482a8SLen Brown  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
3295b482a8SLen Brown  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3395b482a8SLen Brown  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
3495b482a8SLen Brown  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
3595b482a8SLen Brown  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
3695b482a8SLen Brown  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
3795b482a8SLen Brown  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3895b482a8SLen Brown  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
3995b482a8SLen Brown  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
4095b482a8SLen Brown  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
4195b482a8SLen Brown  * POSSIBILITY OF SUCH DAMAGES.
4295b482a8SLen Brown  */
4395b482a8SLen Brown 
44839e928fSLv Zheng #define EXPORT_ACPI_INTERFACES
45839e928fSLv Zheng 
4695b482a8SLen Brown #include <acpi/acpi.h>
47e2f7a777SLen Brown #include "accommon.h"
48e2f7a777SLen Brown #include "actables.h"
4995b482a8SLen Brown 
5095b482a8SLen Brown #define _COMPONENT          ACPI_EVENTS
5195b482a8SLen Brown ACPI_MODULE_NAME("evxfevnt")
5295b482a8SLen Brown 
5333620c54SBob Moore #if (!ACPI_REDUCED_HARDWARE)	/* Entire module */
5495b482a8SLen Brown /*******************************************************************************
5595b482a8SLen Brown  *
5695b482a8SLen Brown  * FUNCTION:    acpi_enable
5795b482a8SLen Brown  *
5895b482a8SLen Brown  * PARAMETERS:  None
5995b482a8SLen Brown  *
6095b482a8SLen Brown  * RETURN:      Status
6195b482a8SLen Brown  *
6295b482a8SLen Brown  * DESCRIPTION: Transfers the system into ACPI mode.
6395b482a8SLen Brown  *
6495b482a8SLen Brown  ******************************************************************************/
6595b482a8SLen Brown acpi_status acpi_enable(void)
6695b482a8SLen Brown {
67b430acbdSLen Brown 	acpi_status status;
683d695839SLen Brown 	int retry;
6995b482a8SLen Brown 
7095b482a8SLen Brown 	ACPI_FUNCTION_TRACE(acpi_enable);
7195b482a8SLen Brown 
7295b482a8SLen Brown 	/* ACPI tables must be present */
7395b482a8SLen Brown 
7495b482a8SLen Brown 	if (!acpi_tb_tables_loaded()) {
7595b482a8SLen Brown 		return_ACPI_STATUS(AE_NO_ACPI_TABLES);
7695b482a8SLen Brown 	}
7795b482a8SLen Brown 
78c39660b2SBob Moore 	/* If the Hardware Reduced flag is set, machine is always in acpi mode */
79c39660b2SBob Moore 
80c39660b2SBob Moore 	if (acpi_gbl_reduced_hardware) {
81c39660b2SBob Moore 		return_ACPI_STATUS(AE_OK);
82c39660b2SBob Moore 	}
83c39660b2SBob Moore 
8495b482a8SLen Brown 	/* Check current mode */
8595b482a8SLen Brown 
8695b482a8SLen Brown 	if (acpi_hw_get_mode() == ACPI_SYS_MODE_ACPI) {
8795b482a8SLen Brown 		ACPI_DEBUG_PRINT((ACPI_DB_INIT,
8895b482a8SLen Brown 				  "System is already in ACPI mode\n"));
89b430acbdSLen Brown 		return_ACPI_STATUS(AE_OK);
90b430acbdSLen Brown 	}
91b430acbdSLen Brown 
9295b482a8SLen Brown 	/* Transition to ACPI mode */
9395b482a8SLen Brown 
9495b482a8SLen Brown 	status = acpi_hw_set_mode(ACPI_SYS_MODE_ACPI);
9595b482a8SLen Brown 	if (ACPI_FAILURE(status)) {
9695b482a8SLen Brown 		ACPI_ERROR((AE_INFO,
9795b482a8SLen Brown 			    "Could not transition to ACPI mode"));
9895b482a8SLen Brown 		return_ACPI_STATUS(status);
9995b482a8SLen Brown 	}
10095b482a8SLen Brown 
101b430acbdSLen Brown 	/* Sanity check that transition succeeded */
102b430acbdSLen Brown 
1033d695839SLen Brown 	for (retry = 0; retry < 30000; ++retry) {
1043d695839SLen Brown 		if (acpi_hw_get_mode() == ACPI_SYS_MODE_ACPI) {
1053d695839SLen Brown 			if (retry != 0)
1063d695839SLen Brown 				ACPI_WARNING((AE_INFO,
1073d695839SLen Brown 				"Platform took > %d00 usec to enter ACPI mode", retry));
1083d695839SLen Brown 			return_ACPI_STATUS(AE_OK);
1093d695839SLen Brown 		}
1103d695839SLen Brown 		acpi_os_stall(100);	/* 100 usec */
11195b482a8SLen Brown 	}
11295b482a8SLen Brown 
1133d695839SLen Brown 	ACPI_ERROR((AE_INFO, "Hardware did not enter ACPI mode"));
1143d695839SLen Brown 	return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE);
11595b482a8SLen Brown }
11695b482a8SLen Brown 
11795b482a8SLen Brown ACPI_EXPORT_SYMBOL(acpi_enable)
11895b482a8SLen Brown 
11995b482a8SLen Brown /*******************************************************************************
12095b482a8SLen Brown  *
12195b482a8SLen Brown  * FUNCTION:    acpi_disable
12295b482a8SLen Brown  *
12395b482a8SLen Brown  * PARAMETERS:  None
12495b482a8SLen Brown  *
12595b482a8SLen Brown  * RETURN:      Status
12695b482a8SLen Brown  *
12795b482a8SLen Brown  * DESCRIPTION: Transfers the system into LEGACY (non-ACPI) mode.
12895b482a8SLen Brown  *
12995b482a8SLen Brown  ******************************************************************************/
13095b482a8SLen Brown acpi_status acpi_disable(void)
13195b482a8SLen Brown {
13295b482a8SLen Brown 	acpi_status status = AE_OK;
13395b482a8SLen Brown 
13495b482a8SLen Brown 	ACPI_FUNCTION_TRACE(acpi_disable);
13595b482a8SLen Brown 
136c39660b2SBob Moore 	/* If the Hardware Reduced flag is set, machine is always in acpi mode */
137c39660b2SBob Moore 
138c39660b2SBob Moore 	if (acpi_gbl_reduced_hardware) {
139c39660b2SBob Moore 		return_ACPI_STATUS(AE_OK);
140c39660b2SBob Moore 	}
141c39660b2SBob Moore 
14295b482a8SLen Brown 	if (acpi_hw_get_mode() == ACPI_SYS_MODE_LEGACY) {
14395b482a8SLen Brown 		ACPI_DEBUG_PRINT((ACPI_DB_INIT,
14495b482a8SLen Brown 				  "System is already in legacy (non-ACPI) mode\n"));
14595b482a8SLen Brown 	} else {
14695b482a8SLen Brown 		/* Transition to LEGACY mode */
14795b482a8SLen Brown 
14895b482a8SLen Brown 		status = acpi_hw_set_mode(ACPI_SYS_MODE_LEGACY);
14995b482a8SLen Brown 
15095b482a8SLen Brown 		if (ACPI_FAILURE(status)) {
15195b482a8SLen Brown 			ACPI_ERROR((AE_INFO,
15295b482a8SLen Brown 				    "Could not exit ACPI mode to legacy mode"));
15395b482a8SLen Brown 			return_ACPI_STATUS(status);
15495b482a8SLen Brown 		}
15595b482a8SLen Brown 
15695b482a8SLen Brown 		ACPI_DEBUG_PRINT((ACPI_DB_INIT, "ACPI mode disabled\n"));
15795b482a8SLen Brown 	}
15895b482a8SLen Brown 
15995b482a8SLen Brown 	return_ACPI_STATUS(status);
16095b482a8SLen Brown }
16195b482a8SLen Brown 
16295b482a8SLen Brown ACPI_EXPORT_SYMBOL(acpi_disable)
16395b482a8SLen Brown 
16495b482a8SLen Brown /*******************************************************************************
16595b482a8SLen Brown  *
16695b482a8SLen Brown  * FUNCTION:    acpi_enable_event
16795b482a8SLen Brown  *
168ba494beeSBob Moore  * PARAMETERS:  event           - The fixed eventto be enabled
169ba494beeSBob Moore  *              flags           - Reserved
17095b482a8SLen Brown  *
17195b482a8SLen Brown  * RETURN:      Status
17295b482a8SLen Brown  *
17395b482a8SLen Brown  * DESCRIPTION: Enable an ACPI event (fixed)
17495b482a8SLen Brown  *
17595b482a8SLen Brown  ******************************************************************************/
17695b482a8SLen Brown acpi_status acpi_enable_event(u32 event, u32 flags)
17795b482a8SLen Brown {
17895b482a8SLen Brown 	acpi_status status = AE_OK;
17995b482a8SLen Brown 	u32 value;
18095b482a8SLen Brown 
18195b482a8SLen Brown 	ACPI_FUNCTION_TRACE(acpi_enable_event);
18295b482a8SLen Brown 
18395b482a8SLen Brown 	/* Decode the Fixed Event */
18495b482a8SLen Brown 
18595b482a8SLen Brown 	if (event > ACPI_EVENT_MAX) {
18695b482a8SLen Brown 		return_ACPI_STATUS(AE_BAD_PARAMETER);
18795b482a8SLen Brown 	}
18895b482a8SLen Brown 
18995b482a8SLen Brown 	/*
19095b482a8SLen Brown 	 * Enable the requested fixed event (by writing a one to the enable
19195b482a8SLen Brown 	 * register bit)
19295b482a8SLen Brown 	 */
19395b482a8SLen Brown 	status =
19450ffba1bSBob Moore 	    acpi_write_bit_register(acpi_gbl_fixed_event_info[event].
195768aaaf1SBob Moore 				    enable_register_id, ACPI_ENABLE_EVENT);
19695b482a8SLen Brown 	if (ACPI_FAILURE(status)) {
19795b482a8SLen Brown 		return_ACPI_STATUS(status);
19895b482a8SLen Brown 	}
19995b482a8SLen Brown 
20095b482a8SLen Brown 	/* Make sure that the hardware responded */
20195b482a8SLen Brown 
20295b482a8SLen Brown 	status =
20350ffba1bSBob Moore 	    acpi_read_bit_register(acpi_gbl_fixed_event_info[event].
20495b482a8SLen Brown 				   enable_register_id, &value);
20595b482a8SLen Brown 	if (ACPI_FAILURE(status)) {
20695b482a8SLen Brown 		return_ACPI_STATUS(status);
20795b482a8SLen Brown 	}
20895b482a8SLen Brown 
20995b482a8SLen Brown 	if (value != 1) {
21095b482a8SLen Brown 		ACPI_ERROR((AE_INFO,
21195b482a8SLen Brown 			    "Could not enable %s event",
21295b482a8SLen Brown 			    acpi_ut_get_event_name(event)));
21395b482a8SLen Brown 		return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE);
21495b482a8SLen Brown 	}
21595b482a8SLen Brown 
21695b482a8SLen Brown 	return_ACPI_STATUS(status);
21795b482a8SLen Brown }
21895b482a8SLen Brown 
21995b482a8SLen Brown ACPI_EXPORT_SYMBOL(acpi_enable_event)
22095b482a8SLen Brown 
22195b482a8SLen Brown /*******************************************************************************
22295b482a8SLen Brown  *
22395b482a8SLen Brown  * FUNCTION:    acpi_disable_event
22495b482a8SLen Brown  *
22575c8044fSLv Zheng  * PARAMETERS:  event           - The fixed event to be disabled
22675c8044fSLv Zheng  *              flags           - Reserved
22795b482a8SLen Brown  *
22895b482a8SLen Brown  * RETURN:      Status
22995b482a8SLen Brown  *
23095b482a8SLen Brown  * DESCRIPTION: Disable an ACPI event (fixed)
23195b482a8SLen Brown  *
23295b482a8SLen Brown  ******************************************************************************/
23395b482a8SLen Brown acpi_status acpi_disable_event(u32 event, u32 flags)
23495b482a8SLen Brown {
23595b482a8SLen Brown 	acpi_status status = AE_OK;
23695b482a8SLen Brown 	u32 value;
23795b482a8SLen Brown 
23895b482a8SLen Brown 	ACPI_FUNCTION_TRACE(acpi_disable_event);
23995b482a8SLen Brown 
24095b482a8SLen Brown 	/* Decode the Fixed Event */
24195b482a8SLen Brown 
24295b482a8SLen Brown 	if (event > ACPI_EVENT_MAX) {
24395b482a8SLen Brown 		return_ACPI_STATUS(AE_BAD_PARAMETER);
24495b482a8SLen Brown 	}
24595b482a8SLen Brown 
24695b482a8SLen Brown 	/*
24795b482a8SLen Brown 	 * Disable the requested fixed event (by writing a zero to the enable
24895b482a8SLen Brown 	 * register bit)
24995b482a8SLen Brown 	 */
25095b482a8SLen Brown 	status =
25150ffba1bSBob Moore 	    acpi_write_bit_register(acpi_gbl_fixed_event_info[event].
252768aaaf1SBob Moore 				    enable_register_id, ACPI_DISABLE_EVENT);
25395b482a8SLen Brown 	if (ACPI_FAILURE(status)) {
25495b482a8SLen Brown 		return_ACPI_STATUS(status);
25595b482a8SLen Brown 	}
25695b482a8SLen Brown 
25795b482a8SLen Brown 	status =
25850ffba1bSBob Moore 	    acpi_read_bit_register(acpi_gbl_fixed_event_info[event].
25995b482a8SLen Brown 				   enable_register_id, &value);
26095b482a8SLen Brown 	if (ACPI_FAILURE(status)) {
26195b482a8SLen Brown 		return_ACPI_STATUS(status);
26295b482a8SLen Brown 	}
26395b482a8SLen Brown 
26495b482a8SLen Brown 	if (value != 0) {
26595b482a8SLen Brown 		ACPI_ERROR((AE_INFO,
26695b482a8SLen Brown 			    "Could not disable %s events",
26795b482a8SLen Brown 			    acpi_ut_get_event_name(event)));
26895b482a8SLen Brown 		return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE);
26995b482a8SLen Brown 	}
27095b482a8SLen Brown 
27195b482a8SLen Brown 	return_ACPI_STATUS(status);
27295b482a8SLen Brown }
27395b482a8SLen Brown 
27495b482a8SLen Brown ACPI_EXPORT_SYMBOL(acpi_disable_event)
27595b482a8SLen Brown 
27695b482a8SLen Brown /*******************************************************************************
27795b482a8SLen Brown  *
27895b482a8SLen Brown  * FUNCTION:    acpi_clear_event
27995b482a8SLen Brown  *
280ba494beeSBob Moore  * PARAMETERS:  event           - The fixed event to be cleared
28195b482a8SLen Brown  *
28295b482a8SLen Brown  * RETURN:      Status
28395b482a8SLen Brown  *
28495b482a8SLen Brown  * DESCRIPTION: Clear an ACPI event (fixed)
28595b482a8SLen Brown  *
28695b482a8SLen Brown  ******************************************************************************/
28795b482a8SLen Brown acpi_status acpi_clear_event(u32 event)
28895b482a8SLen Brown {
28995b482a8SLen Brown 	acpi_status status = AE_OK;
29095b482a8SLen Brown 
29195b482a8SLen Brown 	ACPI_FUNCTION_TRACE(acpi_clear_event);
29295b482a8SLen Brown 
29395b482a8SLen Brown 	/* Decode the Fixed Event */
29495b482a8SLen Brown 
29595b482a8SLen Brown 	if (event > ACPI_EVENT_MAX) {
29695b482a8SLen Brown 		return_ACPI_STATUS(AE_BAD_PARAMETER);
29795b482a8SLen Brown 	}
29895b482a8SLen Brown 
29995b482a8SLen Brown 	/*
30095b482a8SLen Brown 	 * Clear the requested fixed event (By writing a one to the status
30195b482a8SLen Brown 	 * register bit)
30295b482a8SLen Brown 	 */
30395b482a8SLen Brown 	status =
30450ffba1bSBob Moore 	    acpi_write_bit_register(acpi_gbl_fixed_event_info[event].
305768aaaf1SBob Moore 				    status_register_id, ACPI_CLEAR_STATUS);
30695b482a8SLen Brown 
30795b482a8SLen Brown 	return_ACPI_STATUS(status);
30895b482a8SLen Brown }
30995b482a8SLen Brown 
31095b482a8SLen Brown ACPI_EXPORT_SYMBOL(acpi_clear_event)
31195b482a8SLen Brown 
31295b482a8SLen Brown /*******************************************************************************
31395b482a8SLen Brown  *
31495b482a8SLen Brown  * FUNCTION:    acpi_get_event_status
31595b482a8SLen Brown  *
316ba494beeSBob Moore  * PARAMETERS:  event           - The fixed event
31795b482a8SLen Brown  *              event_status    - Where the current status of the event will
31895b482a8SLen Brown  *                                be returned
31995b482a8SLen Brown  *
32095b482a8SLen Brown  * RETURN:      Status
32195b482a8SLen Brown  *
32295b482a8SLen Brown  * DESCRIPTION: Obtains and returns the current status of the event
32395b482a8SLen Brown  *
32495b482a8SLen Brown  ******************************************************************************/
32595b482a8SLen Brown acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status)
32695b482a8SLen Brown {
327a08f813eSLv Zheng 	acpi_status status;
328a08f813eSLv Zheng 	acpi_event_status local_event_status = 0;
329a08f813eSLv Zheng 	u32 in_byte;
33095b482a8SLen Brown 
33195b482a8SLen Brown 	ACPI_FUNCTION_TRACE(acpi_get_event_status);
33295b482a8SLen Brown 
33395b482a8SLen Brown 	if (!event_status) {
33495b482a8SLen Brown 		return_ACPI_STATUS(AE_BAD_PARAMETER);
33595b482a8SLen Brown 	}
33695b482a8SLen Brown 
33795b482a8SLen Brown 	/* Decode the Fixed Event */
33895b482a8SLen Brown 
33995b482a8SLen Brown 	if (event > ACPI_EVENT_MAX) {
34095b482a8SLen Brown 		return_ACPI_STATUS(AE_BAD_PARAMETER);
34195b482a8SLen Brown 	}
34295b482a8SLen Brown 
343a08f813eSLv Zheng 	/* Fixed event currently can be dispatched? */
344a08f813eSLv Zheng 
345a08f813eSLv Zheng 	if (acpi_gbl_fixed_event_handlers[event].handler) {
3462f857234SLv Zheng 		local_event_status |= ACPI_EVENT_FLAG_HAS_HANDLER;
347a08f813eSLv Zheng 	}
348a08f813eSLv Zheng 
349a08f813eSLv Zheng 	/* Fixed event currently enabled? */
35095b482a8SLen Brown 
35195b482a8SLen Brown 	status =
35250ffba1bSBob Moore 	    acpi_read_bit_register(acpi_gbl_fixed_event_info[event].
353a08f813eSLv Zheng 				   enable_register_id, &in_byte);
354a08f813eSLv Zheng 	if (ACPI_FAILURE(status)) {
35595b482a8SLen Brown 		return_ACPI_STATUS(status);
356a08f813eSLv Zheng 	}
35795b482a8SLen Brown 
358a08f813eSLv Zheng 	if (in_byte) {
359a08f813eSLv Zheng 		local_event_status |= ACPI_EVENT_FLAG_ENABLED;
360a08f813eSLv Zheng 	}
361a08f813eSLv Zheng 
362a08f813eSLv Zheng 	/* Fixed event currently active? */
36395b482a8SLen Brown 
36495b482a8SLen Brown 	status =
36550ffba1bSBob Moore 	    acpi_read_bit_register(acpi_gbl_fixed_event_info[event].
366a08f813eSLv Zheng 				   status_register_id, &in_byte);
367a08f813eSLv Zheng 	if (ACPI_FAILURE(status)) {
36895b482a8SLen Brown 		return_ACPI_STATUS(status);
369a08f813eSLv Zheng 	}
37095b482a8SLen Brown 
371a08f813eSLv Zheng 	if (in_byte) {
372a08f813eSLv Zheng 		local_event_status |= ACPI_EVENT_FLAG_SET;
373a08f813eSLv Zheng 	}
37495b482a8SLen Brown 
375a08f813eSLv Zheng 	(*event_status) = local_event_status;
376a08f813eSLv Zheng 	return_ACPI_STATUS(AE_OK);
37795b482a8SLen Brown }
37895b482a8SLen Brown 
37995b482a8SLen Brown ACPI_EXPORT_SYMBOL(acpi_get_event_status)
38033620c54SBob Moore #endif				/* !ACPI_REDUCED_HARDWARE */
381