⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 evevent.c

📁 内核linux2.4.20,可跟rtlinux3.2打补丁 组成实时linux系统,编译内核
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************** * * Module Name: evevent - Fixed and General Purpose Acpi_event *                          handling and dispatch *              $Revision: 51 $ * *****************************************************************************//* *  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 "achware.h"#include "acevents.h"#include "acnamesp.h"#define _COMPONENT          ACPI_EVENTS	 MODULE_NAME         ("evevent")/******************************************************************************* * * FUNCTION:    Acpi_ev_initialize * * PARAMETERS:  None * * RETURN:      Status * * DESCRIPTION: Ensures that the system control interrupt (SCI) is properly *              configured, disables SCI event sources, installs the SCI *              handler * ******************************************************************************/acpi_statusacpi_ev_initialize (	void){	acpi_status             status;	FUNCTION_TRACE ("Ev_initialize");	/* Make sure we have ACPI tables */	if (!acpi_gbl_DSDT) {		ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "No ACPI tables 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, "ACPI Mode is not supported!\n"));		return_ACPI_STATUS (AE_ERROR);	}	acpi_gbl_original_mode = acpi_hw_get_mode();	/*	 * Initialize the Fixed and General Purpose Acpi_events prior. This is	 * done prior to enabling SCIs to prevent interrupts from occuring	 * before handers are installed.	 */	status = acpi_ev_fixed_event_initialize ();	if (ACPI_FAILURE (status)) {		ACPI_DEBUG_PRINT ((ACPI_DB_FATAL, "Unable to initialize fixed events.\n"));		return_ACPI_STATUS (status);	}	status = acpi_ev_gpe_initialize ();	if (ACPI_FAILURE (status)) {		ACPI_DEBUG_PRINT ((ACPI_DB_FATAL, "Unable to initialize general purpose events.\n"));		return_ACPI_STATUS (status);	}	/* Install the SCI handler */	status = acpi_ev_install_sci_handler ();	if (ACPI_FAILURE (status)) {		ACPI_DEBUG_PRINT ((ACPI_DB_FATAL, "Unable to install System Control Interrupt Handler\n"));		return_ACPI_STATUS (status);	}	/* Install handlers for control method GPE handlers (_Lxx, _Exx) */	status = acpi_ev_init_gpe_control_methods ();	if (ACPI_FAILURE (status)) {		ACPI_DEBUG_PRINT ((ACPI_DB_FATAL, "Unable to initialize Gpe control methods\n"));		return_ACPI_STATUS (status);	}	/* Install the handler for the Global Lock */	status = acpi_ev_init_global_lock_handler ();	if (ACPI_FAILURE (status)) {		ACPI_DEBUG_PRINT ((ACPI_DB_FATAL, "Unable to initialize Global Lock handler\n"));		return_ACPI_STATUS (status);	}	return_ACPI_STATUS (status);}/******************************************************************************* * * FUNCTION:    Acpi_ev_fixed_event_initialize * * PARAMETERS:  None * * RETURN:      Status * * DESCRIPTION: Initialize the Fixed Acpi_event data structures * ******************************************************************************/acpi_statusacpi_ev_fixed_event_initialize(void){	int                     i = 0;	/* Initialize the structure that keeps track of fixed event handlers */	for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) {		acpi_gbl_fixed_event_handlers[i].handler = NULL;		acpi_gbl_fixed_event_handlers[i].context = NULL;	}	acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_LOCK, TMR_EN, 0);	acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_LOCK, GBL_EN, 0);	acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_LOCK, PWRBTN_EN, 0);	acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_LOCK, SLPBTN_EN, 0);	acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_LOCK, RTC_EN, 0);	return (AE_OK);}/******************************************************************************* * * FUNCTION:    Acpi_ev_fixed_event_detect * * PARAMETERS:  None * * RETURN:      INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED * * DESCRIPTION: Checks the PM status register for fixed events * ******************************************************************************/u32acpi_ev_fixed_event_detect (void){	u32                     int_status = INTERRUPT_NOT_HANDLED;	u32                     status_register;	u32                     enable_register;	PROC_NAME ("Ev_fixed_event_detect");	/*	 * Read the fixed feature status and enable registers, as all the cases	 * depend on their values.	 */	status_register = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, PM1_STS);	enable_register = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, PM1_EN);	ACPI_DEBUG_PRINT ((ACPI_DB_INTERRUPTS,		"Fixed Acpi_event Block: Enable %08X Status %08X\n",		enable_register, status_register));	/* power management timer roll over */	if ((status_register & ACPI_STATUS_PMTIMER) &&		(enable_register & ACPI_ENABLE_PMTIMER)) {		int_status |= acpi_ev_fixed_event_dispatch (ACPI_EVENT_PMTIMER);	}	/* global event (BIOS wants the global lock) */	if ((status_register & ACPI_STATUS_GLOBAL) &&		(enable_register & ACPI_ENABLE_GLOBAL)) {		int_status |= acpi_ev_fixed_event_dispatch (ACPI_EVENT_GLOBAL);	}	/* power button event */	if ((status_register & ACPI_STATUS_POWER_BUTTON) &&		(enable_register & ACPI_ENABLE_POWER_BUTTON)) {		int_status |= acpi_ev_fixed_event_dispatch (ACPI_EVENT_POWER_BUTTON);	}	/* sleep button event */	if ((status_register & ACPI_STATUS_SLEEP_BUTTON) &&		(enable_register & ACPI_ENABLE_SLEEP_BUTTON)) {		int_status |= acpi_ev_fixed_event_dispatch (ACPI_EVENT_SLEEP_BUTTON);	}	return (int_status);}/******************************************************************************* * * FUNCTION:    Acpi_ev_fixed_event_dispatch * * PARAMETERS:  Event               - Event type * * RETURN:      INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED * * DESCRIPTION: Clears the status bit for the requested event, calls the *              handler that previously registered for the event. * ******************************************************************************/u32acpi_ev_fixed_event_dispatch (	u32                     event){	u32                     register_id;	FUNCTION_ENTRY ();	/* Clear the status bit */	switch (event) {	case ACPI_EVENT_PMTIMER:		register_id = TMR_STS;		break;	case ACPI_EVENT_GLOBAL:		register_id = GBL_STS;		break;	case ACPI_EVENT_POWER_BUTTON:		register_id = PWRBTN_STS;		break;	case ACPI_EVENT_SLEEP_BUTTON:		register_id = SLPBTN_STS;		break;	case ACPI_EVENT_RTC:		register_id = RTC_STS;		break;	default:		return 0;		break;	}	acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_DO_NOT_LOCK, register_id, 1);	/*	 * Make sure we've got a handler.  If not, report an error.	 * The event is disabled to prevent further interrupts.	 */	if (NULL == acpi_gbl_fixed_event_handlers[event].handler) {		register_id = (PM1_EN | REGISTER_BIT_ID(register_id));		acpi_hw_register_bit_access (ACPI_WRITE, ACPI_MTX_DO_NOT_LOCK,				 register_id, 0);		REPORT_ERROR (			("Ev_gpe_dispatch: No installed handler for fixed event [%08X]\n",			event));		return (INTERRUPT_NOT_HANDLED);	}	/* Invoke the handler */	return ((acpi_gbl_fixed_event_handlers[event].handler)(			  acpi_gbl_fixed_event_handlers[event].context));}/******************************************************************************* * * FUNCTION:    Acpi_ev_gpe_initialize * * PARAMETERS:  None * * RETURN:      Status * * DESCRIPTION: Initialize the GPE data structures * ******************************************************************************/acpi_statusacpi_ev_gpe_initialize (void){	u32                     i;	u32                     j;	u32                     register_index;	u32                     gpe_number;	u16                     gpe0register_count;	u16                     gpe1_register_count;	FUNCTION_TRACE ("Ev_gpe_initialize");	/*	 * Set up various GPE counts	 *	 * You may ask,why are the GPE register block lengths divided by 2?	 * From the ACPI 2.0 Spec, section, 4.7.1.6 General-Purpose Event	 * Registers, we have,	 *	 * "Each register block contains two registers of equal length	 * GPEx_STS and GPEx_EN (where x is 0 or 1). The length of the	 * GPE0_STS and GPE0_EN registers is equal to half the GPE0_LEN	 * The length of the GPE1_STS and GPE1_EN registers is equal to	 * half the GPE1_LEN. If a generic register block is not supported	 * then its respective block pointer and block length values in the	 * FADT table contain zeros. The GPE0_LEN and GPE1_LEN do not need	 * to be the same size."	 */	gpe0register_count          = (u16) DIV_2 (acpi_gbl_FADT->gpe0blk_len);	gpe1_register_count         = (u16) DIV_2 (acpi_gbl_FADT->gpe1_blk_len);	acpi_gbl_gpe_register_count = gpe0register_count + gpe1_register_count;	if (!acpi_gbl_gpe_register_count) {		REPORT_WARNING (("Zero GPEs are defined in the FADT\n"));		return_ACPI_STATUS (AE_OK);	}	/*	 * Allocate the Gpe information block	 */	acpi_gbl_gpe_registers = ACPI_MEM_CALLOCATE (acpi_gbl_gpe_register_count *			  sizeof (acpi_gpe_registers));	if (!acpi_gbl_gpe_registers) {		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,			"Could not allocate the Gpe_registers block\n"));		return_ACPI_STATUS (AE_NO_MEMORY);	}	/*	 * Allocate the Gpe dispatch handler block	 * There are eight distinct GP events per register.	 * Initialization to zeros is sufficient	 */	acpi_gbl_gpe_info = ACPI_MEM_CALLOCATE (MUL_8 (acpi_gbl_gpe_register_count) *			  sizeof (acpi_gpe_level_info));	if (!acpi_gbl_gpe_info) {		ACPI_MEM_FREE (acpi_gbl_gpe_registers);		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not allocate the Gpe_info block\n"));		return_ACPI_STATUS (AE_NO_MEMORY);	}	/* Set the Gpe validation table to GPE_INVALID */	MEMSET (acpi_gbl_gpe_valid, (int) ACPI_GPE_INVALID, ACPI_NUM_GPE);	/*	 * Initialize the Gpe information and validation blocks.  A goal of these	 * blocks is to hide the fact that there are two separate GPE register sets	 * In a given block, the status registers occupy the first half, and	 * the enable registers occupy the second half.	 */	/* GPE Block 0 */	register_index = 0;	for (i = 0; i < gpe0register_count; i++) {		acpi_gbl_gpe_registers[register_index].status_addr =				 (u16) (ACPI_GET_ADDRESS (acpi_gbl_FADT->Xgpe0blk.address) + i);		acpi_gbl_gpe_registers[register_index].enable_addr =				 (u16) (ACPI_GET_ADDRESS (acpi_gbl_FADT->Xgpe0blk.address) + i + gpe0register_count);		acpi_gbl_gpe_registers[register_index].gpe_base = (u8) MUL_8 (i);		for (j = 0; j < 8; j++) {			gpe_number = acpi_gbl_gpe_registers[register_index].gpe_base + j;			acpi_gbl_gpe_valid[gpe_number] = (u8) register_index;		}		/*		 * Clear the status/enable registers.  Note that status registers		 * are cleared by writing a '1', while enable registers are cleared		 * by writing a '0'.		 */		acpi_os_write_port (acpi_gbl_gpe_registers[register_index].enable_addr, 0x00, 8);		acpi_os_write_port (acpi_gbl_gpe_registers[register_index].status_addr, 0xFF, 8);		register_index++;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -