1 /******************************************************************************
3 * Module Name: evxfevnt - External Interfaces, ACPI event disable/enable
5 *****************************************************************************/
8 * Copyright (C) 2000 - 2006, R. Byron Moore
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
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.
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.
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.
44 #include <acpi/acpi.h>
45 #include <acpi/acevents.h>
46 #include <acpi/acnamesp.h>
48 #define _COMPONENT ACPI_EVENTS
49 ACPI_MODULE_NAME("evxfevnt")
51 /*******************************************************************************
53 * FUNCTION: acpi_enable
59 * DESCRIPTION: Transfers the system into ACPI mode.
61 ******************************************************************************/
62 acpi_status acpi_enable(void)
64 acpi_status status = AE_OK;
66 ACPI_FUNCTION_TRACE(acpi_enable);
68 if (acpi_hw_get_mode() == ACPI_SYS_MODE_ACPI) {
69 ACPI_DEBUG_PRINT((ACPI_DB_INIT,
70 "System is already in ACPI mode\n"));
72 /* Transition to ACPI mode */
74 status = acpi_hw_set_mode(ACPI_SYS_MODE_ACPI);
75 if (ACPI_FAILURE(status)) {
77 "Could not transition to ACPI mode"));
78 return_ACPI_STATUS(status);
81 ACPI_DEBUG_PRINT((ACPI_DB_INIT,
82 "Transition to ACPI mode successful\n"));
85 return_ACPI_STATUS(status);
88 ACPI_EXPORT_SYMBOL(acpi_enable)
90 /*******************************************************************************
92 * FUNCTION: acpi_disable
98 * DESCRIPTION: Transfers the system into LEGACY (non-ACPI) mode.
100 ******************************************************************************/
101 acpi_status acpi_disable(void)
103 acpi_status status = AE_OK;
105 ACPI_FUNCTION_TRACE(acpi_disable);
107 if (acpi_hw_get_mode() == ACPI_SYS_MODE_LEGACY) {
108 ACPI_DEBUG_PRINT((ACPI_DB_INIT,
109 "System is already in legacy (non-ACPI) mode\n"));
111 /* Transition to LEGACY mode */
113 status = acpi_hw_set_mode(ACPI_SYS_MODE_LEGACY);
115 if (ACPI_FAILURE(status)) {
117 "Could not exit ACPI mode to legacy mode"));
118 return_ACPI_STATUS(status);
121 ACPI_DEBUG_PRINT((ACPI_DB_INIT, "ACPI mode disabled\n"));
124 return_ACPI_STATUS(status);
127 ACPI_EXPORT_SYMBOL(acpi_disable)
129 /*******************************************************************************
131 * FUNCTION: acpi_enable_event
133 * PARAMETERS: Event - The fixed eventto be enabled
138 * DESCRIPTION: Enable an ACPI event (fixed)
140 ******************************************************************************/
141 acpi_status acpi_enable_event(u32 event, u32 flags)
143 acpi_status status = AE_OK;
146 ACPI_FUNCTION_TRACE(acpi_enable_event);
148 /* Decode the Fixed Event */
150 if (event > ACPI_EVENT_MAX) {
151 return_ACPI_STATUS(AE_BAD_PARAMETER);
155 * Enable the requested fixed event (by writing a one to the
156 * enable register bit)
159 acpi_set_register(acpi_gbl_fixed_event_info[event].
160 enable_register_id, 1);
161 if (ACPI_FAILURE(status)) {
162 return_ACPI_STATUS(status);
165 /* Make sure that the hardware responded */
168 acpi_get_register(acpi_gbl_fixed_event_info[event].
169 enable_register_id, &value);
170 if (ACPI_FAILURE(status)) {
171 return_ACPI_STATUS(status);
176 "Could not enable %s event",
177 acpi_ut_get_event_name(event)));
178 return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE);
181 return_ACPI_STATUS(status);
184 ACPI_EXPORT_SYMBOL(acpi_enable_event)
186 /*******************************************************************************
188 * FUNCTION: acpi_set_gpe_type
190 * PARAMETERS: gpe_device - Parent GPE Device
191 * gpe_number - GPE level within the GPE block
192 * Type - New GPE type
196 * DESCRIPTION: Set the type of an individual GPE
198 ******************************************************************************/
199 acpi_status acpi_set_gpe_type(acpi_handle gpe_device, u32 gpe_number, u8 type)
201 acpi_status status = AE_OK;
202 struct acpi_gpe_event_info *gpe_event_info;
204 ACPI_FUNCTION_TRACE(acpi_set_gpe_type);
206 /* Ensure that we have a valid GPE number */
208 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
209 if (!gpe_event_info) {
210 status = AE_BAD_PARAMETER;
211 goto unlock_and_exit;
214 if ((gpe_event_info->flags & ACPI_GPE_TYPE_MASK) == type) {
215 return_ACPI_STATUS(AE_OK);
218 /* Set the new type (will disable GPE if currently enabled) */
220 status = acpi_ev_set_gpe_type(gpe_event_info, type);
223 return_ACPI_STATUS(status);
226 ACPI_EXPORT_SYMBOL(acpi_set_gpe_type)
228 /*******************************************************************************
230 * FUNCTION: acpi_enable_gpe
232 * PARAMETERS: gpe_device - Parent GPE Device
233 * gpe_number - GPE level within the GPE block
234 * Flags - Just enable, or also wake enable?
235 * Called from ISR or not
239 * DESCRIPTION: Enable an ACPI event (general purpose)
241 ******************************************************************************/
242 acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags)
244 acpi_status status = AE_OK;
245 struct acpi_gpe_event_info *gpe_event_info;
247 ACPI_FUNCTION_TRACE(acpi_enable_gpe);
249 /* Use semaphore lock if not executing at interrupt level */
251 if (flags & ACPI_NOT_ISR) {
252 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
253 if (ACPI_FAILURE(status)) {
254 return_ACPI_STATUS(status);
258 /* Ensure that we have a valid GPE number */
260 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
261 if (!gpe_event_info) {
262 status = AE_BAD_PARAMETER;
263 goto unlock_and_exit;
266 /* Perform the enable */
268 status = acpi_ev_enable_gpe(gpe_event_info, TRUE);
271 if (flags & ACPI_NOT_ISR) {
272 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
274 return_ACPI_STATUS(status);
277 ACPI_EXPORT_SYMBOL(acpi_enable_gpe)
279 /*******************************************************************************
281 * FUNCTION: acpi_disable_gpe
283 * PARAMETERS: gpe_device - Parent GPE Device
284 * gpe_number - GPE level within the GPE block
285 * Flags - Just disable, or also wake disable?
286 * Called from ISR or not
290 * DESCRIPTION: Disable an ACPI event (general purpose)
292 ******************************************************************************/
293 acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags)
295 acpi_status status = AE_OK;
296 struct acpi_gpe_event_info *gpe_event_info;
298 ACPI_FUNCTION_TRACE(acpi_disable_gpe);
300 /* Use semaphore lock if not executing at interrupt level */
302 if (flags & ACPI_NOT_ISR) {
303 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
304 if (ACPI_FAILURE(status)) {
305 return_ACPI_STATUS(status);
309 /* Ensure that we have a valid GPE number */
311 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
312 if (!gpe_event_info) {
313 status = AE_BAD_PARAMETER;
314 goto unlock_and_exit;
317 status = acpi_ev_disable_gpe(gpe_event_info);
320 if (flags & ACPI_NOT_ISR) {
321 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
323 return_ACPI_STATUS(status);
326 ACPI_EXPORT_SYMBOL(acpi_disable_gpe)
328 /*******************************************************************************
330 * FUNCTION: acpi_disable_event
332 * PARAMETERS: Event - The fixed eventto be enabled
337 * DESCRIPTION: Disable an ACPI event (fixed)
339 ******************************************************************************/
340 acpi_status acpi_disable_event(u32 event, u32 flags)
342 acpi_status status = AE_OK;
345 ACPI_FUNCTION_TRACE(acpi_disable_event);
347 /* Decode the Fixed Event */
349 if (event > ACPI_EVENT_MAX) {
350 return_ACPI_STATUS(AE_BAD_PARAMETER);
354 * Disable the requested fixed event (by writing a zero to the
355 * enable register bit)
358 acpi_set_register(acpi_gbl_fixed_event_info[event].
359 enable_register_id, 0);
360 if (ACPI_FAILURE(status)) {
361 return_ACPI_STATUS(status);
365 acpi_get_register(acpi_gbl_fixed_event_info[event].
366 enable_register_id, &value);
367 if (ACPI_FAILURE(status)) {
368 return_ACPI_STATUS(status);
373 "Could not disable %s events",
374 acpi_ut_get_event_name(event)));
375 return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE);
378 return_ACPI_STATUS(status);
381 ACPI_EXPORT_SYMBOL(acpi_disable_event)
383 /*******************************************************************************
385 * FUNCTION: acpi_clear_event
387 * PARAMETERS: Event - The fixed event to be cleared
391 * DESCRIPTION: Clear an ACPI event (fixed)
393 ******************************************************************************/
394 acpi_status acpi_clear_event(u32 event)
396 acpi_status status = AE_OK;
398 ACPI_FUNCTION_TRACE(acpi_clear_event);
400 /* Decode the Fixed Event */
402 if (event > ACPI_EVENT_MAX) {
403 return_ACPI_STATUS(AE_BAD_PARAMETER);
407 * Clear the requested fixed event (By writing a one to the
408 * status register bit)
411 acpi_set_register(acpi_gbl_fixed_event_info[event].
412 status_register_id, 1);
414 return_ACPI_STATUS(status);
417 ACPI_EXPORT_SYMBOL(acpi_clear_event)
419 /*******************************************************************************
421 * FUNCTION: acpi_clear_gpe
423 * PARAMETERS: gpe_device - Parent GPE Device
424 * gpe_number - GPE level within the GPE block
425 * Flags - Called from an ISR or not
429 * DESCRIPTION: Clear an ACPI event (general purpose)
431 ******************************************************************************/
432 acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags)
434 acpi_status status = AE_OK;
435 struct acpi_gpe_event_info *gpe_event_info;
437 ACPI_FUNCTION_TRACE(acpi_clear_gpe);
439 /* Use semaphore lock if not executing at interrupt level */
441 if (flags & ACPI_NOT_ISR) {
442 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
443 if (ACPI_FAILURE(status)) {
444 return_ACPI_STATUS(status);
448 /* Ensure that we have a valid GPE number */
450 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
451 if (!gpe_event_info) {
452 status = AE_BAD_PARAMETER;
453 goto unlock_and_exit;
456 status = acpi_hw_clear_gpe(gpe_event_info);
459 if (flags & ACPI_NOT_ISR) {
460 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
462 return_ACPI_STATUS(status);
465 ACPI_EXPORT_SYMBOL(acpi_clear_gpe)
467 #ifdef ACPI_FUTURE_USAGE
468 /*******************************************************************************
470 * FUNCTION: acpi_get_event_status
472 * PARAMETERS: Event - The fixed event
473 * event_status - Where the current status of the event will
478 * DESCRIPTION: Obtains and returns the current status of the event
480 ******************************************************************************/
481 acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status)
483 acpi_status status = AE_OK;
485 ACPI_FUNCTION_TRACE(acpi_get_event_status);
488 return_ACPI_STATUS(AE_BAD_PARAMETER);
491 /* Decode the Fixed Event */
493 if (event > ACPI_EVENT_MAX) {
494 return_ACPI_STATUS(AE_BAD_PARAMETER);
497 /* Get the status of the requested fixed event */
500 acpi_get_register(acpi_gbl_fixed_event_info[event].
501 status_register_id, event_status);
503 return_ACPI_STATUS(status);
506 ACPI_EXPORT_SYMBOL(acpi_get_event_status)
508 /*******************************************************************************
510 * FUNCTION: acpi_get_gpe_status
512 * PARAMETERS: gpe_device - Parent GPE Device
513 * gpe_number - GPE level within the GPE block
514 * Flags - Called from an ISR or not
515 * event_status - Where the current status of the event will
520 * DESCRIPTION: Get status of an event (general purpose)
522 ******************************************************************************/
524 acpi_get_gpe_status(acpi_handle gpe_device,
525 u32 gpe_number, u32 flags, acpi_event_status * event_status)
527 acpi_status status = AE_OK;
528 struct acpi_gpe_event_info *gpe_event_info;
530 ACPI_FUNCTION_TRACE(acpi_get_gpe_status);
532 /* Use semaphore lock if not executing at interrupt level */
534 if (flags & ACPI_NOT_ISR) {
535 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
536 if (ACPI_FAILURE(status)) {
537 return_ACPI_STATUS(status);
541 /* Ensure that we have a valid GPE number */
543 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
544 if (!gpe_event_info) {
545 status = AE_BAD_PARAMETER;
546 goto unlock_and_exit;
549 /* Obtain status on the requested GPE number */
551 status = acpi_hw_get_gpe_status(gpe_event_info, event_status);
554 if (flags & ACPI_NOT_ISR) {
555 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
557 return_ACPI_STATUS(status);
560 ACPI_EXPORT_SYMBOL(acpi_get_gpe_status)
561 #endif /* ACPI_FUTURE_USAGE */
563 /*******************************************************************************
565 * FUNCTION: acpi_install_gpe_block
567 * PARAMETERS: gpe_device - Handle to the parent GPE Block Device
568 * gpe_block_address - Address and space_iD
569 * register_count - Number of GPE register pairs in the block
570 * interrupt_number - H/W interrupt for the block
574 * DESCRIPTION: Create and Install a block of GPE registers
576 ******************************************************************************/
578 acpi_install_gpe_block(acpi_handle gpe_device,
579 struct acpi_generic_address *gpe_block_address,
580 u32 register_count, u32 interrupt_number)
583 union acpi_operand_object *obj_desc;
584 struct acpi_namespace_node *node;
585 struct acpi_gpe_block_info *gpe_block;
587 ACPI_FUNCTION_TRACE(acpi_install_gpe_block);
589 if ((!gpe_device) || (!gpe_block_address) || (!register_count)) {
590 return_ACPI_STATUS(AE_BAD_PARAMETER);
593 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
594 if (ACPI_FAILURE(status)) {
598 node = acpi_ns_map_handle_to_node(gpe_device);
600 status = AE_BAD_PARAMETER;
601 goto unlock_and_exit;
605 * For user-installed GPE Block Devices, the gpe_block_base_number
609 acpi_ev_create_gpe_block(node, gpe_block_address, register_count, 0,
610 interrupt_number, &gpe_block);
611 if (ACPI_FAILURE(status)) {
612 goto unlock_and_exit;
615 /* Run the _PRW methods and enable the GPEs */
617 status = acpi_ev_initialize_gpe_block(node, gpe_block);
618 if (ACPI_FAILURE(status)) {
619 goto unlock_and_exit;
622 /* Get the device_object attached to the node */
624 obj_desc = acpi_ns_get_attached_object(node);
627 /* No object, create a new one */
629 obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_DEVICE);
631 status = AE_NO_MEMORY;
632 goto unlock_and_exit;
636 acpi_ns_attach_object(node, obj_desc, ACPI_TYPE_DEVICE);
638 /* Remove local reference to the object */
640 acpi_ut_remove_reference(obj_desc);
642 if (ACPI_FAILURE(status)) {
643 goto unlock_and_exit;
647 /* Install the GPE block in the device_object */
649 obj_desc->device.gpe_block = gpe_block;
652 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
653 return_ACPI_STATUS(status);
656 ACPI_EXPORT_SYMBOL(acpi_install_gpe_block)
658 /*******************************************************************************
660 * FUNCTION: acpi_remove_gpe_block
662 * PARAMETERS: gpe_device - Handle to the parent GPE Block Device
666 * DESCRIPTION: Remove a previously installed block of GPE registers
668 ******************************************************************************/
669 acpi_status acpi_remove_gpe_block(acpi_handle gpe_device)
671 union acpi_operand_object *obj_desc;
673 struct acpi_namespace_node *node;
675 ACPI_FUNCTION_TRACE(acpi_remove_gpe_block);
678 return_ACPI_STATUS(AE_BAD_PARAMETER);
681 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
682 if (ACPI_FAILURE(status)) {
686 node = acpi_ns_map_handle_to_node(gpe_device);
688 status = AE_BAD_PARAMETER;
689 goto unlock_and_exit;
692 /* Get the device_object attached to the node */
694 obj_desc = acpi_ns_get_attached_object(node);
695 if (!obj_desc || !obj_desc->device.gpe_block) {
696 return_ACPI_STATUS(AE_NULL_OBJECT);
699 /* Delete the GPE block (but not the device_object) */
701 status = acpi_ev_delete_gpe_block(obj_desc->device.gpe_block);
702 if (ACPI_SUCCESS(status)) {
703 obj_desc->device.gpe_block = NULL;
707 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
708 return_ACPI_STATUS(status);
711 ACPI_EXPORT_SYMBOL(acpi_remove_gpe_block)