patch-2.4.22 linux-2.4.22/drivers/acpi/events/evxfevnt.c
Next file: linux-2.4.22/drivers/acpi/events/evxfregn.c
Previous file: linux-2.4.22/drivers/acpi/events/evxface.c
Back to the patch index
Back to the overall index
- Lines: 1013
- Date:
2003-08-25 04:44:41.000000000 -0700
- Orig file:
linux-2.4.21/drivers/acpi/events/evxfevnt.c
- Orig date:
2001-10-24 14:06:22.000000000 -0700
diff -urN linux-2.4.21/drivers/acpi/events/evxfevnt.c linux-2.4.22/drivers/acpi/events/evxfevnt.c
@@ -1,43 +1,58 @@
/******************************************************************************
*
* Module Name: evxfevnt - External Interfaces, ACPI event disable/enable
- * $Revision: 38 $
*
*****************************************************************************/
/*
- * Copyright (C) 2000, 2001 R. Byron Moore
+ * Copyright (C) 2000 - 2003, R. Byron Moore
+ * All rights reserved.
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
*/
-#include "acpi.h"
-#include "achware.h"
-#include "acnamesp.h"
-#include "acevents.h"
-#include "amlcode.h"
-#include "acinterp.h"
+#include <acpi/acpi.h>
+#include <acpi/acevents.h>
+#include <acpi/acnamesp.h>
#define _COMPONENT ACPI_EVENTS
- MODULE_NAME ("evxfevnt")
+ ACPI_MODULE_NAME ("evxfevnt")
/*******************************************************************************
*
- * FUNCTION: Acpi_enable
+ * FUNCTION: acpi_enable
*
* PARAMETERS: None
*
@@ -50,74 +65,79 @@
acpi_status
acpi_enable (void)
{
- acpi_status status;
+ acpi_status status = AE_OK;
- FUNCTION_TRACE ("Acpi_enable");
+ ACPI_FUNCTION_TRACE ("acpi_enable");
- /* Make sure we've got ACPI tables */
+ /* Make sure we have the FADT*/
- if (!acpi_gbl_DSDT) {
- ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "No ACPI tables present!\n"));
+ if (!acpi_gbl_FADT) {
+ ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "No FADT information present!\n"));
return_ACPI_STATUS (AE_NO_ACPI_TABLES);
}
- /* Make sure the BIOS supports ACPI mode */
-
- if (SYS_MODE_LEGACY == acpi_hw_get_mode_capabilities()) {
- ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Only legacy mode supported!\n"));
- return_ACPI_STATUS (AE_ERROR);
+ if (acpi_hw_get_mode() == ACPI_SYS_MODE_ACPI) {
+ ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "System is already in ACPI mode\n"));
}
+ else {
+ /* Transition to ACPI mode */
- /* Transition to ACPI mode */
+ status = acpi_hw_set_mode (ACPI_SYS_MODE_ACPI);
+ if (ACPI_FAILURE (status)) {
+ ACPI_REPORT_ERROR (("Could not transition to ACPI mode.\n"));
+ return_ACPI_STATUS (status);
+ }
- status = acpi_hw_set_mode (SYS_MODE_ACPI);
- if (ACPI_FAILURE (status)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_FATAL, "Could not transition to ACPI mode.\n"));
- return_ACPI_STATUS (status);
+ ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "Transition to ACPI mode successful\n"));
}
- ACPI_DEBUG_PRINT ((ACPI_DB_OK, "Transition to ACPI mode successful\n"));
-
return_ACPI_STATUS (status);
}
/*******************************************************************************
*
- * FUNCTION: Acpi_disable
+ * FUNCTION: acpi_disable
*
* PARAMETERS: None
*
* RETURN: Status
*
- * DESCRIPTION: Returns the system to original ACPI/legacy mode, and
- * uninstalls the SCI interrupt handler.
+ * DESCRIPTION: Transfers the system into LEGACY mode.
*
******************************************************************************/
acpi_status
acpi_disable (void)
{
- acpi_status status;
+ acpi_status status = AE_OK;
- FUNCTION_TRACE ("Acpi_disable");
+ ACPI_FUNCTION_TRACE ("acpi_disable");
- /* Restore original mode */
+ if (!acpi_gbl_FADT) {
+ ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "No FADT information present!\n"));
+ return_ACPI_STATUS (AE_NO_ACPI_TABLES);
+ }
- status = acpi_hw_set_mode (acpi_gbl_original_mode);
- if (ACPI_FAILURE (status)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unable to transition to original mode"));
- return_ACPI_STATUS (status);
+ if (acpi_hw_get_mode() == ACPI_SYS_MODE_LEGACY) {
+ ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "System is already in legacy (non-ACPI) mode\n"));
}
+ else {
+ /* Transition to LEGACY mode */
+
+ status = acpi_hw_set_mode (ACPI_SYS_MODE_LEGACY);
- /* Unload the SCI interrupt handler */
+ if (ACPI_FAILURE (status)) {
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not exit ACPI mode to legacy mode"));
+ return_ACPI_STATUS (status);
+ }
- acpi_ev_remove_sci_handler ();
- acpi_ev_restore_acpi_state ();
+ ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "ACPI mode disabled\n"));
+ }
return_ACPI_STATUS (status);
}
@@ -125,107 +145,179 @@
/*******************************************************************************
*
- * FUNCTION: Acpi_enable_event
+ * FUNCTION: acpi_enable_event
*
- * PARAMETERS: Event - The fixed event or GPE to be enabled
- * Type - The type of event
- * Flags - Just enable, or also wake enable?
+ * PARAMETERS: Event - The fixed eventto be enabled
+ * Flags - Reserved
*
* RETURN: Status
*
- * DESCRIPTION: Enable an ACPI event (fixed and general purpose)
+ * DESCRIPTION: Enable an ACPI event (fixed)
*
******************************************************************************/
acpi_status
acpi_enable_event (
- u32 event,
- u32 type,
- u32 flags)
+ u32 event,
+ u32 flags)
{
- acpi_status status = AE_OK;
- u32 register_id;
+ acpi_status status = AE_OK;
+ u32 value;
- FUNCTION_TRACE ("Acpi_enable_event");
+ ACPI_FUNCTION_TRACE ("acpi_enable_event");
- /* The Type must be either Fixed Acpi_event or GPE */
+ /* Decode the Fixed Event */
- switch (type) {
+ if (event > ACPI_EVENT_MAX) {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
- case ACPI_EVENT_FIXED:
+ /*
+ * Enable the requested fixed event (by writing a one to the
+ * enable register bit)
+ */
+ status = acpi_set_register (acpi_gbl_fixed_event_info[event].enable_register_id,
+ 1, ACPI_MTX_LOCK);
+ if (ACPI_FAILURE (status)) {
+ return_ACPI_STATUS (status);
+ }
- /* Decode the Fixed Acpi_event */
+ /* Make sure that the hardware responded */
- switch (event) {
- case ACPI_EVENT_PMTIMER:
- register_id = TMR_EN;
- break;
+ status = acpi_get_register (acpi_gbl_fixed_event_info[event].enable_register_id,
+ &value, ACPI_MTX_LOCK);
+ if (ACPI_FAILURE (status)) {
+ return_ACPI_STATUS (status);
+ }
- case ACPI_EVENT_GLOBAL:
- register_id = GBL_EN;
- break;
+ if (value != 1) {
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+ "Could not enable %s event\n", acpi_ut_get_event_name (event)));
+ return_ACPI_STATUS (AE_NO_HARDWARE_RESPONSE);
+ }
- case ACPI_EVENT_POWER_BUTTON:
- register_id = PWRBTN_EN;
- break;
+ return_ACPI_STATUS (status);
+}
- case ACPI_EVENT_SLEEP_BUTTON:
- register_id = SLPBTN_EN;
- break;
- case ACPI_EVENT_RTC:
- register_id = RTC_EN;
- break;
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_enable_gpe
+ *
+ * PARAMETERS: gpe_device - Parent GPE Device
+ * gpe_number - GPE level within the GPE block
+ * Flags - Just enable, or also wake enable?
+ * Called from ISR or not
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Enable an ACPI event (general purpose)
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_enable_gpe (
+ acpi_handle gpe_device,
+ u32 gpe_number,
+ u32 flags)
+{
+ acpi_status status = AE_OK;
+ struct acpi_gpe_event_info *gpe_event_info;
- default:
- return_ACPI_STATUS (AE_BAD_PARAMETER);
- break;
- }
- /*
- * Enable the requested fixed event (by writing a one to the
- * enable register bit)
- */
- acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_LOCK, register_id, 1);
-
- if (1 != acpi_hw_register_bit_access(ACPI_READ, ACPI_MTX_LOCK, register_id)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Fixed event bit clear when it should be set\n"));
- return_ACPI_STATUS (AE_NO_HARDWARE_RESPONSE);
+ ACPI_FUNCTION_TRACE ("acpi_enable_gpe");
+
+
+ /* Use semaphore lock if not executing at interrupt level */
+
+ if (flags & ACPI_NOT_ISR) {
+ status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
+ if (ACPI_FAILURE (status)) {
+ return_ACPI_STATUS (status);
}
+ }
- break;
+ /* Ensure that we have a valid GPE number */
+ gpe_event_info = acpi_ev_get_gpe_event_info (gpe_device, gpe_number);
+ if (!gpe_event_info) {
+ status = AE_BAD_PARAMETER;
+ goto unlock_and_exit;
+ }
- case ACPI_EVENT_GPE:
+ /* Enable the requested GPE number */
- /* Ensure that we have a valid GPE number */
+ status = acpi_hw_enable_gpe (gpe_event_info);
+ if (ACPI_FAILURE (status)) {
+ goto unlock_and_exit;
+ }
- if ((event > ACPI_GPE_MAX) ||
- (acpi_gbl_gpe_valid[event] == ACPI_GPE_INVALID)) {
- return_ACPI_STATUS (AE_BAD_PARAMETER);
- }
+ if (flags & ACPI_EVENT_WAKE_ENABLE) {
+ acpi_hw_enable_gpe_for_wakeup (gpe_event_info);
+ }
+unlock_and_exit:
+ if (flags & ACPI_NOT_ISR) {
+ (void) acpi_ut_release_mutex (ACPI_MTX_EVENTS);
+ }
+ return_ACPI_STATUS (status);
+}
- /* Enable the requested GPE number */
- if (flags & ACPI_EVENT_ENABLE) {
- acpi_hw_enable_gpe (event);
- }
- if (flags & ACPI_EVENT_WAKE_ENABLE) {
- acpi_hw_enable_gpe_for_wakeup (event);
- }
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_disable_event
+ *
+ * PARAMETERS: Event - The fixed eventto be enabled
+ * Flags - Reserved
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Disable an ACPI event (fixed)
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_disable_event (
+ u32 event,
+ u32 flags)
+{
+ acpi_status status = AE_OK;
+ u32 value;
- break;
+ ACPI_FUNCTION_TRACE ("acpi_disable_event");
- default:
- status = AE_BAD_PARAMETER;
+ /* Decode the Fixed Event */
+
+ if (event > ACPI_EVENT_MAX) {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+ /*
+ * Disable the requested fixed event (by writing a zero to the
+ * enable register bit)
+ */
+ status = acpi_set_register (acpi_gbl_fixed_event_info[event].enable_register_id,
+ 0, ACPI_MTX_LOCK);
+ if (ACPI_FAILURE (status)) {
+ return_ACPI_STATUS (status);
+ }
+
+ status = acpi_get_register (acpi_gbl_fixed_event_info[event].enable_register_id,
+ &value, ACPI_MTX_LOCK);
+ if (ACPI_FAILURE (status)) {
+ return_ACPI_STATUS (status);
}
+ if (value != 0) {
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+ "Could not disable %s events\n", acpi_ut_get_event_name (event)));
+ return_ACPI_STATUS (AE_NO_HARDWARE_RESPONSE);
+ }
return_ACPI_STATUS (status);
}
@@ -233,293 +325,412 @@
/*******************************************************************************
*
- * FUNCTION: Acpi_disable_event
+ * FUNCTION: acpi_disable_gpe
*
- * PARAMETERS: Event - The fixed event or GPE to be enabled
- * Type - The type of event, fixed or general purpose
- * Flags - Wake disable vs. non-wake disable
+ * PARAMETERS: gpe_device - Parent GPE Device
+ * gpe_number - GPE level within the GPE block
+ * Flags - Just enable, or also wake enable?
+ * Called from ISR or not
*
* RETURN: Status
*
- * DESCRIPTION: Disable an ACPI event (fixed and general purpose)
+ * DESCRIPTION: Disable an ACPI event (general purpose)
*
******************************************************************************/
acpi_status
-acpi_disable_event (
- u32 event,
- u32 type,
- u32 flags)
+acpi_disable_gpe (
+ acpi_handle gpe_device,
+ u32 gpe_number,
+ u32 flags)
{
- acpi_status status = AE_OK;
- u32 register_id;
+ acpi_status status = AE_OK;
+ struct acpi_gpe_event_info *gpe_event_info;
+
+
+ ACPI_FUNCTION_TRACE ("acpi_disable_gpe");
+
+
+ /* Use semaphore lock if not executing at interrupt level */
+
+ if (flags & ACPI_NOT_ISR) {
+ status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
+ if (ACPI_FAILURE (status)) {
+ return_ACPI_STATUS (status);
+ }
+ }
+ /* Ensure that we have a valid GPE number */
- FUNCTION_TRACE ("Acpi_disable_event");
+ gpe_event_info = acpi_ev_get_gpe_event_info (gpe_device, gpe_number);
+ if (!gpe_event_info) {
+ status = AE_BAD_PARAMETER;
+ goto unlock_and_exit;
+ }
+
+ /*
+ * Only disable the requested GPE number for wake if specified.
+ * Otherwise, turn it totally off
+ */
+ if (flags & ACPI_EVENT_WAKE_DISABLE) {
+ acpi_hw_disable_gpe_for_wakeup (gpe_event_info);
+ }
+ else {
+ status = acpi_hw_disable_gpe (gpe_event_info);
+ }
+unlock_and_exit:
+ if (flags & ACPI_NOT_ISR) {
+ (void) acpi_ut_release_mutex (ACPI_MTX_EVENTS);
+ }
+ return_ACPI_STATUS (status);
+}
- /* The Type must be either Fixed Acpi_event or GPE */
- switch (type) {
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_clear_event
+ *
+ * PARAMETERS: Event - The fixed event to be cleared
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Clear an ACPI event (fixed)
+ *
+ ******************************************************************************/
- case ACPI_EVENT_FIXED:
+acpi_status
+acpi_clear_event (
+ u32 event)
+{
+ acpi_status status = AE_OK;
- /* Decode the Fixed Acpi_event */
- switch (event) {
- case ACPI_EVENT_PMTIMER:
- register_id = TMR_EN;
- break;
+ ACPI_FUNCTION_TRACE ("acpi_clear_event");
- case ACPI_EVENT_GLOBAL:
- register_id = GBL_EN;
- break;
- case ACPI_EVENT_POWER_BUTTON:
- register_id = PWRBTN_EN;
- break;
+ /* Decode the Fixed Event */
- case ACPI_EVENT_SLEEP_BUTTON:
- register_id = SLPBTN_EN;
- break;
+ if (event > ACPI_EVENT_MAX) {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
- case ACPI_EVENT_RTC:
- register_id = RTC_EN;
- break;
+ /*
+ * Clear the requested fixed event (By writing a one to the
+ * status register bit)
+ */
+ status = acpi_set_register (acpi_gbl_fixed_event_info[event].status_register_id,
+ 1, ACPI_MTX_LOCK);
- default:
- return_ACPI_STATUS (AE_BAD_PARAMETER);
- break;
- }
+ return_ACPI_STATUS (status);
+}
- /*
- * Disable the requested fixed event (by writing a zero to the
- * enable register bit)
- */
- acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_LOCK, register_id, 0);
-
- if (0 != acpi_hw_register_bit_access(ACPI_READ, ACPI_MTX_LOCK, register_id)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "Fixed event bit set when it should be clear,\n"));
- return_ACPI_STATUS (AE_NO_HARDWARE_RESPONSE);
- }
- break;
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_clear_gpe
+ *
+ * PARAMETERS: gpe_device - Parent GPE Device
+ * gpe_number - GPE level within the GPE block
+ * Flags - Called from an ISR or not
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Clear an ACPI event (general purpose)
+ *
+ ******************************************************************************/
+acpi_status
+acpi_clear_gpe (
+ acpi_handle gpe_device,
+ u32 gpe_number,
+ u32 flags)
+{
+ acpi_status status = AE_OK;
+ struct acpi_gpe_event_info *gpe_event_info;
- case ACPI_EVENT_GPE:
- /* Ensure that we have a valid GPE number */
+ ACPI_FUNCTION_TRACE ("acpi_clear_gpe");
- if ((event > ACPI_GPE_MAX) ||
- (acpi_gbl_gpe_valid[event] == ACPI_GPE_INVALID)) {
- return_ACPI_STATUS (AE_BAD_PARAMETER);
- }
- /* Disable the requested GPE number */
+ /* Use semaphore lock if not executing at interrupt level */
- if (flags & ACPI_EVENT_DISABLE) {
- acpi_hw_disable_gpe (event);
- }
- if (flags & ACPI_EVENT_WAKE_DISABLE) {
- acpi_hw_disable_gpe_for_wakeup (event);
+ if (flags & ACPI_NOT_ISR) {
+ status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
+ if (ACPI_FAILURE (status)) {
+ return_ACPI_STATUS (status);
}
+ }
- break;
-
+ /* Ensure that we have a valid GPE number */
- default:
+ gpe_event_info = acpi_ev_get_gpe_event_info (gpe_device, gpe_number);
+ if (!gpe_event_info) {
status = AE_BAD_PARAMETER;
+ goto unlock_and_exit;
}
+ status = acpi_hw_clear_gpe (gpe_event_info);
+
+unlock_and_exit:
+ if (flags & ACPI_NOT_ISR) {
+ (void) acpi_ut_release_mutex (ACPI_MTX_EVENTS);
+ }
return_ACPI_STATUS (status);
}
/*******************************************************************************
*
- * FUNCTION: Acpi_clear_event
+ * FUNCTION: acpi_get_event_status
*
- * PARAMETERS: Event - The fixed event or GPE to be cleared
- * Type - The type of event
+ * PARAMETERS: Event - The fixed event
+ * Event Status - Where the current status of the event will
+ * be returned
*
* RETURN: Status
*
- * DESCRIPTION: Clear an ACPI event (fixed and general purpose)
+ * DESCRIPTION: Obtains and returns the current status of the event
*
******************************************************************************/
acpi_status
-acpi_clear_event (
- u32 event,
- u32 type)
+acpi_get_event_status (
+ u32 event,
+ acpi_event_status *event_status)
{
- acpi_status status = AE_OK;
- u32 register_id;
-
+ acpi_status status = AE_OK;
- FUNCTION_TRACE ("Acpi_clear_event");
+ ACPI_FUNCTION_TRACE ("acpi_get_event_status");
- /* The Type must be either Fixed Acpi_event or GPE */
- switch (type) {
+ if (!event_status) {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
- case ACPI_EVENT_FIXED:
+ /* Decode the Fixed Event */
- /* Decode the Fixed Acpi_event */
+ if (event > ACPI_EVENT_MAX) {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
- switch (event) {
- case ACPI_EVENT_PMTIMER:
- register_id = TMR_STS;
- break;
+ /* Get the status of the requested fixed event */
- case ACPI_EVENT_GLOBAL:
- register_id = GBL_STS;
- break;
+ status = acpi_get_register (acpi_gbl_fixed_event_info[event].status_register_id,
+ event_status, ACPI_MTX_LOCK);
- case ACPI_EVENT_POWER_BUTTON:
- register_id = PWRBTN_STS;
- break;
+ return_ACPI_STATUS (status);
+}
- case ACPI_EVENT_SLEEP_BUTTON:
- register_id = SLPBTN_STS;
- break;
- case ACPI_EVENT_RTC:
- register_id = RTC_STS;
- break;
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_get_gpe_status
+ *
+ * PARAMETERS: gpe_device - Parent GPE Device
+ * gpe_number - GPE level within the GPE block
+ * Flags - Called from an ISR or not
+ * Event Status - Where the current status of the event will
+ * be returned
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Get status of an event (general purpose)
+ *
+ ******************************************************************************/
- default:
- return_ACPI_STATUS (AE_BAD_PARAMETER);
- break;
- }
+acpi_status
+acpi_get_gpe_status (
+ acpi_handle gpe_device,
+ u32 gpe_number,
+ u32 flags,
+ acpi_event_status *event_status)
+{
+ acpi_status status = AE_OK;
+ struct acpi_gpe_event_info *gpe_event_info;
- /*
- * Clear the requested fixed event (By writing a one to the
- * status register bit)
- */
- acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_LOCK, register_id, 1);
- break;
+ ACPI_FUNCTION_TRACE ("acpi_get_gpe_status");
- case ACPI_EVENT_GPE:
- /* Ensure that we have a valid GPE number */
+ /* Use semaphore lock if not executing at interrupt level */
- if ((event > ACPI_GPE_MAX) ||
- (acpi_gbl_gpe_valid[event] == ACPI_GPE_INVALID)) {
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ if (flags & ACPI_NOT_ISR) {
+ status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
+ if (ACPI_FAILURE (status)) {
+ return_ACPI_STATUS (status);
}
+ }
+ /* Ensure that we have a valid GPE number */
- acpi_hw_clear_gpe (event);
- break;
+ gpe_event_info = acpi_ev_get_gpe_event_info (gpe_device, gpe_number);
+ if (!gpe_event_info) {
+ status = AE_BAD_PARAMETER;
+ goto unlock_and_exit;
+ }
+ /* Obtain status on the requested GPE number */
- default:
+ status = acpi_hw_get_gpe_status (gpe_event_info, event_status);
- status = AE_BAD_PARAMETER;
+unlock_and_exit:
+ if (flags & ACPI_NOT_ISR) {
+ (void) acpi_ut_release_mutex (ACPI_MTX_EVENTS);
}
-
return_ACPI_STATUS (status);
}
/*******************************************************************************
*
- * FUNCTION: Acpi_get_event_status
+ * FUNCTION: acpi_install_gpe_block
*
- * PARAMETERS: Event - The fixed event or GPE
- * Type - The type of event
- * Status - Where the current status of the event will
- * be returned
+ * PARAMETERS: gpe_device - Handle to the parent GPE Block Device
+ * gpe_block_address - Address and space_iD
+ * register_count - Number of GPE register pairs in the block
+ * interrupt_level - H/W interrupt for the block
*
* RETURN: Status
*
- * DESCRIPTION: Obtains and returns the current status of the event
+ * DESCRIPTION: Create and Install a block of GPE registers
*
******************************************************************************/
-
acpi_status
-acpi_get_event_status (
- u32 event,
- u32 type,
- acpi_event_status *event_status)
+acpi_install_gpe_block (
+ acpi_handle gpe_device,
+ struct acpi_generic_address *gpe_block_address,
+ u32 register_count,
+ u32 interrupt_level)
{
- acpi_status status = AE_OK;
- u32 register_id;
+ acpi_status status;
+ union acpi_operand_object *obj_desc;
+ struct acpi_namespace_node *node;
+ struct acpi_gpe_block_info *gpe_block;
- FUNCTION_TRACE ("Acpi_get_event_status");
+ ACPI_FUNCTION_TRACE ("acpi_install_gpe_block");
- if (!event_status) {
+ if ((!gpe_device) ||
+ (!gpe_block_address) ||
+ (!register_count)) {
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
+ status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE (status)) {
+ return (status);
+ }
- /* The Type must be either Fixed Acpi_event or GPE */
-
- switch (type) {
+ node = acpi_ns_map_handle_to_node (gpe_device);
+ if (!node) {
+ status = AE_BAD_PARAMETER;
+ goto unlock_and_exit;
+ }
- case ACPI_EVENT_FIXED:
+ /*
+ * For user-installed GPE Block Devices, the gpe_block_base_number
+ * is always zero
+ */
+ status = acpi_ev_create_gpe_block (node, gpe_block_address, register_count,
+ 0, interrupt_level, &gpe_block);
+ if (ACPI_FAILURE (status)) {
+ goto unlock_and_exit;
+ }
- /* Decode the Fixed Acpi_event */
+ /* Get the device_object attached to the node */
- switch (event) {
- case ACPI_EVENT_PMTIMER:
- register_id = TMR_STS;
- break;
+ obj_desc = acpi_ns_get_attached_object (node);
+ if (!obj_desc) {
+ /* No object, create a new one */
- case ACPI_EVENT_GLOBAL:
- register_id = GBL_STS;
- break;
+ obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_DEVICE);
+ if (!obj_desc) {
+ status = AE_NO_MEMORY;
+ goto unlock_and_exit;
+ }
- case ACPI_EVENT_POWER_BUTTON:
- register_id = PWRBTN_STS;
- break;
+ status = acpi_ns_attach_object (node, obj_desc, ACPI_TYPE_DEVICE);
- case ACPI_EVENT_SLEEP_BUTTON:
- register_id = SLPBTN_STS;
- break;
+ /* Remove local reference to the object */
- case ACPI_EVENT_RTC:
- register_id = RTC_STS;
- break;
+ acpi_ut_remove_reference (obj_desc);
- default:
- return_ACPI_STATUS (AE_BAD_PARAMETER);
- break;
+ if (ACPI_FAILURE (status)) {
+ goto unlock_and_exit;
}
+ }
+
+ /* Install the GPE block in the device_object */
- /* Get the status of the requested fixed event */
+ obj_desc->device.gpe_block = gpe_block;
- *event_status = acpi_hw_register_bit_access (ACPI_READ, ACPI_MTX_LOCK, register_id);
- break;
+unlock_and_exit:
+ (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+ return_ACPI_STATUS (status);
+}
- case ACPI_EVENT_GPE:
- /* Ensure that we have a valid GPE number */
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_remove_gpe_block
+ *
+ * PARAMETERS: gpe_device - Handle to the parent GPE Block Device
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Remove a previously installed block of GPE registers
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_remove_gpe_block (
+ acpi_handle gpe_device)
+{
+ union acpi_operand_object *obj_desc;
+ acpi_status status;
+ struct acpi_namespace_node *node;
- if ((event > ACPI_GPE_MAX) ||
- (acpi_gbl_gpe_valid[event] == ACPI_GPE_INVALID)) {
- return_ACPI_STATUS (AE_BAD_PARAMETER);
- }
+ ACPI_FUNCTION_TRACE ("acpi_remove_gpe_block");
- /* Obtain status on the requested GPE number */
- acpi_hw_get_gpe_status (event, event_status);
- break;
+ if (!gpe_device) {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+ status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE (status)) {
+ return (status);
+ }
- default:
+ node = acpi_ns_map_handle_to_node (gpe_device);
+ if (!node) {
status = AE_BAD_PARAMETER;
+ goto unlock_and_exit;
+ }
+
+ /* Get the device_object attached to the node */
+
+ obj_desc = acpi_ns_get_attached_object (node);
+ if (!obj_desc ||
+ !obj_desc->device.gpe_block) {
+ return_ACPI_STATUS (AE_NULL_OBJECT);
+ }
+
+ /* Delete the GPE block (but not the device_object) */
+
+ status = acpi_ev_delete_gpe_block (obj_desc->device.gpe_block);
+ if (ACPI_SUCCESS (status)) {
+ obj_desc->device.gpe_block = NULL;
}
+unlock_and_exit:
+ (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
return_ACPI_STATUS (status);
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)