xref: /openbmc/linux/drivers/acpi/acpica/evxfevnt.c (revision baa7eb025ab14f3cba2e35c0a8648f9c9f01d24f)
1 /******************************************************************************
2  *
3  * Module Name: evxfevnt - External Interfaces, ACPI event disable/enable
4  *
5  *****************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2010, Intel Corp.
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions, and the following disclaimer,
16  *    without modification.
17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18  *    substantially similar to the "NO WARRANTY" disclaimer below
19  *    ("Disclaimer") and any redistribution must be conditioned upon
20  *    including a substantially similar Disclaimer requirement for further
21  *    binary redistribution.
22  * 3. Neither the names of the above-listed copyright holders nor the names
23  *    of any contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * Alternatively, this software may be distributed under the terms of the
27  * GNU General Public License ("GPL") version 2 as published by the Free
28  * Software Foundation.
29  *
30  * NO WARRANTY
31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41  * POSSIBILITY OF SUCH DAMAGES.
42  */
43 
44 #include <acpi/acpi.h>
45 #include "accommon.h"
46 #include "acevents.h"
47 #include "acnamesp.h"
48 #include "actables.h"
49 
50 #define _COMPONENT          ACPI_EVENTS
51 ACPI_MODULE_NAME("evxfevnt")
52 
53 /* Local prototypes */
54 static acpi_status
55 acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
56 		       struct acpi_gpe_block_info *gpe_block, void *context);
57 
58 /*******************************************************************************
59  *
60  * FUNCTION:    acpi_enable
61  *
62  * PARAMETERS:  None
63  *
64  * RETURN:      Status
65  *
66  * DESCRIPTION: Transfers the system into ACPI mode.
67  *
68  ******************************************************************************/
69 
70 acpi_status acpi_enable(void)
71 {
72 	acpi_status status;
73 	int retry;
74 
75 	ACPI_FUNCTION_TRACE(acpi_enable);
76 
77 	/* ACPI tables must be present */
78 
79 	if (!acpi_tb_tables_loaded()) {
80 		return_ACPI_STATUS(AE_NO_ACPI_TABLES);
81 	}
82 
83 	/* Check current mode */
84 
85 	if (acpi_hw_get_mode() == ACPI_SYS_MODE_ACPI) {
86 		ACPI_DEBUG_PRINT((ACPI_DB_INIT,
87 				  "System is already in ACPI mode\n"));
88 		return_ACPI_STATUS(AE_OK);
89 	}
90 
91 	/* Transition to ACPI mode */
92 
93 	status = acpi_hw_set_mode(ACPI_SYS_MODE_ACPI);
94 	if (ACPI_FAILURE(status)) {
95 		ACPI_ERROR((AE_INFO,
96 			    "Could not transition to ACPI mode"));
97 		return_ACPI_STATUS(status);
98 	}
99 
100 	/* Sanity check that transition succeeded */
101 
102 	for (retry = 0; retry < 30000; ++retry) {
103 		if (acpi_hw_get_mode() == ACPI_SYS_MODE_ACPI) {
104 			if (retry != 0)
105 				ACPI_WARNING((AE_INFO,
106 				"Platform took > %d00 usec to enter ACPI mode", retry));
107 			return_ACPI_STATUS(AE_OK);
108 		}
109 		acpi_os_stall(100);	/* 100 usec */
110 	}
111 
112 	ACPI_ERROR((AE_INFO, "Hardware did not enter ACPI mode"));
113 	return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE);
114 }
115 
116 ACPI_EXPORT_SYMBOL(acpi_enable)
117 
118 /*******************************************************************************
119  *
120  * FUNCTION:    acpi_disable
121  *
122  * PARAMETERS:  None
123  *
124  * RETURN:      Status
125  *
126  * DESCRIPTION: Transfers the system into LEGACY (non-ACPI) mode.
127  *
128  ******************************************************************************/
129 acpi_status acpi_disable(void)
130 {
131 	acpi_status status = AE_OK;
132 
133 	ACPI_FUNCTION_TRACE(acpi_disable);
134 
135 	if (acpi_hw_get_mode() == ACPI_SYS_MODE_LEGACY) {
136 		ACPI_DEBUG_PRINT((ACPI_DB_INIT,
137 				  "System is already in legacy (non-ACPI) mode\n"));
138 	} else {
139 		/* Transition to LEGACY mode */
140 
141 		status = acpi_hw_set_mode(ACPI_SYS_MODE_LEGACY);
142 
143 		if (ACPI_FAILURE(status)) {
144 			ACPI_ERROR((AE_INFO,
145 				    "Could not exit ACPI mode to legacy mode"));
146 			return_ACPI_STATUS(status);
147 		}
148 
149 		ACPI_DEBUG_PRINT((ACPI_DB_INIT, "ACPI mode disabled\n"));
150 	}
151 
152 	return_ACPI_STATUS(status);
153 }
154 
155 ACPI_EXPORT_SYMBOL(acpi_disable)
156 
157 /*******************************************************************************
158  *
159  * FUNCTION:    acpi_enable_event
160  *
161  * PARAMETERS:  Event           - The fixed eventto be enabled
162  *              Flags           - Reserved
163  *
164  * RETURN:      Status
165  *
166  * DESCRIPTION: Enable an ACPI event (fixed)
167  *
168  ******************************************************************************/
169 acpi_status acpi_enable_event(u32 event, u32 flags)
170 {
171 	acpi_status status = AE_OK;
172 	u32 value;
173 
174 	ACPI_FUNCTION_TRACE(acpi_enable_event);
175 
176 	/* Decode the Fixed Event */
177 
178 	if (event > ACPI_EVENT_MAX) {
179 		return_ACPI_STATUS(AE_BAD_PARAMETER);
180 	}
181 
182 	/*
183 	 * Enable the requested fixed event (by writing a one to the enable
184 	 * register bit)
185 	 */
186 	status =
187 	    acpi_write_bit_register(acpi_gbl_fixed_event_info[event].
188 				    enable_register_id, ACPI_ENABLE_EVENT);
189 	if (ACPI_FAILURE(status)) {
190 		return_ACPI_STATUS(status);
191 	}
192 
193 	/* Make sure that the hardware responded */
194 
195 	status =
196 	    acpi_read_bit_register(acpi_gbl_fixed_event_info[event].
197 				   enable_register_id, &value);
198 	if (ACPI_FAILURE(status)) {
199 		return_ACPI_STATUS(status);
200 	}
201 
202 	if (value != 1) {
203 		ACPI_ERROR((AE_INFO,
204 			    "Could not enable %s event",
205 			    acpi_ut_get_event_name(event)));
206 		return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE);
207 	}
208 
209 	return_ACPI_STATUS(status);
210 }
211 
212 ACPI_EXPORT_SYMBOL(acpi_enable_event)
213 
214 /*******************************************************************************
215  *
216  * FUNCTION:    acpi_gpe_wakeup
217  *
218  * PARAMETERS:  gpe_device      - Parent GPE Device. NULL for GPE0/GPE1
219  *              gpe_number      - GPE level within the GPE block
220  *              Action          - Enable or Disable
221  *
222  * RETURN:      Status
223  *
224  * DESCRIPTION: Set or clear the GPE's wakeup enable mask bit.
225  *
226  ******************************************************************************/
227 acpi_status acpi_gpe_wakeup(acpi_handle gpe_device, u32 gpe_number, u8 action)
228 {
229 	acpi_status status = AE_OK;
230 	struct acpi_gpe_event_info *gpe_event_info;
231 	struct acpi_gpe_register_info *gpe_register_info;
232 	acpi_cpu_flags flags;
233 	u32 register_bit;
234 
235 	ACPI_FUNCTION_TRACE(acpi_gpe_wakeup);
236 
237 	flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
238 
239 	/* Ensure that we have a valid GPE number */
240 
241 	gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
242 	if (!gpe_event_info || !(gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) {
243 		status = AE_BAD_PARAMETER;
244 		goto unlock_and_exit;
245 	}
246 
247 	gpe_register_info = gpe_event_info->register_info;
248 	if (!gpe_register_info) {
249 		status = AE_NOT_EXIST;
250 		goto unlock_and_exit;
251 	}
252 
253 	register_bit =
254 	    acpi_hw_get_gpe_register_bit(gpe_event_info, gpe_register_info);
255 
256 	/* Perform the action */
257 
258 	switch (action) {
259 	case ACPI_GPE_ENABLE:
260 		ACPI_SET_BIT(gpe_register_info->enable_for_wake,
261 			     (u8)register_bit);
262 		break;
263 
264 	case ACPI_GPE_DISABLE:
265 		ACPI_CLEAR_BIT(gpe_register_info->enable_for_wake,
266 			       (u8)register_bit);
267 		break;
268 
269 	default:
270 		ACPI_ERROR((AE_INFO, "%u, Invalid action", action));
271 		status = AE_BAD_PARAMETER;
272 		break;
273 	}
274 
275 unlock_and_exit:
276 	acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
277 	return_ACPI_STATUS(status);
278 }
279 
280 ACPI_EXPORT_SYMBOL(acpi_gpe_wakeup)
281 
282 /*******************************************************************************
283  *
284  * FUNCTION:    acpi_enable_gpe
285  *
286  * PARAMETERS:  gpe_device      - Parent GPE Device. NULL for GPE0/GPE1
287  *              gpe_number      - GPE level within the GPE block
288  *
289  * RETURN:      Status
290  *
291  * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is
292  *              hardware-enabled.
293  *
294  ******************************************************************************/
295 acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number)
296 {
297 	acpi_status status = AE_BAD_PARAMETER;
298 	struct acpi_gpe_event_info *gpe_event_info;
299 	acpi_cpu_flags flags;
300 
301 	ACPI_FUNCTION_TRACE(acpi_enable_gpe);
302 
303 	flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
304 
305 	/* Ensure that we have a valid GPE number */
306 
307 	gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
308 	if (gpe_event_info) {
309 		status = acpi_raw_enable_gpe(gpe_event_info);
310 	}
311 
312 	acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
313 	return_ACPI_STATUS(status);
314 }
315 ACPI_EXPORT_SYMBOL(acpi_enable_gpe)
316 
317 /*******************************************************************************
318  *
319  * FUNCTION:    acpi_disable_gpe
320  *
321  * PARAMETERS:  gpe_device      - Parent GPE Device. NULL for GPE0/GPE1
322  *              gpe_number      - GPE level within the GPE block
323  *
324  * RETURN:      Status
325  *
326  * DESCRIPTION: Remove a reference to a GPE. When the last reference is
327  *              removed, only then is the GPE disabled (for runtime GPEs), or
328  *              the GPE mask bit disabled (for wake GPEs)
329  *
330  ******************************************************************************/
331 acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number)
332 {
333 	acpi_status status = AE_BAD_PARAMETER;
334 	struct acpi_gpe_event_info *gpe_event_info;
335 	acpi_cpu_flags flags;
336 
337 	ACPI_FUNCTION_TRACE(acpi_disable_gpe);
338 
339 	flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
340 
341 	/* Ensure that we have a valid GPE number */
342 
343 	gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
344 	if (gpe_event_info) {
345 		status = acpi_raw_disable_gpe(gpe_event_info) ;
346 	}
347 
348 	acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
349 	return_ACPI_STATUS(status);
350 }
351 ACPI_EXPORT_SYMBOL(acpi_disable_gpe)
352 
353 /*******************************************************************************
354  *
355  * FUNCTION:    acpi_gpe_can_wake
356  *
357  * PARAMETERS:  gpe_device      - Parent GPE Device. NULL for GPE0/GPE1
358  *              gpe_number      - GPE level within the GPE block
359  *
360  * RETURN:      Status
361  *
362  * DESCRIPTION: Set the ACPI_GPE_CAN_WAKE flag for the given GPE.  If the GPE
363  *              has a corresponding method and is currently enabled, disable it
364  *              (GPEs with corresponding methods are enabled unconditionally
365  *              during initialization, but GPEs that can wake up are expected
366  *              to be initially disabled).
367  *
368  ******************************************************************************/
369 acpi_status acpi_gpe_can_wake(acpi_handle gpe_device, u32 gpe_number)
370 {
371 	acpi_status status = AE_OK;
372 	struct acpi_gpe_event_info *gpe_event_info;
373 	acpi_cpu_flags flags;
374 
375 	ACPI_FUNCTION_TRACE(acpi_gpe_can_wake);
376 
377 	flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
378 
379 	/* Ensure that we have a valid GPE number */
380 
381 	gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
382 	if (gpe_event_info) {
383 		gpe_event_info->flags |= ACPI_GPE_CAN_WAKE;
384 	} else {
385 		status = AE_BAD_PARAMETER;
386 	}
387 
388 	acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
389 	return_ACPI_STATUS(status);
390 }
391 ACPI_EXPORT_SYMBOL(acpi_gpe_can_wake)
392 
393 /*******************************************************************************
394  *
395  * FUNCTION:    acpi_disable_event
396  *
397  * PARAMETERS:  Event           - The fixed eventto be enabled
398  *              Flags           - Reserved
399  *
400  * RETURN:      Status
401  *
402  * DESCRIPTION: Disable an ACPI event (fixed)
403  *
404  ******************************************************************************/
405 acpi_status acpi_disable_event(u32 event, u32 flags)
406 {
407 	acpi_status status = AE_OK;
408 	u32 value;
409 
410 	ACPI_FUNCTION_TRACE(acpi_disable_event);
411 
412 	/* Decode the Fixed Event */
413 
414 	if (event > ACPI_EVENT_MAX) {
415 		return_ACPI_STATUS(AE_BAD_PARAMETER);
416 	}
417 
418 	/*
419 	 * Disable the requested fixed event (by writing a zero to the enable
420 	 * register bit)
421 	 */
422 	status =
423 	    acpi_write_bit_register(acpi_gbl_fixed_event_info[event].
424 				    enable_register_id, ACPI_DISABLE_EVENT);
425 	if (ACPI_FAILURE(status)) {
426 		return_ACPI_STATUS(status);
427 	}
428 
429 	status =
430 	    acpi_read_bit_register(acpi_gbl_fixed_event_info[event].
431 				   enable_register_id, &value);
432 	if (ACPI_FAILURE(status)) {
433 		return_ACPI_STATUS(status);
434 	}
435 
436 	if (value != 0) {
437 		ACPI_ERROR((AE_INFO,
438 			    "Could not disable %s events",
439 			    acpi_ut_get_event_name(event)));
440 		return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE);
441 	}
442 
443 	return_ACPI_STATUS(status);
444 }
445 
446 ACPI_EXPORT_SYMBOL(acpi_disable_event)
447 
448 /*******************************************************************************
449  *
450  * FUNCTION:    acpi_clear_event
451  *
452  * PARAMETERS:  Event           - The fixed event to be cleared
453  *
454  * RETURN:      Status
455  *
456  * DESCRIPTION: Clear an ACPI event (fixed)
457  *
458  ******************************************************************************/
459 acpi_status acpi_clear_event(u32 event)
460 {
461 	acpi_status status = AE_OK;
462 
463 	ACPI_FUNCTION_TRACE(acpi_clear_event);
464 
465 	/* Decode the Fixed Event */
466 
467 	if (event > ACPI_EVENT_MAX) {
468 		return_ACPI_STATUS(AE_BAD_PARAMETER);
469 	}
470 
471 	/*
472 	 * Clear the requested fixed event (By writing a one to the status
473 	 * register bit)
474 	 */
475 	status =
476 	    acpi_write_bit_register(acpi_gbl_fixed_event_info[event].
477 				    status_register_id, ACPI_CLEAR_STATUS);
478 
479 	return_ACPI_STATUS(status);
480 }
481 
482 ACPI_EXPORT_SYMBOL(acpi_clear_event)
483 
484 /*******************************************************************************
485  *
486  * FUNCTION:    acpi_clear_gpe
487  *
488  * PARAMETERS:  gpe_device      - Parent GPE Device. NULL for GPE0/GPE1
489  *              gpe_number      - GPE level within the GPE block
490  *
491  * RETURN:      Status
492  *
493  * DESCRIPTION: Clear an ACPI event (general purpose)
494  *
495  ******************************************************************************/
496 acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number)
497 {
498 	acpi_status status = AE_OK;
499 	struct acpi_gpe_event_info *gpe_event_info;
500 	acpi_cpu_flags flags;
501 
502 	ACPI_FUNCTION_TRACE(acpi_clear_gpe);
503 
504 	flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
505 
506 	/* Ensure that we have a valid GPE number */
507 
508 	gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
509 	if (!gpe_event_info) {
510 		status = AE_BAD_PARAMETER;
511 		goto unlock_and_exit;
512 	}
513 
514 	status = acpi_hw_clear_gpe(gpe_event_info);
515 
516       unlock_and_exit:
517 	acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
518 	return_ACPI_STATUS(status);
519 }
520 
521 ACPI_EXPORT_SYMBOL(acpi_clear_gpe)
522 /*******************************************************************************
523  *
524  * FUNCTION:    acpi_get_event_status
525  *
526  * PARAMETERS:  Event           - The fixed event
527  *              event_status    - Where the current status of the event will
528  *                                be returned
529  *
530  * RETURN:      Status
531  *
532  * DESCRIPTION: Obtains and returns the current status of the event
533  *
534  ******************************************************************************/
535 acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status)
536 {
537 	acpi_status status = AE_OK;
538 	u32 value;
539 
540 	ACPI_FUNCTION_TRACE(acpi_get_event_status);
541 
542 	if (!event_status) {
543 		return_ACPI_STATUS(AE_BAD_PARAMETER);
544 	}
545 
546 	/* Decode the Fixed Event */
547 
548 	if (event > ACPI_EVENT_MAX) {
549 		return_ACPI_STATUS(AE_BAD_PARAMETER);
550 	}
551 
552 	/* Get the status of the requested fixed event */
553 
554 	status =
555 	    acpi_read_bit_register(acpi_gbl_fixed_event_info[event].
556 			      enable_register_id, &value);
557 	if (ACPI_FAILURE(status))
558 		return_ACPI_STATUS(status);
559 
560 	*event_status = value;
561 
562 	status =
563 	    acpi_read_bit_register(acpi_gbl_fixed_event_info[event].
564 			      status_register_id, &value);
565 	if (ACPI_FAILURE(status))
566 		return_ACPI_STATUS(status);
567 
568 	if (value)
569 		*event_status |= ACPI_EVENT_FLAG_SET;
570 
571 	if (acpi_gbl_fixed_event_handlers[event].handler)
572 		*event_status |= ACPI_EVENT_FLAG_HANDLE;
573 
574 	return_ACPI_STATUS(status);
575 }
576 
577 ACPI_EXPORT_SYMBOL(acpi_get_event_status)
578 
579 /*******************************************************************************
580  *
581  * FUNCTION:    acpi_get_gpe_status
582  *
583  * PARAMETERS:  gpe_device      - Parent GPE Device. NULL for GPE0/GPE1
584  *              gpe_number      - GPE level within the GPE block
585  *              event_status    - Where the current status of the event will
586  *                                be returned
587  *
588  * RETURN:      Status
589  *
590  * DESCRIPTION: Get status of an event (general purpose)
591  *
592  ******************************************************************************/
593 acpi_status
594 acpi_get_gpe_status(acpi_handle gpe_device,
595 		    u32 gpe_number, acpi_event_status *event_status)
596 {
597 	acpi_status status = AE_OK;
598 	struct acpi_gpe_event_info *gpe_event_info;
599 	acpi_cpu_flags flags;
600 
601 	ACPI_FUNCTION_TRACE(acpi_get_gpe_status);
602 
603 	flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
604 
605 	/* Ensure that we have a valid GPE number */
606 
607 	gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
608 	if (!gpe_event_info) {
609 		status = AE_BAD_PARAMETER;
610 		goto unlock_and_exit;
611 	}
612 
613 	/* Obtain status on the requested GPE number */
614 
615 	status = acpi_hw_get_gpe_status(gpe_event_info, event_status);
616 
617 	if (gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK)
618 		*event_status |= ACPI_EVENT_FLAG_HANDLE;
619 
620       unlock_and_exit:
621 	acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
622 	return_ACPI_STATUS(status);
623 }
624 
625 ACPI_EXPORT_SYMBOL(acpi_get_gpe_status)
626 /*******************************************************************************
627  *
628  * FUNCTION:    acpi_install_gpe_block
629  *
630  * PARAMETERS:  gpe_device          - Handle to the parent GPE Block Device
631  *              gpe_block_address   - Address and space_iD
632  *              register_count      - Number of GPE register pairs in the block
633  *              interrupt_number    - H/W interrupt for the block
634  *
635  * RETURN:      Status
636  *
637  * DESCRIPTION: Create and Install a block of GPE registers
638  *
639  ******************************************************************************/
640 acpi_status
641 acpi_install_gpe_block(acpi_handle gpe_device,
642 		       struct acpi_generic_address *gpe_block_address,
643 		       u32 register_count, u32 interrupt_number)
644 {
645 	acpi_status status = AE_OK;
646 	union acpi_operand_object *obj_desc;
647 	struct acpi_namespace_node *node;
648 	struct acpi_gpe_block_info *gpe_block;
649 
650 	ACPI_FUNCTION_TRACE(acpi_install_gpe_block);
651 
652 	if ((!gpe_device) || (!gpe_block_address) || (!register_count)) {
653 		return_ACPI_STATUS(AE_BAD_PARAMETER);
654 	}
655 
656 	status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
657 	if (ACPI_FAILURE(status)) {
658 		return (status);
659 	}
660 
661 	node = acpi_ns_validate_handle(gpe_device);
662 	if (!node) {
663 		status = AE_BAD_PARAMETER;
664 		goto unlock_and_exit;
665 	}
666 
667 	/*
668 	 * For user-installed GPE Block Devices, the gpe_block_base_number
669 	 * is always zero
670 	 */
671 	status =
672 	    acpi_ev_create_gpe_block(node, gpe_block_address, register_count, 0,
673 				     interrupt_number, &gpe_block);
674 	if (ACPI_FAILURE(status)) {
675 		goto unlock_and_exit;
676 	}
677 
678 	/* Install block in the device_object attached to the node */
679 
680 	obj_desc = acpi_ns_get_attached_object(node);
681 	if (!obj_desc) {
682 
683 		/*
684 		 * No object, create a new one (Device nodes do not always have
685 		 * an attached object)
686 		 */
687 		obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_DEVICE);
688 		if (!obj_desc) {
689 			status = AE_NO_MEMORY;
690 			goto unlock_and_exit;
691 		}
692 
693 		status =
694 		    acpi_ns_attach_object(node, obj_desc, ACPI_TYPE_DEVICE);
695 
696 		/* Remove local reference to the object */
697 
698 		acpi_ut_remove_reference(obj_desc);
699 
700 		if (ACPI_FAILURE(status)) {
701 			goto unlock_and_exit;
702 		}
703 	}
704 
705 	/* Now install the GPE block in the device_object */
706 
707 	obj_desc->device.gpe_block = gpe_block;
708 
709       unlock_and_exit:
710 	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
711 	return_ACPI_STATUS(status);
712 }
713 
714 ACPI_EXPORT_SYMBOL(acpi_install_gpe_block)
715 
716 /*******************************************************************************
717  *
718  * FUNCTION:    acpi_remove_gpe_block
719  *
720  * PARAMETERS:  gpe_device          - Handle to the parent GPE Block Device
721  *
722  * RETURN:      Status
723  *
724  * DESCRIPTION: Remove a previously installed block of GPE registers
725  *
726  ******************************************************************************/
727 acpi_status acpi_remove_gpe_block(acpi_handle gpe_device)
728 {
729 	union acpi_operand_object *obj_desc;
730 	acpi_status status;
731 	struct acpi_namespace_node *node;
732 
733 	ACPI_FUNCTION_TRACE(acpi_remove_gpe_block);
734 
735 	if (!gpe_device) {
736 		return_ACPI_STATUS(AE_BAD_PARAMETER);
737 	}
738 
739 	status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
740 	if (ACPI_FAILURE(status)) {
741 		return (status);
742 	}
743 
744 	node = acpi_ns_validate_handle(gpe_device);
745 	if (!node) {
746 		status = AE_BAD_PARAMETER;
747 		goto unlock_and_exit;
748 	}
749 
750 	/* Get the device_object attached to the node */
751 
752 	obj_desc = acpi_ns_get_attached_object(node);
753 	if (!obj_desc || !obj_desc->device.gpe_block) {
754 		return_ACPI_STATUS(AE_NULL_OBJECT);
755 	}
756 
757 	/* Delete the GPE block (but not the device_object) */
758 
759 	status = acpi_ev_delete_gpe_block(obj_desc->device.gpe_block);
760 	if (ACPI_SUCCESS(status)) {
761 		obj_desc->device.gpe_block = NULL;
762 	}
763 
764       unlock_and_exit:
765 	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
766 	return_ACPI_STATUS(status);
767 }
768 
769 ACPI_EXPORT_SYMBOL(acpi_remove_gpe_block)
770 
771 /*******************************************************************************
772  *
773  * FUNCTION:    acpi_get_gpe_device
774  *
775  * PARAMETERS:  Index               - System GPE index (0-current_gpe_count)
776  *              gpe_device          - Where the parent GPE Device is returned
777  *
778  * RETURN:      Status
779  *
780  * DESCRIPTION: Obtain the GPE device associated with the input index. A NULL
781  *              gpe device indicates that the gpe number is contained in one of
782  *              the FADT-defined gpe blocks. Otherwise, the GPE block device.
783  *
784  ******************************************************************************/
785 acpi_status
786 acpi_get_gpe_device(u32 index, acpi_handle *gpe_device)
787 {
788 	struct acpi_gpe_device_info info;
789 	acpi_status status;
790 
791 	ACPI_FUNCTION_TRACE(acpi_get_gpe_device);
792 
793 	if (!gpe_device) {
794 		return_ACPI_STATUS(AE_BAD_PARAMETER);
795 	}
796 
797 	if (index >= acpi_current_gpe_count) {
798 		return_ACPI_STATUS(AE_NOT_EXIST);
799 	}
800 
801 	/* Setup and walk the GPE list */
802 
803 	info.index = index;
804 	info.status = AE_NOT_EXIST;
805 	info.gpe_device = NULL;
806 	info.next_block_base_index = 0;
807 
808 	status = acpi_ev_walk_gpe_list(acpi_ev_get_gpe_device, &info);
809 	if (ACPI_FAILURE(status)) {
810 		return_ACPI_STATUS(status);
811 	}
812 
813 	*gpe_device = info.gpe_device;
814 	return_ACPI_STATUS(info.status);
815 }
816 
817 ACPI_EXPORT_SYMBOL(acpi_get_gpe_device)
818 
819 /*******************************************************************************
820  *
821  * FUNCTION:    acpi_ev_get_gpe_device
822  *
823  * PARAMETERS:  GPE_WALK_CALLBACK
824  *
825  * RETURN:      Status
826  *
827  * DESCRIPTION: Matches the input GPE index (0-current_gpe_count) with a GPE
828  *              block device. NULL if the GPE is one of the FADT-defined GPEs.
829  *
830  ******************************************************************************/
831 static acpi_status
832 acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
833 		       struct acpi_gpe_block_info *gpe_block, void *context)
834 {
835 	struct acpi_gpe_device_info *info = context;
836 
837 	/* Increment Index by the number of GPEs in this block */
838 
839 	info->next_block_base_index += gpe_block->gpe_count;
840 
841 	if (info->index < info->next_block_base_index) {
842 		/*
843 		 * The GPE index is within this block, get the node. Leave the node
844 		 * NULL for the FADT-defined GPEs
845 		 */
846 		if ((gpe_block->node)->type == ACPI_TYPE_DEVICE) {
847 			info->gpe_device = gpe_block->node;
848 		}
849 
850 		info->status = AE_OK;
851 		return (AE_CTRL_END);
852 	}
853 
854 	return (AE_OK);
855 }
856 
857 /******************************************************************************
858  *
859  * FUNCTION:    acpi_disable_all_gpes
860  *
861  * PARAMETERS:  None
862  *
863  * RETURN:      Status
864  *
865  * DESCRIPTION: Disable and clear all GPEs in all GPE blocks
866  *
867  ******************************************************************************/
868 
869 acpi_status acpi_disable_all_gpes(void)
870 {
871 	acpi_status status;
872 
873 	ACPI_FUNCTION_TRACE(acpi_disable_all_gpes);
874 
875 	status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
876 	if (ACPI_FAILURE(status)) {
877 		return_ACPI_STATUS(status);
878 	}
879 
880 	status = acpi_hw_disable_all_gpes();
881 	(void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
882 
883 	return_ACPI_STATUS(status);
884 }
885 
886 /******************************************************************************
887  *
888  * FUNCTION:    acpi_enable_all_runtime_gpes
889  *
890  * PARAMETERS:  None
891  *
892  * RETURN:      Status
893  *
894  * DESCRIPTION: Enable all "runtime" GPEs, in all GPE blocks
895  *
896  ******************************************************************************/
897 
898 acpi_status acpi_enable_all_runtime_gpes(void)
899 {
900 	acpi_status status;
901 
902 	ACPI_FUNCTION_TRACE(acpi_enable_all_runtime_gpes);
903 
904 	status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
905 	if (ACPI_FAILURE(status)) {
906 		return_ACPI_STATUS(status);
907 	}
908 
909 	status = acpi_hw_enable_all_runtime_gpes();
910 	(void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
911 
912 	return_ACPI_STATUS(status);
913 }
914 
915 /******************************************************************************
916  *
917  * FUNCTION:    acpi_update_gpes
918  *
919  * PARAMETERS:  None
920  *
921  * RETURN:      None
922  *
923  * DESCRIPTION: Enable all GPEs that have associated _Lxx or _Exx methods and
924  *              are not pointed to by any device _PRW methods indicating that
925  *              these GPEs are generally intended for system or device wakeup
926  *              (such GPEs have to be enabled directly when the devices whose
927  *              _PRW methods point to them are set up for wakeup signaling).
928  *
929  ******************************************************************************/
930 
931 acpi_status acpi_update_gpes(void)
932 {
933 	acpi_status status;
934 
935 	ACPI_FUNCTION_TRACE(acpi_update_gpes);
936 
937 	status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
938 	if (ACPI_FAILURE(status)) {
939 		return_ACPI_STATUS(status);
940 	} else if (acpi_all_gpes_initialized) {
941 		goto unlock;
942 	}
943 
944 	status = acpi_ev_walk_gpe_list(acpi_ev_initialize_gpe_block, NULL);
945 	if (ACPI_SUCCESS(status)) {
946 		acpi_all_gpes_initialized = TRUE;
947 	}
948 
949 unlock:
950 	(void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
951 
952 	return_ACPI_STATUS(status);
953 }
954