xref: /openbmc/linux/drivers/acpi/acpica/evxfevnt.c (revision 50ffba1b)
195b482a8SLen Brown /******************************************************************************
295b482a8SLen Brown  *
395b482a8SLen Brown  * Module Name: evxfevnt - External Interfaces, ACPI event disable/enable
495b482a8SLen Brown  *
595b482a8SLen Brown  *****************************************************************************/
695b482a8SLen Brown 
795b482a8SLen Brown /*
895b482a8SLen Brown  * Copyright (C) 2000 - 2008, 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 
4495b482a8SLen Brown #include <acpi/acpi.h>
45e2f7a777SLen Brown #include "accommon.h"
46e2f7a777SLen Brown #include "acevents.h"
47e2f7a777SLen Brown #include "acnamesp.h"
48e2f7a777SLen Brown #include "actables.h"
4995b482a8SLen Brown 
5095b482a8SLen Brown #define _COMPONENT          ACPI_EVENTS
5195b482a8SLen Brown ACPI_MODULE_NAME("evxfevnt")
5295b482a8SLen Brown 
5395b482a8SLen Brown /* Local prototypes */
5495b482a8SLen Brown acpi_status
5595b482a8SLen Brown acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
5695b482a8SLen Brown 		       struct acpi_gpe_block_info *gpe_block, void *context);
5795b482a8SLen Brown 
5895b482a8SLen Brown /*******************************************************************************
5995b482a8SLen Brown  *
6095b482a8SLen Brown  * FUNCTION:    acpi_enable
6195b482a8SLen Brown  *
6295b482a8SLen Brown  * PARAMETERS:  None
6395b482a8SLen Brown  *
6495b482a8SLen Brown  * RETURN:      Status
6595b482a8SLen Brown  *
6695b482a8SLen Brown  * DESCRIPTION: Transfers the system into ACPI mode.
6795b482a8SLen Brown  *
6895b482a8SLen Brown  ******************************************************************************/
6995b482a8SLen Brown 
7095b482a8SLen Brown acpi_status acpi_enable(void)
7195b482a8SLen Brown {
7295b482a8SLen Brown 	acpi_status status = AE_OK;
7395b482a8SLen Brown 
7495b482a8SLen Brown 	ACPI_FUNCTION_TRACE(acpi_enable);
7595b482a8SLen Brown 
7695b482a8SLen Brown 	/* ACPI tables must be present */
7795b482a8SLen Brown 
7895b482a8SLen Brown 	if (!acpi_tb_tables_loaded()) {
7995b482a8SLen Brown 		return_ACPI_STATUS(AE_NO_ACPI_TABLES);
8095b482a8SLen Brown 	}
8195b482a8SLen Brown 
8295b482a8SLen Brown 	/* Check current mode */
8395b482a8SLen Brown 
8495b482a8SLen Brown 	if (acpi_hw_get_mode() == ACPI_SYS_MODE_ACPI) {
8595b482a8SLen Brown 		ACPI_DEBUG_PRINT((ACPI_DB_INIT,
8695b482a8SLen Brown 				  "System is already in ACPI mode\n"));
8795b482a8SLen Brown 	} else {
8895b482a8SLen Brown 		/* Transition to ACPI mode */
8995b482a8SLen Brown 
9095b482a8SLen Brown 		status = acpi_hw_set_mode(ACPI_SYS_MODE_ACPI);
9195b482a8SLen Brown 		if (ACPI_FAILURE(status)) {
9295b482a8SLen Brown 			ACPI_ERROR((AE_INFO,
9395b482a8SLen Brown 				    "Could not transition to ACPI mode"));
9495b482a8SLen Brown 			return_ACPI_STATUS(status);
9595b482a8SLen Brown 		}
9695b482a8SLen Brown 
9795b482a8SLen Brown 		ACPI_DEBUG_PRINT((ACPI_DB_INIT,
9895b482a8SLen Brown 				  "Transition to ACPI mode successful\n"));
9995b482a8SLen Brown 	}
10095b482a8SLen Brown 
10195b482a8SLen Brown 	return_ACPI_STATUS(status);
10295b482a8SLen Brown }
10395b482a8SLen Brown 
10495b482a8SLen Brown ACPI_EXPORT_SYMBOL(acpi_enable)
10595b482a8SLen Brown 
10695b482a8SLen Brown /*******************************************************************************
10795b482a8SLen Brown  *
10895b482a8SLen Brown  * FUNCTION:    acpi_disable
10995b482a8SLen Brown  *
11095b482a8SLen Brown  * PARAMETERS:  None
11195b482a8SLen Brown  *
11295b482a8SLen Brown  * RETURN:      Status
11395b482a8SLen Brown  *
11495b482a8SLen Brown  * DESCRIPTION: Transfers the system into LEGACY (non-ACPI) mode.
11595b482a8SLen Brown  *
11695b482a8SLen Brown  ******************************************************************************/
11795b482a8SLen Brown acpi_status acpi_disable(void)
11895b482a8SLen Brown {
11995b482a8SLen Brown 	acpi_status status = AE_OK;
12095b482a8SLen Brown 
12195b482a8SLen Brown 	ACPI_FUNCTION_TRACE(acpi_disable);
12295b482a8SLen Brown 
12395b482a8SLen Brown 	if (acpi_hw_get_mode() == ACPI_SYS_MODE_LEGACY) {
12495b482a8SLen Brown 		ACPI_DEBUG_PRINT((ACPI_DB_INIT,
12595b482a8SLen Brown 				  "System is already in legacy (non-ACPI) mode\n"));
12695b482a8SLen Brown 	} else {
12795b482a8SLen Brown 		/* Transition to LEGACY mode */
12895b482a8SLen Brown 
12995b482a8SLen Brown 		status = acpi_hw_set_mode(ACPI_SYS_MODE_LEGACY);
13095b482a8SLen Brown 
13195b482a8SLen Brown 		if (ACPI_FAILURE(status)) {
13295b482a8SLen Brown 			ACPI_ERROR((AE_INFO,
13395b482a8SLen Brown 				    "Could not exit ACPI mode to legacy mode"));
13495b482a8SLen Brown 			return_ACPI_STATUS(status);
13595b482a8SLen Brown 		}
13695b482a8SLen Brown 
13795b482a8SLen Brown 		ACPI_DEBUG_PRINT((ACPI_DB_INIT, "ACPI mode disabled\n"));
13895b482a8SLen Brown 	}
13995b482a8SLen Brown 
14095b482a8SLen Brown 	return_ACPI_STATUS(status);
14195b482a8SLen Brown }
14295b482a8SLen Brown 
14395b482a8SLen Brown ACPI_EXPORT_SYMBOL(acpi_disable)
14495b482a8SLen Brown 
14595b482a8SLen Brown /*******************************************************************************
14695b482a8SLen Brown  *
14795b482a8SLen Brown  * FUNCTION:    acpi_enable_event
14895b482a8SLen Brown  *
14995b482a8SLen Brown  * PARAMETERS:  Event           - The fixed eventto be enabled
15095b482a8SLen Brown  *              Flags           - Reserved
15195b482a8SLen Brown  *
15295b482a8SLen Brown  * RETURN:      Status
15395b482a8SLen Brown  *
15495b482a8SLen Brown  * DESCRIPTION: Enable an ACPI event (fixed)
15595b482a8SLen Brown  *
15695b482a8SLen Brown  ******************************************************************************/
15795b482a8SLen Brown acpi_status acpi_enable_event(u32 event, u32 flags)
15895b482a8SLen Brown {
15995b482a8SLen Brown 	acpi_status status = AE_OK;
16095b482a8SLen Brown 	u32 value;
16195b482a8SLen Brown 
16295b482a8SLen Brown 	ACPI_FUNCTION_TRACE(acpi_enable_event);
16395b482a8SLen Brown 
16495b482a8SLen Brown 	/* Decode the Fixed Event */
16595b482a8SLen Brown 
16695b482a8SLen Brown 	if (event > ACPI_EVENT_MAX) {
16795b482a8SLen Brown 		return_ACPI_STATUS(AE_BAD_PARAMETER);
16895b482a8SLen Brown 	}
16995b482a8SLen Brown 
17095b482a8SLen Brown 	/*
17195b482a8SLen Brown 	 * Enable the requested fixed event (by writing a one to the enable
17295b482a8SLen Brown 	 * register bit)
17395b482a8SLen Brown 	 */
17495b482a8SLen Brown 	status =
17550ffba1bSBob Moore 	    acpi_write_bit_register(acpi_gbl_fixed_event_info[event].
17695b482a8SLen Brown 				    enable_register_id, 1);
17795b482a8SLen Brown 	if (ACPI_FAILURE(status)) {
17895b482a8SLen Brown 		return_ACPI_STATUS(status);
17995b482a8SLen Brown 	}
18095b482a8SLen Brown 
18195b482a8SLen Brown 	/* Make sure that the hardware responded */
18295b482a8SLen Brown 
18395b482a8SLen Brown 	status =
18450ffba1bSBob Moore 	    acpi_read_bit_register(acpi_gbl_fixed_event_info[event].
18595b482a8SLen Brown 				   enable_register_id, &value);
18695b482a8SLen Brown 	if (ACPI_FAILURE(status)) {
18795b482a8SLen Brown 		return_ACPI_STATUS(status);
18895b482a8SLen Brown 	}
18995b482a8SLen Brown 
19095b482a8SLen Brown 	if (value != 1) {
19195b482a8SLen Brown 		ACPI_ERROR((AE_INFO,
19295b482a8SLen Brown 			    "Could not enable %s event",
19395b482a8SLen Brown 			    acpi_ut_get_event_name(event)));
19495b482a8SLen Brown 		return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE);
19595b482a8SLen Brown 	}
19695b482a8SLen Brown 
19795b482a8SLen Brown 	return_ACPI_STATUS(status);
19895b482a8SLen Brown }
19995b482a8SLen Brown 
20095b482a8SLen Brown ACPI_EXPORT_SYMBOL(acpi_enable_event)
20195b482a8SLen Brown 
20295b482a8SLen Brown /*******************************************************************************
20395b482a8SLen Brown  *
20495b482a8SLen Brown  * FUNCTION:    acpi_set_gpe_type
20595b482a8SLen Brown  *
20695b482a8SLen Brown  * PARAMETERS:  gpe_device      - Parent GPE Device
20795b482a8SLen Brown  *              gpe_number      - GPE level within the GPE block
20895b482a8SLen Brown  *              Type            - New GPE type
20995b482a8SLen Brown  *
21095b482a8SLen Brown  * RETURN:      Status
21195b482a8SLen Brown  *
21295b482a8SLen Brown  * DESCRIPTION: Set the type of an individual GPE
21395b482a8SLen Brown  *
21495b482a8SLen Brown  ******************************************************************************/
21595b482a8SLen Brown acpi_status acpi_set_gpe_type(acpi_handle gpe_device, u32 gpe_number, u8 type)
21695b482a8SLen Brown {
21795b482a8SLen Brown 	acpi_status status = AE_OK;
21895b482a8SLen Brown 	struct acpi_gpe_event_info *gpe_event_info;
21995b482a8SLen Brown 
22095b482a8SLen Brown 	ACPI_FUNCTION_TRACE(acpi_set_gpe_type);
22195b482a8SLen Brown 
22295b482a8SLen Brown 	/* Ensure that we have a valid GPE number */
22395b482a8SLen Brown 
22495b482a8SLen Brown 	gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
22595b482a8SLen Brown 	if (!gpe_event_info) {
22695b482a8SLen Brown 		status = AE_BAD_PARAMETER;
22795b482a8SLen Brown 		goto unlock_and_exit;
22895b482a8SLen Brown 	}
22995b482a8SLen Brown 
23095b482a8SLen Brown 	if ((gpe_event_info->flags & ACPI_GPE_TYPE_MASK) == type) {
23195b482a8SLen Brown 		return_ACPI_STATUS(AE_OK);
23295b482a8SLen Brown 	}
23395b482a8SLen Brown 
23495b482a8SLen Brown 	/* Set the new type (will disable GPE if currently enabled) */
23595b482a8SLen Brown 
23695b482a8SLen Brown 	status = acpi_ev_set_gpe_type(gpe_event_info, type);
23795b482a8SLen Brown 
23895b482a8SLen Brown       unlock_and_exit:
23995b482a8SLen Brown 	return_ACPI_STATUS(status);
24095b482a8SLen Brown }
24195b482a8SLen Brown 
24295b482a8SLen Brown ACPI_EXPORT_SYMBOL(acpi_set_gpe_type)
24395b482a8SLen Brown 
24495b482a8SLen Brown /*******************************************************************************
24595b482a8SLen Brown  *
24695b482a8SLen Brown  * FUNCTION:    acpi_enable_gpe
24795b482a8SLen Brown  *
24895b482a8SLen Brown  * PARAMETERS:  gpe_device      - Parent GPE Device
24995b482a8SLen Brown  *              gpe_number      - GPE level within the GPE block
25095b482a8SLen Brown  *              Flags           - Just enable, or also wake enable?
25195b482a8SLen Brown  *                                Called from ISR or not
25295b482a8SLen Brown  *
25395b482a8SLen Brown  * RETURN:      Status
25495b482a8SLen Brown  *
25595b482a8SLen Brown  * DESCRIPTION: Enable an ACPI event (general purpose)
25695b482a8SLen Brown  *
25795b482a8SLen Brown  ******************************************************************************/
25895b482a8SLen Brown acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number)
25995b482a8SLen Brown {
26095b482a8SLen Brown 	acpi_status status = AE_OK;
26195b482a8SLen Brown 	acpi_cpu_flags flags;
26295b482a8SLen Brown 	struct acpi_gpe_event_info *gpe_event_info;
26395b482a8SLen Brown 
26495b482a8SLen Brown 	ACPI_FUNCTION_TRACE(acpi_enable_gpe);
26595b482a8SLen Brown 
26695b482a8SLen Brown 	flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
26795b482a8SLen Brown 
26895b482a8SLen Brown 	/* Ensure that we have a valid GPE number */
26995b482a8SLen Brown 
27095b482a8SLen Brown 	gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
27195b482a8SLen Brown 	if (!gpe_event_info) {
27295b482a8SLen Brown 		status = AE_BAD_PARAMETER;
27395b482a8SLen Brown 		goto unlock_and_exit;
27495b482a8SLen Brown 	}
27595b482a8SLen Brown 
27695b482a8SLen Brown 	/* Perform the enable */
27795b482a8SLen Brown 
27895b482a8SLen Brown 	status = acpi_ev_enable_gpe(gpe_event_info, TRUE);
27995b482a8SLen Brown 
28095b482a8SLen Brown       unlock_and_exit:
28195b482a8SLen Brown 	acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
28295b482a8SLen Brown 	return_ACPI_STATUS(status);
28395b482a8SLen Brown }
28495b482a8SLen Brown 
28595b482a8SLen Brown ACPI_EXPORT_SYMBOL(acpi_enable_gpe)
28695b482a8SLen Brown 
28795b482a8SLen Brown /*******************************************************************************
28895b482a8SLen Brown  *
28995b482a8SLen Brown  * FUNCTION:    acpi_disable_gpe
29095b482a8SLen Brown  *
29195b482a8SLen Brown  * PARAMETERS:  gpe_device      - Parent GPE Device
29295b482a8SLen Brown  *              gpe_number      - GPE level within the GPE block
29395b482a8SLen Brown  *              Flags           - Just disable, or also wake disable?
29495b482a8SLen Brown  *                                Called from ISR or not
29595b482a8SLen Brown  *
29695b482a8SLen Brown  * RETURN:      Status
29795b482a8SLen Brown  *
29895b482a8SLen Brown  * DESCRIPTION: Disable an ACPI event (general purpose)
29995b482a8SLen Brown  *
30095b482a8SLen Brown  ******************************************************************************/
30195b482a8SLen Brown acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number)
30295b482a8SLen Brown {
30395b482a8SLen Brown 	acpi_status status = AE_OK;
30495b482a8SLen Brown 	acpi_cpu_flags flags;
30595b482a8SLen Brown 	struct acpi_gpe_event_info *gpe_event_info;
30695b482a8SLen Brown 
30795b482a8SLen Brown 	ACPI_FUNCTION_TRACE(acpi_disable_gpe);
30895b482a8SLen Brown 
30995b482a8SLen Brown 	flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
31095b482a8SLen Brown 	/* Ensure that we have a valid GPE number */
31195b482a8SLen Brown 
31295b482a8SLen Brown 	gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
31395b482a8SLen Brown 	if (!gpe_event_info) {
31495b482a8SLen Brown 		status = AE_BAD_PARAMETER;
31595b482a8SLen Brown 		goto unlock_and_exit;
31695b482a8SLen Brown 	}
31795b482a8SLen Brown 
31895b482a8SLen Brown 	status = acpi_ev_disable_gpe(gpe_event_info);
31995b482a8SLen Brown 
32095b482a8SLen Brown unlock_and_exit:
32195b482a8SLen Brown 	acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
32295b482a8SLen Brown 	return_ACPI_STATUS(status);
32395b482a8SLen Brown }
32495b482a8SLen Brown 
32595b482a8SLen Brown ACPI_EXPORT_SYMBOL(acpi_disable_gpe)
32695b482a8SLen Brown 
32795b482a8SLen Brown /*******************************************************************************
32895b482a8SLen Brown  *
32995b482a8SLen Brown  * FUNCTION:    acpi_disable_event
33095b482a8SLen Brown  *
33195b482a8SLen Brown  * PARAMETERS:  Event           - The fixed eventto be enabled
33295b482a8SLen Brown  *              Flags           - Reserved
33395b482a8SLen Brown  *
33495b482a8SLen Brown  * RETURN:      Status
33595b482a8SLen Brown  *
33695b482a8SLen Brown  * DESCRIPTION: Disable an ACPI event (fixed)
33795b482a8SLen Brown  *
33895b482a8SLen Brown  ******************************************************************************/
33995b482a8SLen Brown acpi_status acpi_disable_event(u32 event, u32 flags)
34095b482a8SLen Brown {
34195b482a8SLen Brown 	acpi_status status = AE_OK;
34295b482a8SLen Brown 	u32 value;
34395b482a8SLen Brown 
34495b482a8SLen Brown 	ACPI_FUNCTION_TRACE(acpi_disable_event);
34595b482a8SLen Brown 
34695b482a8SLen Brown 	/* Decode the Fixed Event */
34795b482a8SLen Brown 
34895b482a8SLen Brown 	if (event > ACPI_EVENT_MAX) {
34995b482a8SLen Brown 		return_ACPI_STATUS(AE_BAD_PARAMETER);
35095b482a8SLen Brown 	}
35195b482a8SLen Brown 
35295b482a8SLen Brown 	/*
35395b482a8SLen Brown 	 * Disable the requested fixed event (by writing a zero to the enable
35495b482a8SLen Brown 	 * register bit)
35595b482a8SLen Brown 	 */
35695b482a8SLen Brown 	status =
35750ffba1bSBob Moore 	    acpi_write_bit_register(acpi_gbl_fixed_event_info[event].
35895b482a8SLen Brown 				    enable_register_id, 0);
35995b482a8SLen Brown 	if (ACPI_FAILURE(status)) {
36095b482a8SLen Brown 		return_ACPI_STATUS(status);
36195b482a8SLen Brown 	}
36295b482a8SLen Brown 
36395b482a8SLen Brown 	status =
36450ffba1bSBob Moore 	    acpi_read_bit_register(acpi_gbl_fixed_event_info[event].
36595b482a8SLen Brown 				   enable_register_id, &value);
36695b482a8SLen Brown 	if (ACPI_FAILURE(status)) {
36795b482a8SLen Brown 		return_ACPI_STATUS(status);
36895b482a8SLen Brown 	}
36995b482a8SLen Brown 
37095b482a8SLen Brown 	if (value != 0) {
37195b482a8SLen Brown 		ACPI_ERROR((AE_INFO,
37295b482a8SLen Brown 			    "Could not disable %s events",
37395b482a8SLen Brown 			    acpi_ut_get_event_name(event)));
37495b482a8SLen Brown 		return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE);
37595b482a8SLen Brown 	}
37695b482a8SLen Brown 
37795b482a8SLen Brown 	return_ACPI_STATUS(status);
37895b482a8SLen Brown }
37995b482a8SLen Brown 
38095b482a8SLen Brown ACPI_EXPORT_SYMBOL(acpi_disable_event)
38195b482a8SLen Brown 
38295b482a8SLen Brown /*******************************************************************************
38395b482a8SLen Brown  *
38495b482a8SLen Brown  * FUNCTION:    acpi_clear_event
38595b482a8SLen Brown  *
38695b482a8SLen Brown  * PARAMETERS:  Event           - The fixed event to be cleared
38795b482a8SLen Brown  *
38895b482a8SLen Brown  * RETURN:      Status
38995b482a8SLen Brown  *
39095b482a8SLen Brown  * DESCRIPTION: Clear an ACPI event (fixed)
39195b482a8SLen Brown  *
39295b482a8SLen Brown  ******************************************************************************/
39395b482a8SLen Brown acpi_status acpi_clear_event(u32 event)
39495b482a8SLen Brown {
39595b482a8SLen Brown 	acpi_status status = AE_OK;
39695b482a8SLen Brown 
39795b482a8SLen Brown 	ACPI_FUNCTION_TRACE(acpi_clear_event);
39895b482a8SLen Brown 
39995b482a8SLen Brown 	/* Decode the Fixed Event */
40095b482a8SLen Brown 
40195b482a8SLen Brown 	if (event > ACPI_EVENT_MAX) {
40295b482a8SLen Brown 		return_ACPI_STATUS(AE_BAD_PARAMETER);
40395b482a8SLen Brown 	}
40495b482a8SLen Brown 
40595b482a8SLen Brown 	/*
40695b482a8SLen Brown 	 * Clear the requested fixed event (By writing a one to the status
40795b482a8SLen Brown 	 * register bit)
40895b482a8SLen Brown 	 */
40995b482a8SLen Brown 	status =
41050ffba1bSBob Moore 	    acpi_write_bit_register(acpi_gbl_fixed_event_info[event].
41195b482a8SLen Brown 				    status_register_id, 1);
41295b482a8SLen Brown 
41395b482a8SLen Brown 	return_ACPI_STATUS(status);
41495b482a8SLen Brown }
41595b482a8SLen Brown 
41695b482a8SLen Brown ACPI_EXPORT_SYMBOL(acpi_clear_event)
41795b482a8SLen Brown 
41895b482a8SLen Brown /*******************************************************************************
41995b482a8SLen Brown  *
42095b482a8SLen Brown  * FUNCTION:    acpi_clear_gpe
42195b482a8SLen Brown  *
42295b482a8SLen Brown  * PARAMETERS:  gpe_device      - Parent GPE Device
42395b482a8SLen Brown  *              gpe_number      - GPE level within the GPE block
42495b482a8SLen Brown  *              Flags           - Called from an ISR or not
42595b482a8SLen Brown  *
42695b482a8SLen Brown  * RETURN:      Status
42795b482a8SLen Brown  *
42895b482a8SLen Brown  * DESCRIPTION: Clear an ACPI event (general purpose)
42995b482a8SLen Brown  *
43095b482a8SLen Brown  ******************************************************************************/
43195b482a8SLen Brown acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags)
43295b482a8SLen Brown {
43395b482a8SLen Brown 	acpi_status status = AE_OK;
43495b482a8SLen Brown 	struct acpi_gpe_event_info *gpe_event_info;
43595b482a8SLen Brown 
43695b482a8SLen Brown 	ACPI_FUNCTION_TRACE(acpi_clear_gpe);
43795b482a8SLen Brown 
43895b482a8SLen Brown 	/* Use semaphore lock if not executing at interrupt level */
43995b482a8SLen Brown 
44095b482a8SLen Brown 	if (flags & ACPI_NOT_ISR) {
44195b482a8SLen Brown 		status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
44295b482a8SLen Brown 		if (ACPI_FAILURE(status)) {
44395b482a8SLen Brown 			return_ACPI_STATUS(status);
44495b482a8SLen Brown 		}
44595b482a8SLen Brown 	}
44695b482a8SLen Brown 
44795b482a8SLen Brown 	/* Ensure that we have a valid GPE number */
44895b482a8SLen Brown 
44995b482a8SLen Brown 	gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
45095b482a8SLen Brown 	if (!gpe_event_info) {
45195b482a8SLen Brown 		status = AE_BAD_PARAMETER;
45295b482a8SLen Brown 		goto unlock_and_exit;
45395b482a8SLen Brown 	}
45495b482a8SLen Brown 
45595b482a8SLen Brown 	status = acpi_hw_clear_gpe(gpe_event_info);
45695b482a8SLen Brown 
45795b482a8SLen Brown       unlock_and_exit:
45895b482a8SLen Brown 	if (flags & ACPI_NOT_ISR) {
45995b482a8SLen Brown 		(void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
46095b482a8SLen Brown 	}
46195b482a8SLen Brown 	return_ACPI_STATUS(status);
46295b482a8SLen Brown }
46395b482a8SLen Brown 
46495b482a8SLen Brown ACPI_EXPORT_SYMBOL(acpi_clear_gpe)
46595b482a8SLen Brown /*******************************************************************************
46695b482a8SLen Brown  *
46795b482a8SLen Brown  * FUNCTION:    acpi_get_event_status
46895b482a8SLen Brown  *
46995b482a8SLen Brown  * PARAMETERS:  Event           - The fixed event
47095b482a8SLen Brown  *              event_status    - Where the current status of the event will
47195b482a8SLen Brown  *                                be returned
47295b482a8SLen Brown  *
47395b482a8SLen Brown  * RETURN:      Status
47495b482a8SLen Brown  *
47595b482a8SLen Brown  * DESCRIPTION: Obtains and returns the current status of the event
47695b482a8SLen Brown  *
47795b482a8SLen Brown  ******************************************************************************/
47895b482a8SLen Brown acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status)
47995b482a8SLen Brown {
48095b482a8SLen Brown 	acpi_status status = AE_OK;
48195b482a8SLen Brown 	u32 value;
48295b482a8SLen Brown 
48395b482a8SLen Brown 	ACPI_FUNCTION_TRACE(acpi_get_event_status);
48495b482a8SLen Brown 
48595b482a8SLen Brown 	if (!event_status) {
48695b482a8SLen Brown 		return_ACPI_STATUS(AE_BAD_PARAMETER);
48795b482a8SLen Brown 	}
48895b482a8SLen Brown 
48995b482a8SLen Brown 	/* Decode the Fixed Event */
49095b482a8SLen Brown 
49195b482a8SLen Brown 	if (event > ACPI_EVENT_MAX) {
49295b482a8SLen Brown 		return_ACPI_STATUS(AE_BAD_PARAMETER);
49395b482a8SLen Brown 	}
49495b482a8SLen Brown 
49595b482a8SLen Brown 	/* Get the status of the requested fixed event */
49695b482a8SLen Brown 
49795b482a8SLen Brown 	status =
49850ffba1bSBob Moore 	    acpi_read_bit_register(acpi_gbl_fixed_event_info[event].
49995b482a8SLen Brown 			      enable_register_id, &value);
50095b482a8SLen Brown 	if (ACPI_FAILURE(status))
50195b482a8SLen Brown 		return_ACPI_STATUS(status);
50295b482a8SLen Brown 
50395b482a8SLen Brown 	*event_status = value;
50495b482a8SLen Brown 
50595b482a8SLen Brown 	status =
50650ffba1bSBob Moore 	    acpi_read_bit_register(acpi_gbl_fixed_event_info[event].
50795b482a8SLen Brown 			      status_register_id, &value);
50895b482a8SLen Brown 	if (ACPI_FAILURE(status))
50995b482a8SLen Brown 		return_ACPI_STATUS(status);
51095b482a8SLen Brown 
51195b482a8SLen Brown 	if (value)
51295b482a8SLen Brown 		*event_status |= ACPI_EVENT_FLAG_SET;
51395b482a8SLen Brown 
51495b482a8SLen Brown 	if (acpi_gbl_fixed_event_handlers[event].handler)
51595b482a8SLen Brown 		*event_status |= ACPI_EVENT_FLAG_HANDLE;
51695b482a8SLen Brown 
51795b482a8SLen Brown 	return_ACPI_STATUS(status);
51895b482a8SLen Brown }
51995b482a8SLen Brown 
52095b482a8SLen Brown ACPI_EXPORT_SYMBOL(acpi_get_event_status)
52195b482a8SLen Brown 
52295b482a8SLen Brown /*******************************************************************************
52395b482a8SLen Brown  *
52495b482a8SLen Brown  * FUNCTION:    acpi_get_gpe_status
52595b482a8SLen Brown  *
52695b482a8SLen Brown  * PARAMETERS:  gpe_device      - Parent GPE Device
52795b482a8SLen Brown  *              gpe_number      - GPE level within the GPE block
52895b482a8SLen Brown  *              Flags           - Called from an ISR or not
52995b482a8SLen Brown  *              event_status    - Where the current status of the event will
53095b482a8SLen Brown  *                                be returned
53195b482a8SLen Brown  *
53295b482a8SLen Brown  * RETURN:      Status
53395b482a8SLen Brown  *
53495b482a8SLen Brown  * DESCRIPTION: Get status of an event (general purpose)
53595b482a8SLen Brown  *
53695b482a8SLen Brown  ******************************************************************************/
53795b482a8SLen Brown acpi_status
53895b482a8SLen Brown acpi_get_gpe_status(acpi_handle gpe_device,
53995b482a8SLen Brown 		    u32 gpe_number, u32 flags, acpi_event_status * event_status)
54095b482a8SLen Brown {
54195b482a8SLen Brown 	acpi_status status = AE_OK;
54295b482a8SLen Brown 	struct acpi_gpe_event_info *gpe_event_info;
54395b482a8SLen Brown 
54495b482a8SLen Brown 	ACPI_FUNCTION_TRACE(acpi_get_gpe_status);
54595b482a8SLen Brown 
54695b482a8SLen Brown 	/* Use semaphore lock if not executing at interrupt level */
54795b482a8SLen Brown 
54895b482a8SLen Brown 	if (flags & ACPI_NOT_ISR) {
54995b482a8SLen Brown 		status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
55095b482a8SLen Brown 		if (ACPI_FAILURE(status)) {
55195b482a8SLen Brown 			return_ACPI_STATUS(status);
55295b482a8SLen Brown 		}
55395b482a8SLen Brown 	}
55495b482a8SLen Brown 
55595b482a8SLen Brown 	/* Ensure that we have a valid GPE number */
55695b482a8SLen Brown 
55795b482a8SLen Brown 	gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
55895b482a8SLen Brown 	if (!gpe_event_info) {
55995b482a8SLen Brown 		status = AE_BAD_PARAMETER;
56095b482a8SLen Brown 		goto unlock_and_exit;
56195b482a8SLen Brown 	}
56295b482a8SLen Brown 
56395b482a8SLen Brown 	/* Obtain status on the requested GPE number */
56495b482a8SLen Brown 
56595b482a8SLen Brown 	status = acpi_hw_get_gpe_status(gpe_event_info, event_status);
56695b482a8SLen Brown 
56795b482a8SLen Brown 	if (gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK)
56895b482a8SLen Brown 		*event_status |= ACPI_EVENT_FLAG_HANDLE;
56995b482a8SLen Brown 
57095b482a8SLen Brown       unlock_and_exit:
57195b482a8SLen Brown 	if (flags & ACPI_NOT_ISR) {
57295b482a8SLen Brown 		(void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
57395b482a8SLen Brown 	}
57495b482a8SLen Brown 	return_ACPI_STATUS(status);
57595b482a8SLen Brown }
57695b482a8SLen Brown 
57795b482a8SLen Brown ACPI_EXPORT_SYMBOL(acpi_get_gpe_status)
57895b482a8SLen Brown /*******************************************************************************
57995b482a8SLen Brown  *
58095b482a8SLen Brown  * FUNCTION:    acpi_install_gpe_block
58195b482a8SLen Brown  *
58295b482a8SLen Brown  * PARAMETERS:  gpe_device          - Handle to the parent GPE Block Device
58395b482a8SLen Brown  *              gpe_block_address   - Address and space_iD
58495b482a8SLen Brown  *              register_count      - Number of GPE register pairs in the block
58595b482a8SLen Brown  *              interrupt_number    - H/W interrupt for the block
58695b482a8SLen Brown  *
58795b482a8SLen Brown  * RETURN:      Status
58895b482a8SLen Brown  *
58995b482a8SLen Brown  * DESCRIPTION: Create and Install a block of GPE registers
59095b482a8SLen Brown  *
59195b482a8SLen Brown  ******************************************************************************/
59295b482a8SLen Brown acpi_status
59395b482a8SLen Brown acpi_install_gpe_block(acpi_handle gpe_device,
59495b482a8SLen Brown 		       struct acpi_generic_address *gpe_block_address,
59595b482a8SLen Brown 		       u32 register_count, u32 interrupt_number)
59695b482a8SLen Brown {
59795b482a8SLen Brown 	acpi_status status;
59895b482a8SLen Brown 	union acpi_operand_object *obj_desc;
59995b482a8SLen Brown 	struct acpi_namespace_node *node;
60095b482a8SLen Brown 	struct acpi_gpe_block_info *gpe_block;
60195b482a8SLen Brown 
60295b482a8SLen Brown 	ACPI_FUNCTION_TRACE(acpi_install_gpe_block);
60395b482a8SLen Brown 
60495b482a8SLen Brown 	if ((!gpe_device) || (!gpe_block_address) || (!register_count)) {
60595b482a8SLen Brown 		return_ACPI_STATUS(AE_BAD_PARAMETER);
60695b482a8SLen Brown 	}
60795b482a8SLen Brown 
60895b482a8SLen Brown 	status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
60995b482a8SLen Brown 	if (ACPI_FAILURE(status)) {
61095b482a8SLen Brown 		return (status);
61195b482a8SLen Brown 	}
61295b482a8SLen Brown 
61395b482a8SLen Brown 	node = acpi_ns_map_handle_to_node(gpe_device);
61495b482a8SLen Brown 	if (!node) {
61595b482a8SLen Brown 		status = AE_BAD_PARAMETER;
61695b482a8SLen Brown 		goto unlock_and_exit;
61795b482a8SLen Brown 	}
61895b482a8SLen Brown 
61995b482a8SLen Brown 	/*
62095b482a8SLen Brown 	 * For user-installed GPE Block Devices, the gpe_block_base_number
62195b482a8SLen Brown 	 * is always zero
62295b482a8SLen Brown 	 */
62395b482a8SLen Brown 	status =
62495b482a8SLen Brown 	    acpi_ev_create_gpe_block(node, gpe_block_address, register_count, 0,
62595b482a8SLen Brown 				     interrupt_number, &gpe_block);
62695b482a8SLen Brown 	if (ACPI_FAILURE(status)) {
62795b482a8SLen Brown 		goto unlock_and_exit;
62895b482a8SLen Brown 	}
62995b482a8SLen Brown 
63095b482a8SLen Brown 	/* Run the _PRW methods and enable the GPEs */
63195b482a8SLen Brown 
63295b482a8SLen Brown 	status = acpi_ev_initialize_gpe_block(node, gpe_block);
63395b482a8SLen Brown 	if (ACPI_FAILURE(status)) {
63495b482a8SLen Brown 		goto unlock_and_exit;
63595b482a8SLen Brown 	}
63695b482a8SLen Brown 
63795b482a8SLen Brown 	/* Get the device_object attached to the node */
63895b482a8SLen Brown 
63995b482a8SLen Brown 	obj_desc = acpi_ns_get_attached_object(node);
64095b482a8SLen Brown 	if (!obj_desc) {
64195b482a8SLen Brown 
64295b482a8SLen Brown 		/* No object, create a new one */
64395b482a8SLen Brown 
64495b482a8SLen Brown 		obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_DEVICE);
64595b482a8SLen Brown 		if (!obj_desc) {
64695b482a8SLen Brown 			status = AE_NO_MEMORY;
64795b482a8SLen Brown 			goto unlock_and_exit;
64895b482a8SLen Brown 		}
64995b482a8SLen Brown 
65095b482a8SLen Brown 		status =
65195b482a8SLen Brown 		    acpi_ns_attach_object(node, obj_desc, ACPI_TYPE_DEVICE);
65295b482a8SLen Brown 
65395b482a8SLen Brown 		/* Remove local reference to the object */
65495b482a8SLen Brown 
65595b482a8SLen Brown 		acpi_ut_remove_reference(obj_desc);
65695b482a8SLen Brown 
65795b482a8SLen Brown 		if (ACPI_FAILURE(status)) {
65895b482a8SLen Brown 			goto unlock_and_exit;
65995b482a8SLen Brown 		}
66095b482a8SLen Brown 	}
66195b482a8SLen Brown 
66295b482a8SLen Brown 	/* Install the GPE block in the device_object */
66395b482a8SLen Brown 
66495b482a8SLen Brown 	obj_desc->device.gpe_block = gpe_block;
66595b482a8SLen Brown 
66695b482a8SLen Brown       unlock_and_exit:
66795b482a8SLen Brown 	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
66895b482a8SLen Brown 	return_ACPI_STATUS(status);
66995b482a8SLen Brown }
67095b482a8SLen Brown 
67195b482a8SLen Brown ACPI_EXPORT_SYMBOL(acpi_install_gpe_block)
67295b482a8SLen Brown 
67395b482a8SLen Brown /*******************************************************************************
67495b482a8SLen Brown  *
67595b482a8SLen Brown  * FUNCTION:    acpi_remove_gpe_block
67695b482a8SLen Brown  *
67795b482a8SLen Brown  * PARAMETERS:  gpe_device          - Handle to the parent GPE Block Device
67895b482a8SLen Brown  *
67995b482a8SLen Brown  * RETURN:      Status
68095b482a8SLen Brown  *
68195b482a8SLen Brown  * DESCRIPTION: Remove a previously installed block of GPE registers
68295b482a8SLen Brown  *
68395b482a8SLen Brown  ******************************************************************************/
68495b482a8SLen Brown acpi_status acpi_remove_gpe_block(acpi_handle gpe_device)
68595b482a8SLen Brown {
68695b482a8SLen Brown 	union acpi_operand_object *obj_desc;
68795b482a8SLen Brown 	acpi_status status;
68895b482a8SLen Brown 	struct acpi_namespace_node *node;
68995b482a8SLen Brown 
69095b482a8SLen Brown 	ACPI_FUNCTION_TRACE(acpi_remove_gpe_block);
69195b482a8SLen Brown 
69295b482a8SLen Brown 	if (!gpe_device) {
69395b482a8SLen Brown 		return_ACPI_STATUS(AE_BAD_PARAMETER);
69495b482a8SLen Brown 	}
69595b482a8SLen Brown 
69695b482a8SLen Brown 	status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
69795b482a8SLen Brown 	if (ACPI_FAILURE(status)) {
69895b482a8SLen Brown 		return (status);
69995b482a8SLen Brown 	}
70095b482a8SLen Brown 
70195b482a8SLen Brown 	node = acpi_ns_map_handle_to_node(gpe_device);
70295b482a8SLen Brown 	if (!node) {
70395b482a8SLen Brown 		status = AE_BAD_PARAMETER;
70495b482a8SLen Brown 		goto unlock_and_exit;
70595b482a8SLen Brown 	}
70695b482a8SLen Brown 
70795b482a8SLen Brown 	/* Get the device_object attached to the node */
70895b482a8SLen Brown 
70995b482a8SLen Brown 	obj_desc = acpi_ns_get_attached_object(node);
71095b482a8SLen Brown 	if (!obj_desc || !obj_desc->device.gpe_block) {
71195b482a8SLen Brown 		return_ACPI_STATUS(AE_NULL_OBJECT);
71295b482a8SLen Brown 	}
71395b482a8SLen Brown 
71495b482a8SLen Brown 	/* Delete the GPE block (but not the device_object) */
71595b482a8SLen Brown 
71695b482a8SLen Brown 	status = acpi_ev_delete_gpe_block(obj_desc->device.gpe_block);
71795b482a8SLen Brown 	if (ACPI_SUCCESS(status)) {
71895b482a8SLen Brown 		obj_desc->device.gpe_block = NULL;
71995b482a8SLen Brown 	}
72095b482a8SLen Brown 
72195b482a8SLen Brown       unlock_and_exit:
72295b482a8SLen Brown 	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
72395b482a8SLen Brown 	return_ACPI_STATUS(status);
72495b482a8SLen Brown }
72595b482a8SLen Brown 
72695b482a8SLen Brown ACPI_EXPORT_SYMBOL(acpi_remove_gpe_block)
72795b482a8SLen Brown 
72895b482a8SLen Brown /*******************************************************************************
72995b482a8SLen Brown  *
73095b482a8SLen Brown  * FUNCTION:    acpi_get_gpe_device
73195b482a8SLen Brown  *
73295b482a8SLen Brown  * PARAMETERS:  Index               - System GPE index (0-current_gpe_count)
73395b482a8SLen Brown  *              gpe_device          - Where the parent GPE Device is returned
73495b482a8SLen Brown  *
73595b482a8SLen Brown  * RETURN:      Status
73695b482a8SLen Brown  *
73795b482a8SLen Brown  * DESCRIPTION: Obtain the GPE device associated with the input index. A NULL
73895b482a8SLen Brown  *              gpe device indicates that the gpe number is contained in one of
73995b482a8SLen Brown  *              the FADT-defined gpe blocks. Otherwise, the GPE block device.
74095b482a8SLen Brown  *
74195b482a8SLen Brown  ******************************************************************************/
74295b482a8SLen Brown acpi_status
74395b482a8SLen Brown acpi_get_gpe_device(u32 index, acpi_handle *gpe_device)
74495b482a8SLen Brown {
74595b482a8SLen Brown 	struct acpi_gpe_device_info info;
74695b482a8SLen Brown 	acpi_status status;
74795b482a8SLen Brown 
74895b482a8SLen Brown 	ACPI_FUNCTION_TRACE(acpi_get_gpe_device);
74995b482a8SLen Brown 
75095b482a8SLen Brown 	if (!gpe_device) {
75195b482a8SLen Brown 		return_ACPI_STATUS(AE_BAD_PARAMETER);
75295b482a8SLen Brown 	}
75395b482a8SLen Brown 
75495b482a8SLen Brown 	if (index >= acpi_current_gpe_count) {
75595b482a8SLen Brown 		return_ACPI_STATUS(AE_NOT_EXIST);
75695b482a8SLen Brown 	}
75795b482a8SLen Brown 
75895b482a8SLen Brown 	/* Setup and walk the GPE list */
75995b482a8SLen Brown 
76095b482a8SLen Brown 	info.index = index;
76195b482a8SLen Brown 	info.status = AE_NOT_EXIST;
76295b482a8SLen Brown 	info.gpe_device = NULL;
76395b482a8SLen Brown 	info.next_block_base_index = 0;
76495b482a8SLen Brown 
76595b482a8SLen Brown 	status = acpi_ev_walk_gpe_list(acpi_ev_get_gpe_device, &info);
76695b482a8SLen Brown 	if (ACPI_FAILURE(status)) {
76795b482a8SLen Brown 		return_ACPI_STATUS(status);
76895b482a8SLen Brown 	}
76995b482a8SLen Brown 
77095b482a8SLen Brown 	*gpe_device = info.gpe_device;
77195b482a8SLen Brown 	return_ACPI_STATUS(info.status);
77295b482a8SLen Brown }
77395b482a8SLen Brown 
77495b482a8SLen Brown ACPI_EXPORT_SYMBOL(acpi_get_gpe_device)
77595b482a8SLen Brown 
77695b482a8SLen Brown /*******************************************************************************
77795b482a8SLen Brown  *
77895b482a8SLen Brown  * FUNCTION:    acpi_ev_get_gpe_device
77995b482a8SLen Brown  *
78095b482a8SLen Brown  * PARAMETERS:  GPE_WALK_CALLBACK
78195b482a8SLen Brown  *
78295b482a8SLen Brown  * RETURN:      Status
78395b482a8SLen Brown  *
78495b482a8SLen Brown  * DESCRIPTION: Matches the input GPE index (0-current_gpe_count) with a GPE
78595b482a8SLen Brown  *              block device. NULL if the GPE is one of the FADT-defined GPEs.
78695b482a8SLen Brown  *
78795b482a8SLen Brown  ******************************************************************************/
78895b482a8SLen Brown acpi_status
78995b482a8SLen Brown acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
79095b482a8SLen Brown 		       struct acpi_gpe_block_info *gpe_block, void *context)
79195b482a8SLen Brown {
79295b482a8SLen Brown 	struct acpi_gpe_device_info *info = context;
79395b482a8SLen Brown 
79495b482a8SLen Brown 	/* Increment Index by the number of GPEs in this block */
79595b482a8SLen Brown 
79695b482a8SLen Brown 	info->next_block_base_index +=
79795b482a8SLen Brown 	    (gpe_block->register_count * ACPI_GPE_REGISTER_WIDTH);
79895b482a8SLen Brown 
79995b482a8SLen Brown 	if (info->index < info->next_block_base_index) {
80095b482a8SLen Brown 		/*
80195b482a8SLen Brown 		 * The GPE index is within this block, get the node. Leave the node
80295b482a8SLen Brown 		 * NULL for the FADT-defined GPEs
80395b482a8SLen Brown 		 */
80495b482a8SLen Brown 		if ((gpe_block->node)->type == ACPI_TYPE_DEVICE) {
80595b482a8SLen Brown 			info->gpe_device = gpe_block->node;
80695b482a8SLen Brown 		}
80795b482a8SLen Brown 
80895b482a8SLen Brown 		info->status = AE_OK;
80995b482a8SLen Brown 		return (AE_CTRL_END);
81095b482a8SLen Brown 	}
81195b482a8SLen Brown 
81295b482a8SLen Brown 	return (AE_OK);
81395b482a8SLen Brown }
81495b482a8SLen Brown 
81595b482a8SLen Brown /******************************************************************************
81695b482a8SLen Brown  *
81795b482a8SLen Brown  * FUNCTION:    acpi_disable_all_gpes
81895b482a8SLen Brown  *
81995b482a8SLen Brown  * PARAMETERS:  None
82095b482a8SLen Brown  *
82195b482a8SLen Brown  * RETURN:      Status
82295b482a8SLen Brown  *
82395b482a8SLen Brown  * DESCRIPTION: Disable and clear all GPEs in all GPE blocks
82495b482a8SLen Brown  *
82595b482a8SLen Brown  ******************************************************************************/
82695b482a8SLen Brown 
82795b482a8SLen Brown acpi_status acpi_disable_all_gpes(void)
82895b482a8SLen Brown {
82995b482a8SLen Brown 	acpi_status status;
83095b482a8SLen Brown 
83195b482a8SLen Brown 	ACPI_FUNCTION_TRACE(acpi_disable_all_gpes);
83295b482a8SLen Brown 
83395b482a8SLen Brown 	status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
83495b482a8SLen Brown 	if (ACPI_FAILURE(status)) {
83595b482a8SLen Brown 		return_ACPI_STATUS(status);
83695b482a8SLen Brown 	}
83795b482a8SLen Brown 
83895b482a8SLen Brown 	status = acpi_hw_disable_all_gpes();
83995b482a8SLen Brown 	(void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
84095b482a8SLen Brown 
84195b482a8SLen Brown 	return_ACPI_STATUS(status);
84295b482a8SLen Brown }
84395b482a8SLen Brown 
84495b482a8SLen Brown /******************************************************************************
84595b482a8SLen Brown  *
84695b482a8SLen Brown  * FUNCTION:    acpi_enable_all_runtime_gpes
84795b482a8SLen Brown  *
84895b482a8SLen Brown  * PARAMETERS:  None
84995b482a8SLen Brown  *
85095b482a8SLen Brown  * RETURN:      Status
85195b482a8SLen Brown  *
85295b482a8SLen Brown  * DESCRIPTION: Enable all "runtime" GPEs, in all GPE blocks
85395b482a8SLen Brown  *
85495b482a8SLen Brown  ******************************************************************************/
85595b482a8SLen Brown 
85695b482a8SLen Brown acpi_status acpi_enable_all_runtime_gpes(void)
85795b482a8SLen Brown {
85895b482a8SLen Brown 	acpi_status status;
85995b482a8SLen Brown 
86095b482a8SLen Brown 	ACPI_FUNCTION_TRACE(acpi_enable_all_runtime_gpes);
86195b482a8SLen Brown 
86295b482a8SLen Brown 	status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
86395b482a8SLen Brown 	if (ACPI_FAILURE(status)) {
86495b482a8SLen Brown 		return_ACPI_STATUS(status);
86595b482a8SLen Brown 	}
86695b482a8SLen Brown 
86795b482a8SLen Brown 	status = acpi_hw_enable_all_runtime_gpes();
86895b482a8SLen Brown 	(void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
86995b482a8SLen Brown 
87095b482a8SLen Brown 	return_ACPI_STATUS(status);
87195b482a8SLen Brown }
872