Viewing file: evsci.c (7.13 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
/******************************************************************************* * * Module Name: evsci - System Control Interrupt configuration and * legacy to ACPI mode state transition functions * $Revision: 74 $ * ******************************************************************************/
/* * Copyright (C) 2000, 2001 R. Byron Moore * * 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 */
#include "acpi.h" #include "acnamesp.h" #include "achware.h" #include "acevents.h"
#define _COMPONENT ACPI_EVENTS MODULE_NAME ("evsci")
/* * Elements correspond to counts for TMR, NOT_USED, GBL, PWR_BTN, SLP_BTN, RTC, * and GENERAL respectively. These counts are modified by the ACPI interrupt * handler. * * TBD: [Investigate] Note that GENERAL should probably be split out into * one element for each bit in the GPE registers */
/******************************************************************************* * * FUNCTION: Acpi_ev_sci_handler * * PARAMETERS: Context - Calling Context * * RETURN: Status code indicates whether interrupt was handled. * * DESCRIPTION: Interrupt handler that will figure out what function or * control method to call to deal with a SCI. Installed * using BU interrupt support. * ******************************************************************************/
static u32 acpi_ev_sci_handler (void *context) { u32 interrupt_handled = INTERRUPT_NOT_HANDLED;
FUNCTION_TRACE("Ev_sci_handler");
/* * Make sure that ACPI is enabled by checking SCI_EN. Note that we are * required to treat the SCI interrupt as sharable, level, active low. */ if (!acpi_hw_register_bit_access (ACPI_READ, ACPI_MTX_DO_NOT_LOCK, SCI_EN)) { /* ACPI is not enabled; this interrupt cannot be for us */
return_VALUE (INTERRUPT_NOT_HANDLED); }
/* * Fixed Acpi_events: * ------------- * Check for and dispatch any Fixed Acpi_events that have occurred */ interrupt_handled |= acpi_ev_fixed_event_detect ();
/* * GPEs: * ----- * Check for and dispatch any GPEs that have occurred */ interrupt_handled |= acpi_ev_gpe_detect ();
return_VALUE (interrupt_handled); }
/****************************************************************************** * * FUNCTION: Acpi_ev_install_sci_handler * * PARAMETERS: none * * RETURN: Status * * DESCRIPTION: Installs SCI handler. * ******************************************************************************/
u32 acpi_ev_install_sci_handler (void) { u32 status = AE_OK;
FUNCTION_TRACE ("Ev_install_sci_handler");
status = acpi_os_install_interrupt_handler ((u32) acpi_gbl_FADT->sci_int, acpi_ev_sci_handler, NULL); return_ACPI_STATUS (status); }
/******************************************************************************
* * FUNCTION: Acpi_ev_remove_sci_handler * * PARAMETERS: none * * RETURN: E_OK if handler uninstalled OK, E_ERROR if handler was not * installed to begin with * * DESCRIPTION: Restores original status of all fixed event enable bits and * removes SCI handler. * ******************************************************************************/
acpi_status acpi_ev_remove_sci_handler (void) { FUNCTION_TRACE ("Ev_remove_sci_handler");
#if 0 /* TBD:[Investigate] Figure this out!! Disable all events first ??? */
if (original_fixed_enable_bit_status ^ 1 << acpi_event_index (TMR_FIXED_EVENT)) { acpi_event_disable_event (TMR_FIXED_EVENT); }
if (original_fixed_enable_bit_status ^ 1 << acpi_event_index (GBL_FIXED_EVENT)) { acpi_event_disable_event (GBL_FIXED_EVENT); }
if (original_fixed_enable_bit_status ^ 1 << acpi_event_index (PWR_BTN_FIXED_EVENT)) { acpi_event_disable_event (PWR_BTN_FIXED_EVENT); }
if (original_fixed_enable_bit_status ^ 1 << acpi_event_index (SLP_BTN_FIXED_EVENT)) { acpi_event_disable_event (SLP_BTN_FIXED_EVENT); }
if (original_fixed_enable_bit_status ^ 1 << acpi_event_index (RTC_FIXED_EVENT)) { acpi_event_disable_event (RTC_FIXED_EVENT); }
original_fixed_enable_bit_status = 0;
#endif
acpi_os_remove_interrupt_handler ((u32) acpi_gbl_FADT->sci_int, acpi_ev_sci_handler);
return_ACPI_STATUS (AE_OK); }
/******************************************************************************* * * FUNCTION: Acpi_ev_restore_acpi_state * * PARAMETERS: none * * RETURN: none * * DESCRIPTION: Restore the original ACPI state of the machine * ******************************************************************************/
void acpi_ev_restore_acpi_state (void) { u32 index;
FUNCTION_TRACE ("Ev_restore_acpi_state");
/* Restore the state of the chipset enable bits. */
if (acpi_gbl_restore_acpi_chipset == TRUE) { /* Restore the fixed events */
if (acpi_hw_register_read (ACPI_MTX_LOCK, PM1_EN) != acpi_gbl_pm1_enable_register_save) { acpi_hw_register_write (ACPI_MTX_LOCK, PM1_EN, acpi_gbl_pm1_enable_register_save); }
/* Ensure that all status bits are clear */
acpi_hw_clear_acpi_status ();
/* Now restore the GPEs */
for (index = 0; index < DIV_2 (acpi_gbl_FADT->gpe0blk_len); index++) { if (acpi_hw_register_read (ACPI_MTX_LOCK, GPE0_EN_BLOCK | index) != acpi_gbl_gpe0enable_register_save[index]) { acpi_hw_register_write (ACPI_MTX_LOCK, GPE0_EN_BLOCK | index, acpi_gbl_gpe0enable_register_save[index]); } }
/* GPE 1 present? */
if (acpi_gbl_FADT->gpe1_blk_len) { for (index = 0; index < DIV_2 (acpi_gbl_FADT->gpe1_blk_len); index++) { if (acpi_hw_register_read (ACPI_MTX_LOCK, GPE1_EN_BLOCK | index) != acpi_gbl_gpe1_enable_register_save[index]) { acpi_hw_register_write (ACPI_MTX_LOCK, GPE1_EN_BLOCK | index, acpi_gbl_gpe1_enable_register_save[index]); } } }
if (acpi_hw_get_mode() != acpi_gbl_original_mode) { acpi_hw_set_mode (acpi_gbl_original_mode); } }
return_VOID; }
/****************************************************************************** * * FUNCTION: Acpi_ev_terminate * * PARAMETERS: none * * RETURN: none * * DESCRIPTION: free memory allocated for table storage. * ******************************************************************************/
void acpi_ev_terminate (void) {
FUNCTION_TRACE ("Ev_terminate");
/* * Free global tables, etc. */ if (acpi_gbl_gpe_registers) { ACPI_MEM_FREE (acpi_gbl_gpe_registers); }
if (acpi_gbl_gpe_info) { ACPI_MEM_FREE (acpi_gbl_gpe_info); }
return_VOID; }
|