xref: /OK3568_Linux_fs/kernel/drivers/acpi/acpica/evxfgpe.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2*4882a593Smuzhiyun /******************************************************************************
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * Module Name: evxfgpe - External Interfaces for General Purpose Events (GPEs)
5*4882a593Smuzhiyun  *
6*4882a593Smuzhiyun  * Copyright (C) 2000 - 2020, Intel Corp.
7*4882a593Smuzhiyun  *
8*4882a593Smuzhiyun  *****************************************************************************/
9*4882a593Smuzhiyun 
10*4882a593Smuzhiyun #define EXPORT_ACPI_INTERFACES
11*4882a593Smuzhiyun 
12*4882a593Smuzhiyun #include <acpi/acpi.h>
13*4882a593Smuzhiyun #include "accommon.h"
14*4882a593Smuzhiyun #include "acevents.h"
15*4882a593Smuzhiyun #include "acnamesp.h"
16*4882a593Smuzhiyun 
17*4882a593Smuzhiyun #define _COMPONENT          ACPI_EVENTS
18*4882a593Smuzhiyun ACPI_MODULE_NAME("evxfgpe")
19*4882a593Smuzhiyun 
20*4882a593Smuzhiyun #if (!ACPI_REDUCED_HARDWARE)	/* Entire module */
21*4882a593Smuzhiyun /*******************************************************************************
22*4882a593Smuzhiyun  *
23*4882a593Smuzhiyun  * FUNCTION:    acpi_update_all_gpes
24*4882a593Smuzhiyun  *
25*4882a593Smuzhiyun  * PARAMETERS:  None
26*4882a593Smuzhiyun  *
27*4882a593Smuzhiyun  * RETURN:      Status
28*4882a593Smuzhiyun  *
29*4882a593Smuzhiyun  * DESCRIPTION: Complete GPE initialization and enable all GPEs that have
30*4882a593Smuzhiyun  *              associated _Lxx or _Exx methods and are not pointed to by any
31*4882a593Smuzhiyun  *              device _PRW methods (this indicates that these GPEs are
32*4882a593Smuzhiyun  *              generally intended for system or device wakeup. Such GPEs
33*4882a593Smuzhiyun  *              have to be enabled directly when the devices whose _PRW
34*4882a593Smuzhiyun  *              methods point to them are set up for wakeup signaling.)
35*4882a593Smuzhiyun  *
36*4882a593Smuzhiyun  * NOTE: Should be called after any GPEs are added to the system. Primarily,
37*4882a593Smuzhiyun  * after the system _PRW methods have been run, but also after a GPE Block
38*4882a593Smuzhiyun  * Device has been added or if any new GPE methods have been added via a
39*4882a593Smuzhiyun  * dynamic table load.
40*4882a593Smuzhiyun  *
41*4882a593Smuzhiyun  ******************************************************************************/
42*4882a593Smuzhiyun 
acpi_update_all_gpes(void)43*4882a593Smuzhiyun acpi_status acpi_update_all_gpes(void)
44*4882a593Smuzhiyun {
45*4882a593Smuzhiyun 	acpi_status status;
46*4882a593Smuzhiyun 	u8 is_polling_needed = FALSE;
47*4882a593Smuzhiyun 
48*4882a593Smuzhiyun 	ACPI_FUNCTION_TRACE(acpi_update_all_gpes);
49*4882a593Smuzhiyun 
50*4882a593Smuzhiyun 	status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
51*4882a593Smuzhiyun 	if (ACPI_FAILURE(status)) {
52*4882a593Smuzhiyun 		return_ACPI_STATUS(status);
53*4882a593Smuzhiyun 	}
54*4882a593Smuzhiyun 
55*4882a593Smuzhiyun 	if (acpi_gbl_all_gpes_initialized) {
56*4882a593Smuzhiyun 		goto unlock_and_exit;
57*4882a593Smuzhiyun 	}
58*4882a593Smuzhiyun 
59*4882a593Smuzhiyun 	status = acpi_ev_walk_gpe_list(acpi_ev_initialize_gpe_block,
60*4882a593Smuzhiyun 				       &is_polling_needed);
61*4882a593Smuzhiyun 	if (ACPI_SUCCESS(status)) {
62*4882a593Smuzhiyun 		acpi_gbl_all_gpes_initialized = TRUE;
63*4882a593Smuzhiyun 	}
64*4882a593Smuzhiyun 
65*4882a593Smuzhiyun unlock_and_exit:
66*4882a593Smuzhiyun 	(void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
67*4882a593Smuzhiyun 
68*4882a593Smuzhiyun 	if (is_polling_needed && acpi_gbl_all_gpes_initialized) {
69*4882a593Smuzhiyun 
70*4882a593Smuzhiyun 		/* Poll GPEs to handle already triggered events */
71*4882a593Smuzhiyun 
72*4882a593Smuzhiyun 		acpi_ev_gpe_detect(acpi_gbl_gpe_xrupt_list_head);
73*4882a593Smuzhiyun 	}
74*4882a593Smuzhiyun 	return_ACPI_STATUS(status);
75*4882a593Smuzhiyun }
76*4882a593Smuzhiyun 
ACPI_EXPORT_SYMBOL(acpi_update_all_gpes)77*4882a593Smuzhiyun ACPI_EXPORT_SYMBOL(acpi_update_all_gpes)
78*4882a593Smuzhiyun 
79*4882a593Smuzhiyun /*******************************************************************************
80*4882a593Smuzhiyun  *
81*4882a593Smuzhiyun  * FUNCTION:    acpi_enable_gpe
82*4882a593Smuzhiyun  *
83*4882a593Smuzhiyun  * PARAMETERS:  gpe_device          - Parent GPE Device. NULL for GPE0/GPE1
84*4882a593Smuzhiyun  *              gpe_number          - GPE level within the GPE block
85*4882a593Smuzhiyun  *
86*4882a593Smuzhiyun  * RETURN:      Status
87*4882a593Smuzhiyun  *
88*4882a593Smuzhiyun  * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is
89*4882a593Smuzhiyun  *              hardware-enabled.
90*4882a593Smuzhiyun  *
91*4882a593Smuzhiyun  ******************************************************************************/
92*4882a593Smuzhiyun acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number)
93*4882a593Smuzhiyun {
94*4882a593Smuzhiyun 	acpi_status status = AE_BAD_PARAMETER;
95*4882a593Smuzhiyun 	struct acpi_gpe_event_info *gpe_event_info;
96*4882a593Smuzhiyun 	acpi_cpu_flags flags;
97*4882a593Smuzhiyun 
98*4882a593Smuzhiyun 	ACPI_FUNCTION_TRACE(acpi_enable_gpe);
99*4882a593Smuzhiyun 
100*4882a593Smuzhiyun 	flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
101*4882a593Smuzhiyun 
102*4882a593Smuzhiyun 	/*
103*4882a593Smuzhiyun 	 * Ensure that we have a valid GPE number and that there is some way
104*4882a593Smuzhiyun 	 * of handling the GPE (handler or a GPE method). In other words, we
105*4882a593Smuzhiyun 	 * won't allow a valid GPE to be enabled if there is no way to handle it.
106*4882a593Smuzhiyun 	 */
107*4882a593Smuzhiyun 	gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
108*4882a593Smuzhiyun 	if (gpe_event_info) {
109*4882a593Smuzhiyun 		if (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) !=
110*4882a593Smuzhiyun 		    ACPI_GPE_DISPATCH_NONE) {
111*4882a593Smuzhiyun 			status = acpi_ev_add_gpe_reference(gpe_event_info, TRUE);
112*4882a593Smuzhiyun 			if (ACPI_SUCCESS(status) &&
113*4882a593Smuzhiyun 			    ACPI_GPE_IS_POLLING_NEEDED(gpe_event_info)) {
114*4882a593Smuzhiyun 
115*4882a593Smuzhiyun 				/* Poll edge-triggered GPEs to handle existing events */
116*4882a593Smuzhiyun 
117*4882a593Smuzhiyun 				acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
118*4882a593Smuzhiyun 				(void)acpi_ev_detect_gpe(gpe_device,
119*4882a593Smuzhiyun 							 gpe_event_info,
120*4882a593Smuzhiyun 							 gpe_number);
121*4882a593Smuzhiyun 				flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
122*4882a593Smuzhiyun 			}
123*4882a593Smuzhiyun 		} else {
124*4882a593Smuzhiyun 			status = AE_NO_HANDLER;
125*4882a593Smuzhiyun 		}
126*4882a593Smuzhiyun 	}
127*4882a593Smuzhiyun 
128*4882a593Smuzhiyun 	acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
129*4882a593Smuzhiyun 	return_ACPI_STATUS(status);
130*4882a593Smuzhiyun }
ACPI_EXPORT_SYMBOL(acpi_enable_gpe)131*4882a593Smuzhiyun ACPI_EXPORT_SYMBOL(acpi_enable_gpe)
132*4882a593Smuzhiyun 
133*4882a593Smuzhiyun /*******************************************************************************
134*4882a593Smuzhiyun  *
135*4882a593Smuzhiyun  * FUNCTION:    acpi_disable_gpe
136*4882a593Smuzhiyun  *
137*4882a593Smuzhiyun  * PARAMETERS:  gpe_device      - Parent GPE Device. NULL for GPE0/GPE1
138*4882a593Smuzhiyun  *              gpe_number      - GPE level within the GPE block
139*4882a593Smuzhiyun  *
140*4882a593Smuzhiyun  * RETURN:      Status
141*4882a593Smuzhiyun  *
142*4882a593Smuzhiyun  * DESCRIPTION: Remove a reference to a GPE. When the last reference is
143*4882a593Smuzhiyun  *              removed, only then is the GPE disabled (for runtime GPEs), or
144*4882a593Smuzhiyun  *              the GPE mask bit disabled (for wake GPEs)
145*4882a593Smuzhiyun  *
146*4882a593Smuzhiyun  ******************************************************************************/
147*4882a593Smuzhiyun 
148*4882a593Smuzhiyun acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number)
149*4882a593Smuzhiyun {
150*4882a593Smuzhiyun 	acpi_status status = AE_BAD_PARAMETER;
151*4882a593Smuzhiyun 	struct acpi_gpe_event_info *gpe_event_info;
152*4882a593Smuzhiyun 	acpi_cpu_flags flags;
153*4882a593Smuzhiyun 
154*4882a593Smuzhiyun 	ACPI_FUNCTION_TRACE(acpi_disable_gpe);
155*4882a593Smuzhiyun 
156*4882a593Smuzhiyun 	flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
157*4882a593Smuzhiyun 
158*4882a593Smuzhiyun 	/* Ensure that we have a valid GPE number */
159*4882a593Smuzhiyun 
160*4882a593Smuzhiyun 	gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
161*4882a593Smuzhiyun 	if (gpe_event_info) {
162*4882a593Smuzhiyun 		status = acpi_ev_remove_gpe_reference(gpe_event_info) ;
163*4882a593Smuzhiyun 	}
164*4882a593Smuzhiyun 
165*4882a593Smuzhiyun 	acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
166*4882a593Smuzhiyun 	return_ACPI_STATUS(status);
167*4882a593Smuzhiyun }
168*4882a593Smuzhiyun 
ACPI_EXPORT_SYMBOL(acpi_disable_gpe)169*4882a593Smuzhiyun ACPI_EXPORT_SYMBOL(acpi_disable_gpe)
170*4882a593Smuzhiyun 
171*4882a593Smuzhiyun /*******************************************************************************
172*4882a593Smuzhiyun  *
173*4882a593Smuzhiyun  * FUNCTION:    acpi_set_gpe
174*4882a593Smuzhiyun  *
175*4882a593Smuzhiyun  * PARAMETERS:  gpe_device          - Parent GPE Device. NULL for GPE0/GPE1
176*4882a593Smuzhiyun  *              gpe_number          - GPE level within the GPE block
177*4882a593Smuzhiyun  *              action              - ACPI_GPE_ENABLE or ACPI_GPE_DISABLE
178*4882a593Smuzhiyun  *
179*4882a593Smuzhiyun  * RETURN:      Status
180*4882a593Smuzhiyun  *
181*4882a593Smuzhiyun  * DESCRIPTION: Enable or disable an individual GPE. This function bypasses
182*4882a593Smuzhiyun  *              the reference count mechanism used in the acpi_enable_gpe(),
183*4882a593Smuzhiyun  *              acpi_disable_gpe() interfaces.
184*4882a593Smuzhiyun  *              This API is typically used by the GPE raw handler mode driver
185*4882a593Smuzhiyun  *              to switch between the polling mode and the interrupt mode after
186*4882a593Smuzhiyun  *              the driver has enabled the GPE.
187*4882a593Smuzhiyun  *              The APIs should be invoked in this order:
188*4882a593Smuzhiyun  *               acpi_enable_gpe()            <- Ensure the reference count > 0
189*4882a593Smuzhiyun  *               acpi_set_gpe(ACPI_GPE_DISABLE) <- Enter polling mode
190*4882a593Smuzhiyun  *               acpi_set_gpe(ACPI_GPE_ENABLE) <- Leave polling mode
191*4882a593Smuzhiyun  *               acpi_disable_gpe()           <- Decrease the reference count
192*4882a593Smuzhiyun  *
193*4882a593Smuzhiyun  * Note: If a GPE is shared by 2 silicon components, then both the drivers
194*4882a593Smuzhiyun  *       should support GPE polling mode or disabling the GPE for long period
195*4882a593Smuzhiyun  *       for one driver may break the other. So use it with care since all
196*4882a593Smuzhiyun  *       firmware _Lxx/_Exx handlers currently rely on the GPE interrupt mode.
197*4882a593Smuzhiyun  *
198*4882a593Smuzhiyun  ******************************************************************************/
199*4882a593Smuzhiyun acpi_status acpi_set_gpe(acpi_handle gpe_device, u32 gpe_number, u8 action)
200*4882a593Smuzhiyun {
201*4882a593Smuzhiyun 	struct acpi_gpe_event_info *gpe_event_info;
202*4882a593Smuzhiyun 	acpi_status status;
203*4882a593Smuzhiyun 	acpi_cpu_flags flags;
204*4882a593Smuzhiyun 
205*4882a593Smuzhiyun 	ACPI_FUNCTION_TRACE(acpi_set_gpe);
206*4882a593Smuzhiyun 
207*4882a593Smuzhiyun 	flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
208*4882a593Smuzhiyun 
209*4882a593Smuzhiyun 	/* Ensure that we have a valid GPE number */
210*4882a593Smuzhiyun 
211*4882a593Smuzhiyun 	gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
212*4882a593Smuzhiyun 	if (!gpe_event_info) {
213*4882a593Smuzhiyun 		status = AE_BAD_PARAMETER;
214*4882a593Smuzhiyun 		goto unlock_and_exit;
215*4882a593Smuzhiyun 	}
216*4882a593Smuzhiyun 
217*4882a593Smuzhiyun 	/* Perform the action */
218*4882a593Smuzhiyun 
219*4882a593Smuzhiyun 	switch (action) {
220*4882a593Smuzhiyun 	case ACPI_GPE_ENABLE:
221*4882a593Smuzhiyun 
222*4882a593Smuzhiyun 		status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_ENABLE);
223*4882a593Smuzhiyun 		gpe_event_info->disable_for_dispatch = FALSE;
224*4882a593Smuzhiyun 		break;
225*4882a593Smuzhiyun 
226*4882a593Smuzhiyun 	case ACPI_GPE_DISABLE:
227*4882a593Smuzhiyun 
228*4882a593Smuzhiyun 		status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE);
229*4882a593Smuzhiyun 		gpe_event_info->disable_for_dispatch = TRUE;
230*4882a593Smuzhiyun 		break;
231*4882a593Smuzhiyun 
232*4882a593Smuzhiyun 	default:
233*4882a593Smuzhiyun 
234*4882a593Smuzhiyun 		status = AE_BAD_PARAMETER;
235*4882a593Smuzhiyun 		break;
236*4882a593Smuzhiyun 	}
237*4882a593Smuzhiyun 
238*4882a593Smuzhiyun unlock_and_exit:
239*4882a593Smuzhiyun 	acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
240*4882a593Smuzhiyun 	return_ACPI_STATUS(status);
241*4882a593Smuzhiyun }
242*4882a593Smuzhiyun 
ACPI_EXPORT_SYMBOL(acpi_set_gpe)243*4882a593Smuzhiyun ACPI_EXPORT_SYMBOL(acpi_set_gpe)
244*4882a593Smuzhiyun 
245*4882a593Smuzhiyun /*******************************************************************************
246*4882a593Smuzhiyun  *
247*4882a593Smuzhiyun  * FUNCTION:    acpi_mask_gpe
248*4882a593Smuzhiyun  *
249*4882a593Smuzhiyun  * PARAMETERS:  gpe_device          - Parent GPE Device. NULL for GPE0/GPE1
250*4882a593Smuzhiyun  *              gpe_number          - GPE level within the GPE block
251*4882a593Smuzhiyun  *              is_masked           - Whether the GPE is masked or not
252*4882a593Smuzhiyun  *
253*4882a593Smuzhiyun  * RETURN:      Status
254*4882a593Smuzhiyun  *
255*4882a593Smuzhiyun  * DESCRIPTION: Unconditionally mask/unmask the an individual GPE, ex., to
256*4882a593Smuzhiyun  *              prevent a GPE flooding.
257*4882a593Smuzhiyun  *
258*4882a593Smuzhiyun  ******************************************************************************/
259*4882a593Smuzhiyun acpi_status acpi_mask_gpe(acpi_handle gpe_device, u32 gpe_number, u8 is_masked)
260*4882a593Smuzhiyun {
261*4882a593Smuzhiyun 	struct acpi_gpe_event_info *gpe_event_info;
262*4882a593Smuzhiyun 	acpi_status status;
263*4882a593Smuzhiyun 	acpi_cpu_flags flags;
264*4882a593Smuzhiyun 
265*4882a593Smuzhiyun 	ACPI_FUNCTION_TRACE(acpi_mask_gpe);
266*4882a593Smuzhiyun 
267*4882a593Smuzhiyun 	flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
268*4882a593Smuzhiyun 
269*4882a593Smuzhiyun 	/* Ensure that we have a valid GPE number */
270*4882a593Smuzhiyun 
271*4882a593Smuzhiyun 	gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
272*4882a593Smuzhiyun 	if (!gpe_event_info) {
273*4882a593Smuzhiyun 		status = AE_BAD_PARAMETER;
274*4882a593Smuzhiyun 		goto unlock_and_exit;
275*4882a593Smuzhiyun 	}
276*4882a593Smuzhiyun 
277*4882a593Smuzhiyun 	status = acpi_ev_mask_gpe(gpe_event_info, is_masked);
278*4882a593Smuzhiyun 
279*4882a593Smuzhiyun unlock_and_exit:
280*4882a593Smuzhiyun 	acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
281*4882a593Smuzhiyun 	return_ACPI_STATUS(status);
282*4882a593Smuzhiyun }
283*4882a593Smuzhiyun 
ACPI_EXPORT_SYMBOL(acpi_mask_gpe)284*4882a593Smuzhiyun ACPI_EXPORT_SYMBOL(acpi_mask_gpe)
285*4882a593Smuzhiyun 
286*4882a593Smuzhiyun /*******************************************************************************
287*4882a593Smuzhiyun  *
288*4882a593Smuzhiyun  * FUNCTION:    acpi_mark_gpe_for_wake
289*4882a593Smuzhiyun  *
290*4882a593Smuzhiyun  * PARAMETERS:  gpe_device          - Parent GPE Device. NULL for GPE0/GPE1
291*4882a593Smuzhiyun  *              gpe_number          - GPE level within the GPE block
292*4882a593Smuzhiyun  *
293*4882a593Smuzhiyun  * RETURN:      Status
294*4882a593Smuzhiyun  *
295*4882a593Smuzhiyun  * DESCRIPTION: Mark a GPE as having the ability to wake the system. Simply
296*4882a593Smuzhiyun  *              sets the ACPI_GPE_CAN_WAKE flag.
297*4882a593Smuzhiyun  *
298*4882a593Smuzhiyun  * Some potential callers of acpi_setup_gpe_for_wake may know in advance that
299*4882a593Smuzhiyun  * there won't be any notify handlers installed for device wake notifications
300*4882a593Smuzhiyun  * from the given GPE (one example is a button GPE in Linux). For these cases,
301*4882a593Smuzhiyun  * acpi_mark_gpe_for_wake should be used instead of acpi_setup_gpe_for_wake.
302*4882a593Smuzhiyun  * This will set the ACPI_GPE_CAN_WAKE flag for the GPE without trying to
303*4882a593Smuzhiyun  * setup implicit wake notification for it (since there's no handler method).
304*4882a593Smuzhiyun  *
305*4882a593Smuzhiyun  ******************************************************************************/
306*4882a593Smuzhiyun acpi_status acpi_mark_gpe_for_wake(acpi_handle gpe_device, u32 gpe_number)
307*4882a593Smuzhiyun {
308*4882a593Smuzhiyun 	struct acpi_gpe_event_info *gpe_event_info;
309*4882a593Smuzhiyun 	acpi_status status = AE_BAD_PARAMETER;
310*4882a593Smuzhiyun 	acpi_cpu_flags flags;
311*4882a593Smuzhiyun 
312*4882a593Smuzhiyun 	ACPI_FUNCTION_TRACE(acpi_mark_gpe_for_wake);
313*4882a593Smuzhiyun 
314*4882a593Smuzhiyun 	flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
315*4882a593Smuzhiyun 
316*4882a593Smuzhiyun 	/* Ensure that we have a valid GPE number */
317*4882a593Smuzhiyun 
318*4882a593Smuzhiyun 	gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
319*4882a593Smuzhiyun 	if (gpe_event_info) {
320*4882a593Smuzhiyun 
321*4882a593Smuzhiyun 		/* Mark the GPE as a possible wake event */
322*4882a593Smuzhiyun 
323*4882a593Smuzhiyun 		gpe_event_info->flags |= ACPI_GPE_CAN_WAKE;
324*4882a593Smuzhiyun 		status = AE_OK;
325*4882a593Smuzhiyun 	}
326*4882a593Smuzhiyun 
327*4882a593Smuzhiyun 	acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
328*4882a593Smuzhiyun 	return_ACPI_STATUS(status);
329*4882a593Smuzhiyun }
330*4882a593Smuzhiyun 
ACPI_EXPORT_SYMBOL(acpi_mark_gpe_for_wake)331*4882a593Smuzhiyun ACPI_EXPORT_SYMBOL(acpi_mark_gpe_for_wake)
332*4882a593Smuzhiyun 
333*4882a593Smuzhiyun /*******************************************************************************
334*4882a593Smuzhiyun  *
335*4882a593Smuzhiyun  * FUNCTION:    acpi_setup_gpe_for_wake
336*4882a593Smuzhiyun  *
337*4882a593Smuzhiyun  * PARAMETERS:  wake_device         - Device associated with the GPE (via _PRW)
338*4882a593Smuzhiyun  *              gpe_device          - Parent GPE Device. NULL for GPE0/GPE1
339*4882a593Smuzhiyun  *              gpe_number          - GPE level within the GPE block
340*4882a593Smuzhiyun  *
341*4882a593Smuzhiyun  * RETURN:      Status
342*4882a593Smuzhiyun  *
343*4882a593Smuzhiyun  * DESCRIPTION: Mark a GPE as having the ability to wake the system. This
344*4882a593Smuzhiyun  *              interface is intended to be used as the host executes the
345*4882a593Smuzhiyun  *              _PRW methods (Power Resources for Wake) in the system tables.
346*4882a593Smuzhiyun  *              Each _PRW appears under a Device Object (The wake_device), and
347*4882a593Smuzhiyun  *              contains the info for the wake GPE associated with the
348*4882a593Smuzhiyun  *              wake_device.
349*4882a593Smuzhiyun  *
350*4882a593Smuzhiyun  ******************************************************************************/
351*4882a593Smuzhiyun acpi_status
352*4882a593Smuzhiyun acpi_setup_gpe_for_wake(acpi_handle wake_device,
353*4882a593Smuzhiyun 			acpi_handle gpe_device, u32 gpe_number)
354*4882a593Smuzhiyun {
355*4882a593Smuzhiyun 	acpi_status status;
356*4882a593Smuzhiyun 	struct acpi_gpe_event_info *gpe_event_info;
357*4882a593Smuzhiyun 	struct acpi_namespace_node *device_node;
358*4882a593Smuzhiyun 	struct acpi_gpe_notify_info *notify;
359*4882a593Smuzhiyun 	struct acpi_gpe_notify_info *new_notify;
360*4882a593Smuzhiyun 	acpi_cpu_flags flags;
361*4882a593Smuzhiyun 
362*4882a593Smuzhiyun 	ACPI_FUNCTION_TRACE(acpi_setup_gpe_for_wake);
363*4882a593Smuzhiyun 
364*4882a593Smuzhiyun 	/* Parameter Validation */
365*4882a593Smuzhiyun 
366*4882a593Smuzhiyun 	if (!wake_device) {
367*4882a593Smuzhiyun 		/*
368*4882a593Smuzhiyun 		 * By forcing wake_device to be valid, we automatically enable the
369*4882a593Smuzhiyun 		 * implicit notify feature on all hosts.
370*4882a593Smuzhiyun 		 */
371*4882a593Smuzhiyun 		return_ACPI_STATUS(AE_BAD_PARAMETER);
372*4882a593Smuzhiyun 	}
373*4882a593Smuzhiyun 
374*4882a593Smuzhiyun 	/* Handle root object case */
375*4882a593Smuzhiyun 
376*4882a593Smuzhiyun 	if (wake_device == ACPI_ROOT_OBJECT) {
377*4882a593Smuzhiyun 		device_node = acpi_gbl_root_node;
378*4882a593Smuzhiyun 	} else {
379*4882a593Smuzhiyun 		device_node =
380*4882a593Smuzhiyun 		    ACPI_CAST_PTR(struct acpi_namespace_node, wake_device);
381*4882a593Smuzhiyun 	}
382*4882a593Smuzhiyun 
383*4882a593Smuzhiyun 	/* Validate wake_device is of type Device */
384*4882a593Smuzhiyun 
385*4882a593Smuzhiyun 	if (device_node->type != ACPI_TYPE_DEVICE) {
386*4882a593Smuzhiyun 		return_ACPI_STATUS (AE_BAD_PARAMETER);
387*4882a593Smuzhiyun 	}
388*4882a593Smuzhiyun 
389*4882a593Smuzhiyun 	/*
390*4882a593Smuzhiyun 	 * Allocate a new notify object up front, in case it is needed.
391*4882a593Smuzhiyun 	 * Memory allocation while holding a spinlock is a big no-no
392*4882a593Smuzhiyun 	 * on some hosts.
393*4882a593Smuzhiyun 	 */
394*4882a593Smuzhiyun 	new_notify = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_gpe_notify_info));
395*4882a593Smuzhiyun 	if (!new_notify) {
396*4882a593Smuzhiyun 		return_ACPI_STATUS(AE_NO_MEMORY);
397*4882a593Smuzhiyun 	}
398*4882a593Smuzhiyun 
399*4882a593Smuzhiyun 	flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
400*4882a593Smuzhiyun 
401*4882a593Smuzhiyun 	/* Ensure that we have a valid GPE number */
402*4882a593Smuzhiyun 
403*4882a593Smuzhiyun 	gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
404*4882a593Smuzhiyun 	if (!gpe_event_info) {
405*4882a593Smuzhiyun 		status = AE_BAD_PARAMETER;
406*4882a593Smuzhiyun 		goto unlock_and_exit;
407*4882a593Smuzhiyun 	}
408*4882a593Smuzhiyun 
409*4882a593Smuzhiyun 	/*
410*4882a593Smuzhiyun 	 * If there is no method or handler for this GPE, then the
411*4882a593Smuzhiyun 	 * wake_device will be notified whenever this GPE fires. This is
412*4882a593Smuzhiyun 	 * known as an "implicit notify". Note: The GPE is assumed to be
413*4882a593Smuzhiyun 	 * level-triggered (for windows compatibility).
414*4882a593Smuzhiyun 	 */
415*4882a593Smuzhiyun 	if (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) ==
416*4882a593Smuzhiyun 	    ACPI_GPE_DISPATCH_NONE) {
417*4882a593Smuzhiyun 		/*
418*4882a593Smuzhiyun 		 * This is the first device for implicit notify on this GPE.
419*4882a593Smuzhiyun 		 * Just set the flags here, and enter the NOTIFY block below.
420*4882a593Smuzhiyun 		 */
421*4882a593Smuzhiyun 		gpe_event_info->flags =
422*4882a593Smuzhiyun 		    (ACPI_GPE_DISPATCH_NOTIFY | ACPI_GPE_LEVEL_TRIGGERED);
423*4882a593Smuzhiyun 	} else if (gpe_event_info->flags & ACPI_GPE_AUTO_ENABLED) {
424*4882a593Smuzhiyun 		/*
425*4882a593Smuzhiyun 		 * A reference to this GPE has been added during the GPE block
426*4882a593Smuzhiyun 		 * initialization, so drop it now to prevent the GPE from being
427*4882a593Smuzhiyun 		 * permanently enabled and clear its ACPI_GPE_AUTO_ENABLED flag.
428*4882a593Smuzhiyun 		 */
429*4882a593Smuzhiyun 		(void)acpi_ev_remove_gpe_reference(gpe_event_info);
430*4882a593Smuzhiyun 		gpe_event_info->flags &= ~ACPI_GPE_AUTO_ENABLED;
431*4882a593Smuzhiyun 	}
432*4882a593Smuzhiyun 
433*4882a593Smuzhiyun 	/*
434*4882a593Smuzhiyun 	 * If we already have an implicit notify on this GPE, add
435*4882a593Smuzhiyun 	 * this device to the notify list.
436*4882a593Smuzhiyun 	 */
437*4882a593Smuzhiyun 	if (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) ==
438*4882a593Smuzhiyun 	    ACPI_GPE_DISPATCH_NOTIFY) {
439*4882a593Smuzhiyun 
440*4882a593Smuzhiyun 		/* Ensure that the device is not already in the list */
441*4882a593Smuzhiyun 
442*4882a593Smuzhiyun 		notify = gpe_event_info->dispatch.notify_list;
443*4882a593Smuzhiyun 		while (notify) {
444*4882a593Smuzhiyun 			if (notify->device_node == device_node) {
445*4882a593Smuzhiyun 				status = AE_ALREADY_EXISTS;
446*4882a593Smuzhiyun 				goto unlock_and_exit;
447*4882a593Smuzhiyun 			}
448*4882a593Smuzhiyun 			notify = notify->next;
449*4882a593Smuzhiyun 		}
450*4882a593Smuzhiyun 
451*4882a593Smuzhiyun 		/* Add this device to the notify list for this GPE */
452*4882a593Smuzhiyun 
453*4882a593Smuzhiyun 		new_notify->device_node = device_node;
454*4882a593Smuzhiyun 		new_notify->next = gpe_event_info->dispatch.notify_list;
455*4882a593Smuzhiyun 		gpe_event_info->dispatch.notify_list = new_notify;
456*4882a593Smuzhiyun 		new_notify = NULL;
457*4882a593Smuzhiyun 	}
458*4882a593Smuzhiyun 
459*4882a593Smuzhiyun 	/* Mark the GPE as a possible wake event */
460*4882a593Smuzhiyun 
461*4882a593Smuzhiyun 	gpe_event_info->flags |= ACPI_GPE_CAN_WAKE;
462*4882a593Smuzhiyun 	status = AE_OK;
463*4882a593Smuzhiyun 
464*4882a593Smuzhiyun unlock_and_exit:
465*4882a593Smuzhiyun 	acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
466*4882a593Smuzhiyun 
467*4882a593Smuzhiyun 	/* Delete the notify object if it was not used above */
468*4882a593Smuzhiyun 
469*4882a593Smuzhiyun 	if (new_notify) {
470*4882a593Smuzhiyun 		ACPI_FREE(new_notify);
471*4882a593Smuzhiyun 	}
472*4882a593Smuzhiyun 	return_ACPI_STATUS(status);
473*4882a593Smuzhiyun }
ACPI_EXPORT_SYMBOL(acpi_setup_gpe_for_wake)474*4882a593Smuzhiyun ACPI_EXPORT_SYMBOL(acpi_setup_gpe_for_wake)
475*4882a593Smuzhiyun 
476*4882a593Smuzhiyun /*******************************************************************************
477*4882a593Smuzhiyun  *
478*4882a593Smuzhiyun  * FUNCTION:    acpi_set_gpe_wake_mask
479*4882a593Smuzhiyun  *
480*4882a593Smuzhiyun  * PARAMETERS:  gpe_device      - Parent GPE Device. NULL for GPE0/GPE1
481*4882a593Smuzhiyun  *              gpe_number      - GPE level within the GPE block
482*4882a593Smuzhiyun  *              action              - Enable or Disable
483*4882a593Smuzhiyun  *
484*4882a593Smuzhiyun  * RETURN:      Status
485*4882a593Smuzhiyun  *
486*4882a593Smuzhiyun  * DESCRIPTION: Set or clear the GPE's wakeup enable mask bit. The GPE must
487*4882a593Smuzhiyun  *              already be marked as a WAKE GPE.
488*4882a593Smuzhiyun  *
489*4882a593Smuzhiyun  ******************************************************************************/
490*4882a593Smuzhiyun 
491*4882a593Smuzhiyun acpi_status
492*4882a593Smuzhiyun acpi_set_gpe_wake_mask(acpi_handle gpe_device, u32 gpe_number, u8 action)
493*4882a593Smuzhiyun {
494*4882a593Smuzhiyun 	acpi_status status = AE_OK;
495*4882a593Smuzhiyun 	struct acpi_gpe_event_info *gpe_event_info;
496*4882a593Smuzhiyun 	struct acpi_gpe_register_info *gpe_register_info;
497*4882a593Smuzhiyun 	acpi_cpu_flags flags;
498*4882a593Smuzhiyun 	u32 register_bit;
499*4882a593Smuzhiyun 
500*4882a593Smuzhiyun 	ACPI_FUNCTION_TRACE(acpi_set_gpe_wake_mask);
501*4882a593Smuzhiyun 
502*4882a593Smuzhiyun 	flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
503*4882a593Smuzhiyun 
504*4882a593Smuzhiyun 	/*
505*4882a593Smuzhiyun 	 * Ensure that we have a valid GPE number and that this GPE is in
506*4882a593Smuzhiyun 	 * fact a wake GPE
507*4882a593Smuzhiyun 	 */
508*4882a593Smuzhiyun 	gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
509*4882a593Smuzhiyun 	if (!gpe_event_info) {
510*4882a593Smuzhiyun 		status = AE_BAD_PARAMETER;
511*4882a593Smuzhiyun 		goto unlock_and_exit;
512*4882a593Smuzhiyun 	}
513*4882a593Smuzhiyun 
514*4882a593Smuzhiyun 	if (!(gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) {
515*4882a593Smuzhiyun 		status = AE_TYPE;
516*4882a593Smuzhiyun 		goto unlock_and_exit;
517*4882a593Smuzhiyun 	}
518*4882a593Smuzhiyun 
519*4882a593Smuzhiyun 	gpe_register_info = gpe_event_info->register_info;
520*4882a593Smuzhiyun 	if (!gpe_register_info) {
521*4882a593Smuzhiyun 		status = AE_NOT_EXIST;
522*4882a593Smuzhiyun 		goto unlock_and_exit;
523*4882a593Smuzhiyun 	}
524*4882a593Smuzhiyun 
525*4882a593Smuzhiyun 	register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info);
526*4882a593Smuzhiyun 
527*4882a593Smuzhiyun 	/* Perform the action */
528*4882a593Smuzhiyun 
529*4882a593Smuzhiyun 	switch (action) {
530*4882a593Smuzhiyun 	case ACPI_GPE_ENABLE:
531*4882a593Smuzhiyun 
532*4882a593Smuzhiyun 		ACPI_SET_BIT(gpe_register_info->enable_for_wake,
533*4882a593Smuzhiyun 			     (u8)register_bit);
534*4882a593Smuzhiyun 		break;
535*4882a593Smuzhiyun 
536*4882a593Smuzhiyun 	case ACPI_GPE_DISABLE:
537*4882a593Smuzhiyun 
538*4882a593Smuzhiyun 		ACPI_CLEAR_BIT(gpe_register_info->enable_for_wake,
539*4882a593Smuzhiyun 			       (u8)register_bit);
540*4882a593Smuzhiyun 		break;
541*4882a593Smuzhiyun 
542*4882a593Smuzhiyun 	default:
543*4882a593Smuzhiyun 
544*4882a593Smuzhiyun 		ACPI_ERROR((AE_INFO, "%u, Invalid action", action));
545*4882a593Smuzhiyun 		status = AE_BAD_PARAMETER;
546*4882a593Smuzhiyun 		break;
547*4882a593Smuzhiyun 	}
548*4882a593Smuzhiyun 
549*4882a593Smuzhiyun unlock_and_exit:
550*4882a593Smuzhiyun 	acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
551*4882a593Smuzhiyun 	return_ACPI_STATUS(status);
552*4882a593Smuzhiyun }
553*4882a593Smuzhiyun 
ACPI_EXPORT_SYMBOL(acpi_set_gpe_wake_mask)554*4882a593Smuzhiyun ACPI_EXPORT_SYMBOL(acpi_set_gpe_wake_mask)
555*4882a593Smuzhiyun 
556*4882a593Smuzhiyun /*******************************************************************************
557*4882a593Smuzhiyun  *
558*4882a593Smuzhiyun  * FUNCTION:    acpi_clear_gpe
559*4882a593Smuzhiyun  *
560*4882a593Smuzhiyun  * PARAMETERS:  gpe_device      - Parent GPE Device. NULL for GPE0/GPE1
561*4882a593Smuzhiyun  *              gpe_number      - GPE level within the GPE block
562*4882a593Smuzhiyun  *
563*4882a593Smuzhiyun  * RETURN:      Status
564*4882a593Smuzhiyun  *
565*4882a593Smuzhiyun  * DESCRIPTION: Clear an ACPI event (general purpose)
566*4882a593Smuzhiyun  *
567*4882a593Smuzhiyun  ******************************************************************************/
568*4882a593Smuzhiyun acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number)
569*4882a593Smuzhiyun {
570*4882a593Smuzhiyun 	acpi_status status = AE_OK;
571*4882a593Smuzhiyun 	struct acpi_gpe_event_info *gpe_event_info;
572*4882a593Smuzhiyun 	acpi_cpu_flags flags;
573*4882a593Smuzhiyun 
574*4882a593Smuzhiyun 	ACPI_FUNCTION_TRACE(acpi_clear_gpe);
575*4882a593Smuzhiyun 
576*4882a593Smuzhiyun 	flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
577*4882a593Smuzhiyun 
578*4882a593Smuzhiyun 	/* Ensure that we have a valid GPE number */
579*4882a593Smuzhiyun 
580*4882a593Smuzhiyun 	gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
581*4882a593Smuzhiyun 	if (!gpe_event_info) {
582*4882a593Smuzhiyun 		status = AE_BAD_PARAMETER;
583*4882a593Smuzhiyun 		goto unlock_and_exit;
584*4882a593Smuzhiyun 	}
585*4882a593Smuzhiyun 
586*4882a593Smuzhiyun 	status = acpi_hw_clear_gpe(gpe_event_info);
587*4882a593Smuzhiyun 
588*4882a593Smuzhiyun       unlock_and_exit:
589*4882a593Smuzhiyun 	acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
590*4882a593Smuzhiyun 	return_ACPI_STATUS(status);
591*4882a593Smuzhiyun }
592*4882a593Smuzhiyun 
ACPI_EXPORT_SYMBOL(acpi_clear_gpe)593*4882a593Smuzhiyun ACPI_EXPORT_SYMBOL(acpi_clear_gpe)
594*4882a593Smuzhiyun 
595*4882a593Smuzhiyun /*******************************************************************************
596*4882a593Smuzhiyun  *
597*4882a593Smuzhiyun  * FUNCTION:    acpi_get_gpe_status
598*4882a593Smuzhiyun  *
599*4882a593Smuzhiyun  * PARAMETERS:  gpe_device          - Parent GPE Device. NULL for GPE0/GPE1
600*4882a593Smuzhiyun  *              gpe_number          - GPE level within the GPE block
601*4882a593Smuzhiyun  *              event_status        - Where the current status of the event
602*4882a593Smuzhiyun  *                                    will be returned
603*4882a593Smuzhiyun  *
604*4882a593Smuzhiyun  * RETURN:      Status
605*4882a593Smuzhiyun  *
606*4882a593Smuzhiyun  * DESCRIPTION: Get the current status of a GPE (signalled/not_signalled)
607*4882a593Smuzhiyun  *
608*4882a593Smuzhiyun  ******************************************************************************/
609*4882a593Smuzhiyun acpi_status
610*4882a593Smuzhiyun acpi_get_gpe_status(acpi_handle gpe_device,
611*4882a593Smuzhiyun 		    u32 gpe_number, acpi_event_status *event_status)
612*4882a593Smuzhiyun {
613*4882a593Smuzhiyun 	acpi_status status = AE_OK;
614*4882a593Smuzhiyun 	struct acpi_gpe_event_info *gpe_event_info;
615*4882a593Smuzhiyun 	acpi_cpu_flags flags;
616*4882a593Smuzhiyun 
617*4882a593Smuzhiyun 	ACPI_FUNCTION_TRACE(acpi_get_gpe_status);
618*4882a593Smuzhiyun 
619*4882a593Smuzhiyun 	flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
620*4882a593Smuzhiyun 
621*4882a593Smuzhiyun 	/* Ensure that we have a valid GPE number */
622*4882a593Smuzhiyun 
623*4882a593Smuzhiyun 	gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
624*4882a593Smuzhiyun 	if (!gpe_event_info) {
625*4882a593Smuzhiyun 		status = AE_BAD_PARAMETER;
626*4882a593Smuzhiyun 		goto unlock_and_exit;
627*4882a593Smuzhiyun 	}
628*4882a593Smuzhiyun 
629*4882a593Smuzhiyun 	/* Obtain status on the requested GPE number */
630*4882a593Smuzhiyun 
631*4882a593Smuzhiyun 	status = acpi_hw_get_gpe_status(gpe_event_info, event_status);
632*4882a593Smuzhiyun 
633*4882a593Smuzhiyun unlock_and_exit:
634*4882a593Smuzhiyun 	acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
635*4882a593Smuzhiyun 	return_ACPI_STATUS(status);
636*4882a593Smuzhiyun }
637*4882a593Smuzhiyun 
ACPI_EXPORT_SYMBOL(acpi_get_gpe_status)638*4882a593Smuzhiyun ACPI_EXPORT_SYMBOL(acpi_get_gpe_status)
639*4882a593Smuzhiyun 
640*4882a593Smuzhiyun /*******************************************************************************
641*4882a593Smuzhiyun  *
642*4882a593Smuzhiyun  * FUNCTION:    acpi_gispatch_gpe
643*4882a593Smuzhiyun  *
644*4882a593Smuzhiyun  * PARAMETERS:  gpe_device          - Parent GPE Device. NULL for GPE0/GPE1
645*4882a593Smuzhiyun  *              gpe_number          - GPE level within the GPE block
646*4882a593Smuzhiyun  *
647*4882a593Smuzhiyun  * RETURN:      INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED
648*4882a593Smuzhiyun  *
649*4882a593Smuzhiyun  * DESCRIPTION: Detect and dispatch a General Purpose Event to either a function
650*4882a593Smuzhiyun  *              (e.g. EC) or method (e.g. _Lxx/_Exx) handler.
651*4882a593Smuzhiyun  *
652*4882a593Smuzhiyun  ******************************************************************************/
653*4882a593Smuzhiyun u32 acpi_dispatch_gpe(acpi_handle gpe_device, u32 gpe_number)
654*4882a593Smuzhiyun {
655*4882a593Smuzhiyun 	ACPI_FUNCTION_TRACE(acpi_dispatch_gpe);
656*4882a593Smuzhiyun 
657*4882a593Smuzhiyun 	return acpi_ev_detect_gpe(gpe_device, NULL, gpe_number);
658*4882a593Smuzhiyun }
659*4882a593Smuzhiyun 
ACPI_EXPORT_SYMBOL(acpi_dispatch_gpe)660*4882a593Smuzhiyun ACPI_EXPORT_SYMBOL(acpi_dispatch_gpe)
661*4882a593Smuzhiyun 
662*4882a593Smuzhiyun /*******************************************************************************
663*4882a593Smuzhiyun  *
664*4882a593Smuzhiyun  * FUNCTION:    acpi_finish_gpe
665*4882a593Smuzhiyun  *
666*4882a593Smuzhiyun  * PARAMETERS:  gpe_device          - Namespace node for the GPE Block
667*4882a593Smuzhiyun  *                                    (NULL for FADT defined GPEs)
668*4882a593Smuzhiyun  *              gpe_number          - GPE level within the GPE block
669*4882a593Smuzhiyun  *
670*4882a593Smuzhiyun  * RETURN:      Status
671*4882a593Smuzhiyun  *
672*4882a593Smuzhiyun  * DESCRIPTION: Clear and conditionally re-enable a GPE. This completes the GPE
673*4882a593Smuzhiyun  *              processing. Intended for use by asynchronous host-installed
674*4882a593Smuzhiyun  *              GPE handlers. The GPE is only re-enabled if the enable_for_run bit
675*4882a593Smuzhiyun  *              is set in the GPE info.
676*4882a593Smuzhiyun  *
677*4882a593Smuzhiyun  ******************************************************************************/
678*4882a593Smuzhiyun acpi_status acpi_finish_gpe(acpi_handle gpe_device, u32 gpe_number)
679*4882a593Smuzhiyun {
680*4882a593Smuzhiyun 	struct acpi_gpe_event_info *gpe_event_info;
681*4882a593Smuzhiyun 	acpi_status status;
682*4882a593Smuzhiyun 	acpi_cpu_flags flags;
683*4882a593Smuzhiyun 
684*4882a593Smuzhiyun 	ACPI_FUNCTION_TRACE(acpi_finish_gpe);
685*4882a593Smuzhiyun 
686*4882a593Smuzhiyun 	flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
687*4882a593Smuzhiyun 
688*4882a593Smuzhiyun 	/* Ensure that we have a valid GPE number */
689*4882a593Smuzhiyun 
690*4882a593Smuzhiyun 	gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
691*4882a593Smuzhiyun 	if (!gpe_event_info) {
692*4882a593Smuzhiyun 		status = AE_BAD_PARAMETER;
693*4882a593Smuzhiyun 		goto unlock_and_exit;
694*4882a593Smuzhiyun 	}
695*4882a593Smuzhiyun 
696*4882a593Smuzhiyun 	status = acpi_ev_finish_gpe(gpe_event_info);
697*4882a593Smuzhiyun 
698*4882a593Smuzhiyun unlock_and_exit:
699*4882a593Smuzhiyun 	acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
700*4882a593Smuzhiyun 	return_ACPI_STATUS(status);
701*4882a593Smuzhiyun }
702*4882a593Smuzhiyun 
ACPI_EXPORT_SYMBOL(acpi_finish_gpe)703*4882a593Smuzhiyun ACPI_EXPORT_SYMBOL(acpi_finish_gpe)
704*4882a593Smuzhiyun 
705*4882a593Smuzhiyun /******************************************************************************
706*4882a593Smuzhiyun  *
707*4882a593Smuzhiyun  * FUNCTION:    acpi_disable_all_gpes
708*4882a593Smuzhiyun  *
709*4882a593Smuzhiyun  * PARAMETERS:  None
710*4882a593Smuzhiyun  *
711*4882a593Smuzhiyun  * RETURN:      Status
712*4882a593Smuzhiyun  *
713*4882a593Smuzhiyun  * DESCRIPTION: Disable and clear all GPEs in all GPE blocks
714*4882a593Smuzhiyun  *
715*4882a593Smuzhiyun  ******************************************************************************/
716*4882a593Smuzhiyun 
717*4882a593Smuzhiyun acpi_status acpi_disable_all_gpes(void)
718*4882a593Smuzhiyun {
719*4882a593Smuzhiyun 	acpi_status status;
720*4882a593Smuzhiyun 
721*4882a593Smuzhiyun 	ACPI_FUNCTION_TRACE(acpi_disable_all_gpes);
722*4882a593Smuzhiyun 
723*4882a593Smuzhiyun 	status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
724*4882a593Smuzhiyun 	if (ACPI_FAILURE(status)) {
725*4882a593Smuzhiyun 		return_ACPI_STATUS(status);
726*4882a593Smuzhiyun 	}
727*4882a593Smuzhiyun 
728*4882a593Smuzhiyun 	status = acpi_hw_disable_all_gpes();
729*4882a593Smuzhiyun 	(void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
730*4882a593Smuzhiyun 
731*4882a593Smuzhiyun 	return_ACPI_STATUS(status);
732*4882a593Smuzhiyun }
733*4882a593Smuzhiyun 
ACPI_EXPORT_SYMBOL(acpi_disable_all_gpes)734*4882a593Smuzhiyun ACPI_EXPORT_SYMBOL(acpi_disable_all_gpes)
735*4882a593Smuzhiyun 
736*4882a593Smuzhiyun /******************************************************************************
737*4882a593Smuzhiyun  *
738*4882a593Smuzhiyun  * FUNCTION:    acpi_enable_all_runtime_gpes
739*4882a593Smuzhiyun  *
740*4882a593Smuzhiyun  * PARAMETERS:  None
741*4882a593Smuzhiyun  *
742*4882a593Smuzhiyun  * RETURN:      Status
743*4882a593Smuzhiyun  *
744*4882a593Smuzhiyun  * DESCRIPTION: Enable all "runtime" GPEs, in all GPE blocks
745*4882a593Smuzhiyun  *
746*4882a593Smuzhiyun  ******************************************************************************/
747*4882a593Smuzhiyun 
748*4882a593Smuzhiyun acpi_status acpi_enable_all_runtime_gpes(void)
749*4882a593Smuzhiyun {
750*4882a593Smuzhiyun 	acpi_status status;
751*4882a593Smuzhiyun 
752*4882a593Smuzhiyun 	ACPI_FUNCTION_TRACE(acpi_enable_all_runtime_gpes);
753*4882a593Smuzhiyun 
754*4882a593Smuzhiyun 	status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
755*4882a593Smuzhiyun 	if (ACPI_FAILURE(status)) {
756*4882a593Smuzhiyun 		return_ACPI_STATUS(status);
757*4882a593Smuzhiyun 	}
758*4882a593Smuzhiyun 
759*4882a593Smuzhiyun 	status = acpi_hw_enable_all_runtime_gpes();
760*4882a593Smuzhiyun 	(void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
761*4882a593Smuzhiyun 
762*4882a593Smuzhiyun 	return_ACPI_STATUS(status);
763*4882a593Smuzhiyun }
764*4882a593Smuzhiyun 
ACPI_EXPORT_SYMBOL(acpi_enable_all_runtime_gpes)765*4882a593Smuzhiyun ACPI_EXPORT_SYMBOL(acpi_enable_all_runtime_gpes)
766*4882a593Smuzhiyun 
767*4882a593Smuzhiyun /******************************************************************************
768*4882a593Smuzhiyun  *
769*4882a593Smuzhiyun  * FUNCTION:    acpi_enable_all_wakeup_gpes
770*4882a593Smuzhiyun  *
771*4882a593Smuzhiyun  * PARAMETERS:  None
772*4882a593Smuzhiyun  *
773*4882a593Smuzhiyun  * RETURN:      Status
774*4882a593Smuzhiyun  *
775*4882a593Smuzhiyun  * DESCRIPTION: Enable all "wakeup" GPEs and disable all of the other GPEs, in
776*4882a593Smuzhiyun  *              all GPE blocks.
777*4882a593Smuzhiyun  *
778*4882a593Smuzhiyun  ******************************************************************************/
779*4882a593Smuzhiyun acpi_status acpi_enable_all_wakeup_gpes(void)
780*4882a593Smuzhiyun {
781*4882a593Smuzhiyun 	acpi_status status;
782*4882a593Smuzhiyun 
783*4882a593Smuzhiyun 	ACPI_FUNCTION_TRACE(acpi_enable_all_wakeup_gpes);
784*4882a593Smuzhiyun 
785*4882a593Smuzhiyun 	status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
786*4882a593Smuzhiyun 	if (ACPI_FAILURE(status)) {
787*4882a593Smuzhiyun 		return_ACPI_STATUS(status);
788*4882a593Smuzhiyun 	}
789*4882a593Smuzhiyun 
790*4882a593Smuzhiyun 	status = acpi_hw_enable_all_wakeup_gpes();
791*4882a593Smuzhiyun 	(void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
792*4882a593Smuzhiyun 
793*4882a593Smuzhiyun 	return_ACPI_STATUS(status);
794*4882a593Smuzhiyun }
795*4882a593Smuzhiyun 
ACPI_EXPORT_SYMBOL(acpi_enable_all_wakeup_gpes)796*4882a593Smuzhiyun ACPI_EXPORT_SYMBOL(acpi_enable_all_wakeup_gpes)
797*4882a593Smuzhiyun 
798*4882a593Smuzhiyun /******************************************************************************
799*4882a593Smuzhiyun  *
800*4882a593Smuzhiyun  * FUNCTION:    acpi_any_gpe_status_set
801*4882a593Smuzhiyun  *
802*4882a593Smuzhiyun  * PARAMETERS:  gpe_skip_number      - Number of the GPE to skip
803*4882a593Smuzhiyun  *
804*4882a593Smuzhiyun  * RETURN:      Whether or not the status bit is set for any GPE
805*4882a593Smuzhiyun  *
806*4882a593Smuzhiyun  * DESCRIPTION: Check the status bits of all enabled GPEs, except for the one
807*4882a593Smuzhiyun  *              represented by the "skip" argument, and return TRUE if any of
808*4882a593Smuzhiyun  *              them is set or FALSE otherwise.
809*4882a593Smuzhiyun  *
810*4882a593Smuzhiyun  ******************************************************************************/
811*4882a593Smuzhiyun u32 acpi_any_gpe_status_set(u32 gpe_skip_number)
812*4882a593Smuzhiyun {
813*4882a593Smuzhiyun 	acpi_status status;
814*4882a593Smuzhiyun 	acpi_handle gpe_device;
815*4882a593Smuzhiyun 	u8 ret;
816*4882a593Smuzhiyun 
817*4882a593Smuzhiyun 	ACPI_FUNCTION_TRACE(acpi_any_gpe_status_set);
818*4882a593Smuzhiyun 
819*4882a593Smuzhiyun 	status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
820*4882a593Smuzhiyun 	if (ACPI_FAILURE(status)) {
821*4882a593Smuzhiyun 		return (FALSE);
822*4882a593Smuzhiyun 	}
823*4882a593Smuzhiyun 
824*4882a593Smuzhiyun 	status = acpi_get_gpe_device(gpe_skip_number, &gpe_device);
825*4882a593Smuzhiyun 	if (ACPI_FAILURE(status)) {
826*4882a593Smuzhiyun 		gpe_device = NULL;
827*4882a593Smuzhiyun 	}
828*4882a593Smuzhiyun 
829*4882a593Smuzhiyun 	ret = acpi_hw_check_all_gpes(gpe_device, gpe_skip_number);
830*4882a593Smuzhiyun 	(void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
831*4882a593Smuzhiyun 
832*4882a593Smuzhiyun 	return (ret);
833*4882a593Smuzhiyun }
834*4882a593Smuzhiyun 
ACPI_EXPORT_SYMBOL(acpi_any_gpe_status_set)835*4882a593Smuzhiyun ACPI_EXPORT_SYMBOL(acpi_any_gpe_status_set)
836*4882a593Smuzhiyun 
837*4882a593Smuzhiyun /*******************************************************************************
838*4882a593Smuzhiyun  *
839*4882a593Smuzhiyun  * FUNCTION:    acpi_install_gpe_block
840*4882a593Smuzhiyun  *
841*4882a593Smuzhiyun  * PARAMETERS:  gpe_device          - Handle to the parent GPE Block Device
842*4882a593Smuzhiyun  *              gpe_block_address   - Address and space_ID
843*4882a593Smuzhiyun  *              register_count      - Number of GPE register pairs in the block
844*4882a593Smuzhiyun  *              interrupt_number    - H/W interrupt for the block
845*4882a593Smuzhiyun  *
846*4882a593Smuzhiyun  * RETURN:      Status
847*4882a593Smuzhiyun  *
848*4882a593Smuzhiyun  * DESCRIPTION: Create and Install a block of GPE registers. The GPEs are not
849*4882a593Smuzhiyun  *              enabled here.
850*4882a593Smuzhiyun  *
851*4882a593Smuzhiyun  ******************************************************************************/
852*4882a593Smuzhiyun acpi_status
853*4882a593Smuzhiyun acpi_install_gpe_block(acpi_handle gpe_device,
854*4882a593Smuzhiyun 		       struct acpi_generic_address *gpe_block_address,
855*4882a593Smuzhiyun 		       u32 register_count, u32 interrupt_number)
856*4882a593Smuzhiyun {
857*4882a593Smuzhiyun 	acpi_status status;
858*4882a593Smuzhiyun 	union acpi_operand_object *obj_desc;
859*4882a593Smuzhiyun 	struct acpi_namespace_node *node;
860*4882a593Smuzhiyun 	struct acpi_gpe_block_info *gpe_block;
861*4882a593Smuzhiyun 
862*4882a593Smuzhiyun 	ACPI_FUNCTION_TRACE(acpi_install_gpe_block);
863*4882a593Smuzhiyun 
864*4882a593Smuzhiyun 	if ((!gpe_device) || (!gpe_block_address) || (!register_count)) {
865*4882a593Smuzhiyun 		return_ACPI_STATUS(AE_BAD_PARAMETER);
866*4882a593Smuzhiyun 	}
867*4882a593Smuzhiyun 
868*4882a593Smuzhiyun 	status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
869*4882a593Smuzhiyun 	if (ACPI_FAILURE(status)) {
870*4882a593Smuzhiyun 		return_ACPI_STATUS(status);
871*4882a593Smuzhiyun 	}
872*4882a593Smuzhiyun 
873*4882a593Smuzhiyun 	node = acpi_ns_validate_handle(gpe_device);
874*4882a593Smuzhiyun 	if (!node) {
875*4882a593Smuzhiyun 		status = AE_BAD_PARAMETER;
876*4882a593Smuzhiyun 		goto unlock_and_exit;
877*4882a593Smuzhiyun 	}
878*4882a593Smuzhiyun 
879*4882a593Smuzhiyun 	/* Validate the parent device */
880*4882a593Smuzhiyun 
881*4882a593Smuzhiyun 	if (node->type != ACPI_TYPE_DEVICE) {
882*4882a593Smuzhiyun 		status = AE_TYPE;
883*4882a593Smuzhiyun 		goto unlock_and_exit;
884*4882a593Smuzhiyun 	}
885*4882a593Smuzhiyun 
886*4882a593Smuzhiyun 	if (node->object) {
887*4882a593Smuzhiyun 		status = AE_ALREADY_EXISTS;
888*4882a593Smuzhiyun 		goto unlock_and_exit;
889*4882a593Smuzhiyun 	}
890*4882a593Smuzhiyun 
891*4882a593Smuzhiyun 	/*
892*4882a593Smuzhiyun 	 * For user-installed GPE Block Devices, the gpe_block_base_number
893*4882a593Smuzhiyun 	 * is always zero
894*4882a593Smuzhiyun 	 */
895*4882a593Smuzhiyun 	status = acpi_ev_create_gpe_block(node, gpe_block_address->address,
896*4882a593Smuzhiyun 					  gpe_block_address->space_id,
897*4882a593Smuzhiyun 					  register_count, 0, interrupt_number,
898*4882a593Smuzhiyun 					  &gpe_block);
899*4882a593Smuzhiyun 	if (ACPI_FAILURE(status)) {
900*4882a593Smuzhiyun 		goto unlock_and_exit;
901*4882a593Smuzhiyun 	}
902*4882a593Smuzhiyun 
903*4882a593Smuzhiyun 	/* Install block in the device_object attached to the node */
904*4882a593Smuzhiyun 
905*4882a593Smuzhiyun 	obj_desc = acpi_ns_get_attached_object(node);
906*4882a593Smuzhiyun 	if (!obj_desc) {
907*4882a593Smuzhiyun 
908*4882a593Smuzhiyun 		/*
909*4882a593Smuzhiyun 		 * No object, create a new one (Device nodes do not always have
910*4882a593Smuzhiyun 		 * an attached object)
911*4882a593Smuzhiyun 		 */
912*4882a593Smuzhiyun 		obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_DEVICE);
913*4882a593Smuzhiyun 		if (!obj_desc) {
914*4882a593Smuzhiyun 			status = AE_NO_MEMORY;
915*4882a593Smuzhiyun 			goto unlock_and_exit;
916*4882a593Smuzhiyun 		}
917*4882a593Smuzhiyun 
918*4882a593Smuzhiyun 		status =
919*4882a593Smuzhiyun 		    acpi_ns_attach_object(node, obj_desc, ACPI_TYPE_DEVICE);
920*4882a593Smuzhiyun 
921*4882a593Smuzhiyun 		/* Remove local reference to the object */
922*4882a593Smuzhiyun 
923*4882a593Smuzhiyun 		acpi_ut_remove_reference(obj_desc);
924*4882a593Smuzhiyun 
925*4882a593Smuzhiyun 		if (ACPI_FAILURE(status)) {
926*4882a593Smuzhiyun 			goto unlock_and_exit;
927*4882a593Smuzhiyun 		}
928*4882a593Smuzhiyun 	}
929*4882a593Smuzhiyun 
930*4882a593Smuzhiyun 	/* Now install the GPE block in the device_object */
931*4882a593Smuzhiyun 
932*4882a593Smuzhiyun 	obj_desc->device.gpe_block = gpe_block;
933*4882a593Smuzhiyun 
934*4882a593Smuzhiyun unlock_and_exit:
935*4882a593Smuzhiyun 	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
936*4882a593Smuzhiyun 	return_ACPI_STATUS(status);
937*4882a593Smuzhiyun }
938*4882a593Smuzhiyun 
ACPI_EXPORT_SYMBOL(acpi_install_gpe_block)939*4882a593Smuzhiyun ACPI_EXPORT_SYMBOL(acpi_install_gpe_block)
940*4882a593Smuzhiyun 
941*4882a593Smuzhiyun /*******************************************************************************
942*4882a593Smuzhiyun  *
943*4882a593Smuzhiyun  * FUNCTION:    acpi_remove_gpe_block
944*4882a593Smuzhiyun  *
945*4882a593Smuzhiyun  * PARAMETERS:  gpe_device          - Handle to the parent GPE Block Device
946*4882a593Smuzhiyun  *
947*4882a593Smuzhiyun  * RETURN:      Status
948*4882a593Smuzhiyun  *
949*4882a593Smuzhiyun  * DESCRIPTION: Remove a previously installed block of GPE registers
950*4882a593Smuzhiyun  *
951*4882a593Smuzhiyun  ******************************************************************************/
952*4882a593Smuzhiyun acpi_status acpi_remove_gpe_block(acpi_handle gpe_device)
953*4882a593Smuzhiyun {
954*4882a593Smuzhiyun 	union acpi_operand_object *obj_desc;
955*4882a593Smuzhiyun 	acpi_status status;
956*4882a593Smuzhiyun 	struct acpi_namespace_node *node;
957*4882a593Smuzhiyun 
958*4882a593Smuzhiyun 	ACPI_FUNCTION_TRACE(acpi_remove_gpe_block);
959*4882a593Smuzhiyun 
960*4882a593Smuzhiyun 	if (!gpe_device) {
961*4882a593Smuzhiyun 		return_ACPI_STATUS(AE_BAD_PARAMETER);
962*4882a593Smuzhiyun 	}
963*4882a593Smuzhiyun 
964*4882a593Smuzhiyun 	status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
965*4882a593Smuzhiyun 	if (ACPI_FAILURE(status)) {
966*4882a593Smuzhiyun 		return_ACPI_STATUS(status);
967*4882a593Smuzhiyun 	}
968*4882a593Smuzhiyun 
969*4882a593Smuzhiyun 	node = acpi_ns_validate_handle(gpe_device);
970*4882a593Smuzhiyun 	if (!node) {
971*4882a593Smuzhiyun 		status = AE_BAD_PARAMETER;
972*4882a593Smuzhiyun 		goto unlock_and_exit;
973*4882a593Smuzhiyun 	}
974*4882a593Smuzhiyun 
975*4882a593Smuzhiyun 	/* Validate the parent device */
976*4882a593Smuzhiyun 
977*4882a593Smuzhiyun 	if (node->type != ACPI_TYPE_DEVICE) {
978*4882a593Smuzhiyun 		status = AE_TYPE;
979*4882a593Smuzhiyun 		goto unlock_and_exit;
980*4882a593Smuzhiyun 	}
981*4882a593Smuzhiyun 
982*4882a593Smuzhiyun 	/* Get the device_object attached to the node */
983*4882a593Smuzhiyun 
984*4882a593Smuzhiyun 	obj_desc = acpi_ns_get_attached_object(node);
985*4882a593Smuzhiyun 	if (!obj_desc || !obj_desc->device.gpe_block) {
986*4882a593Smuzhiyun 		return_ACPI_STATUS(AE_NULL_OBJECT);
987*4882a593Smuzhiyun 	}
988*4882a593Smuzhiyun 
989*4882a593Smuzhiyun 	/* Delete the GPE block (but not the device_object) */
990*4882a593Smuzhiyun 
991*4882a593Smuzhiyun 	status = acpi_ev_delete_gpe_block(obj_desc->device.gpe_block);
992*4882a593Smuzhiyun 	if (ACPI_SUCCESS(status)) {
993*4882a593Smuzhiyun 		obj_desc->device.gpe_block = NULL;
994*4882a593Smuzhiyun 	}
995*4882a593Smuzhiyun 
996*4882a593Smuzhiyun unlock_and_exit:
997*4882a593Smuzhiyun 	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
998*4882a593Smuzhiyun 	return_ACPI_STATUS(status);
999*4882a593Smuzhiyun }
1000*4882a593Smuzhiyun 
ACPI_EXPORT_SYMBOL(acpi_remove_gpe_block)1001*4882a593Smuzhiyun ACPI_EXPORT_SYMBOL(acpi_remove_gpe_block)
1002*4882a593Smuzhiyun 
1003*4882a593Smuzhiyun /*******************************************************************************
1004*4882a593Smuzhiyun  *
1005*4882a593Smuzhiyun  * FUNCTION:    acpi_get_gpe_device
1006*4882a593Smuzhiyun  *
1007*4882a593Smuzhiyun  * PARAMETERS:  index               - System GPE index (0-current_gpe_count)
1008*4882a593Smuzhiyun  *              gpe_device          - Where the parent GPE Device is returned
1009*4882a593Smuzhiyun  *
1010*4882a593Smuzhiyun  * RETURN:      Status
1011*4882a593Smuzhiyun  *
1012*4882a593Smuzhiyun  * DESCRIPTION: Obtain the GPE device associated with the input index. A NULL
1013*4882a593Smuzhiyun  *              gpe device indicates that the gpe number is contained in one of
1014*4882a593Smuzhiyun  *              the FADT-defined gpe blocks. Otherwise, the GPE block device.
1015*4882a593Smuzhiyun  *
1016*4882a593Smuzhiyun  ******************************************************************************/
1017*4882a593Smuzhiyun acpi_status acpi_get_gpe_device(u32 index, acpi_handle *gpe_device)
1018*4882a593Smuzhiyun {
1019*4882a593Smuzhiyun 	struct acpi_gpe_device_info info;
1020*4882a593Smuzhiyun 	acpi_status status;
1021*4882a593Smuzhiyun 
1022*4882a593Smuzhiyun 	ACPI_FUNCTION_TRACE(acpi_get_gpe_device);
1023*4882a593Smuzhiyun 
1024*4882a593Smuzhiyun 	if (!gpe_device) {
1025*4882a593Smuzhiyun 		return_ACPI_STATUS(AE_BAD_PARAMETER);
1026*4882a593Smuzhiyun 	}
1027*4882a593Smuzhiyun 
1028*4882a593Smuzhiyun 	if (index >= acpi_current_gpe_count) {
1029*4882a593Smuzhiyun 		return_ACPI_STATUS(AE_NOT_EXIST);
1030*4882a593Smuzhiyun 	}
1031*4882a593Smuzhiyun 
1032*4882a593Smuzhiyun 	/* Setup and walk the GPE list */
1033*4882a593Smuzhiyun 
1034*4882a593Smuzhiyun 	info.index = index;
1035*4882a593Smuzhiyun 	info.status = AE_NOT_EXIST;
1036*4882a593Smuzhiyun 	info.gpe_device = NULL;
1037*4882a593Smuzhiyun 	info.next_block_base_index = 0;
1038*4882a593Smuzhiyun 
1039*4882a593Smuzhiyun 	status = acpi_ev_walk_gpe_list(acpi_ev_get_gpe_device, &info);
1040*4882a593Smuzhiyun 	if (ACPI_FAILURE(status)) {
1041*4882a593Smuzhiyun 		return_ACPI_STATUS(status);
1042*4882a593Smuzhiyun 	}
1043*4882a593Smuzhiyun 
1044*4882a593Smuzhiyun 	*gpe_device = ACPI_CAST_PTR(acpi_handle, info.gpe_device);
1045*4882a593Smuzhiyun 	return_ACPI_STATUS(info.status);
1046*4882a593Smuzhiyun }
1047*4882a593Smuzhiyun 
1048*4882a593Smuzhiyun ACPI_EXPORT_SYMBOL(acpi_get_gpe_device)
1049*4882a593Smuzhiyun #endif				/* !ACPI_REDUCED_HARDWARE */
1050