/******************************************************************************1*2* Module Name: evevent - Fixed Event handling and dispatch3*4*****************************************************************************/56/*7* Copyright (C) 2000 - 2011, Intel Corp.8* All rights reserved.9*10* Redistribution and use in source and binary forms, with or without11* modification, are permitted provided that the following conditions12* are met:13* 1. Redistributions of source code must retain the above copyright14* notice, this list of conditions, and the following disclaimer,15* without modification.16* 2. Redistributions in binary form must reproduce at minimum a disclaimer17* substantially similar to the "NO WARRANTY" disclaimer below18* ("Disclaimer") and any redistribution must be conditioned upon19* including a substantially similar Disclaimer requirement for further20* binary redistribution.21* 3. Neither the names of the above-listed copyright holders nor the names22* of any contributors may be used to endorse or promote products derived23* from this software without specific prior written permission.24*25* Alternatively, this software may be distributed under the terms of the26* GNU General Public License ("GPL") version 2 as published by the Free27* Software Foundation.28*29* NO WARRANTY30* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS31* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT32* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR33* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT34* HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL35* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS36* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)37* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,38* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING39* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE40* POSSIBILITY OF SUCH DAMAGES.41*/4243#include <acpi/acpi.h>44#include "accommon.h"45#include "acevents.h"4647#define _COMPONENT ACPI_EVENTS48ACPI_MODULE_NAME("evevent")4950/* Local prototypes */51static acpi_status acpi_ev_fixed_event_initialize(void);5253static u32 acpi_ev_fixed_event_dispatch(u32 event);5455/*******************************************************************************56*57* FUNCTION: acpi_ev_initialize_events58*59* PARAMETERS: None60*61* RETURN: Status62*63* DESCRIPTION: Initialize global data structures for ACPI events (Fixed, GPE)64*65******************************************************************************/6667acpi_status acpi_ev_initialize_events(void)68{69acpi_status status;7071ACPI_FUNCTION_TRACE(ev_initialize_events);7273/*74* Initialize the Fixed and General Purpose Events. This is done prior to75* enabling SCIs to prevent interrupts from occurring before the handlers76* are installed.77*/78status = acpi_ev_fixed_event_initialize();79if (ACPI_FAILURE(status)) {80ACPI_EXCEPTION((AE_INFO, status,81"Unable to initialize fixed events"));82return_ACPI_STATUS(status);83}8485status = acpi_ev_gpe_initialize();86if (ACPI_FAILURE(status)) {87ACPI_EXCEPTION((AE_INFO, status,88"Unable to initialize general purpose events"));89return_ACPI_STATUS(status);90}9192return_ACPI_STATUS(status);93}9495/*******************************************************************************96*97* FUNCTION: acpi_ev_install_xrupt_handlers98*99* PARAMETERS: None100*101* RETURN: Status102*103* DESCRIPTION: Install interrupt handlers for the SCI and Global Lock104*105******************************************************************************/106107acpi_status acpi_ev_install_xrupt_handlers(void)108{109acpi_status status;110111ACPI_FUNCTION_TRACE(ev_install_xrupt_handlers);112113/* Install the SCI handler */114115status = acpi_ev_install_sci_handler();116if (ACPI_FAILURE(status)) {117ACPI_EXCEPTION((AE_INFO, status,118"Unable to install System Control Interrupt handler"));119return_ACPI_STATUS(status);120}121122/* Install the handler for the Global Lock */123124status = acpi_ev_init_global_lock_handler();125if (ACPI_FAILURE(status)) {126ACPI_EXCEPTION((AE_INFO, status,127"Unable to initialize Global Lock handler"));128return_ACPI_STATUS(status);129}130131acpi_gbl_events_initialized = TRUE;132return_ACPI_STATUS(status);133}134135/*******************************************************************************136*137* FUNCTION: acpi_ev_fixed_event_initialize138*139* PARAMETERS: None140*141* RETURN: Status142*143* DESCRIPTION: Install the fixed event handlers and disable all fixed events.144*145******************************************************************************/146147static acpi_status acpi_ev_fixed_event_initialize(void)148{149u32 i;150acpi_status status;151152/*153* Initialize the structure that keeps track of fixed event handlers and154* enable the fixed events.155*/156for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) {157acpi_gbl_fixed_event_handlers[i].handler = NULL;158acpi_gbl_fixed_event_handlers[i].context = NULL;159160/* Disable the fixed event */161162if (acpi_gbl_fixed_event_info[i].enable_register_id != 0xFF) {163status =164acpi_write_bit_register(acpi_gbl_fixed_event_info165[i].enable_register_id,166ACPI_DISABLE_EVENT);167if (ACPI_FAILURE(status)) {168return (status);169}170}171}172173return (AE_OK);174}175176/*******************************************************************************177*178* FUNCTION: acpi_ev_fixed_event_detect179*180* PARAMETERS: None181*182* RETURN: INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED183*184* DESCRIPTION: Checks the PM status register for active fixed events185*186******************************************************************************/187188u32 acpi_ev_fixed_event_detect(void)189{190u32 int_status = ACPI_INTERRUPT_NOT_HANDLED;191u32 fixed_status;192u32 fixed_enable;193u32 i;194195ACPI_FUNCTION_NAME(ev_fixed_event_detect);196197/*198* Read the fixed feature status and enable registers, as all the cases199* depend on their values. Ignore errors here.200*/201(void)acpi_hw_register_read(ACPI_REGISTER_PM1_STATUS, &fixed_status);202(void)acpi_hw_register_read(ACPI_REGISTER_PM1_ENABLE, &fixed_enable);203204ACPI_DEBUG_PRINT((ACPI_DB_INTERRUPTS,205"Fixed Event Block: Enable %08X Status %08X\n",206fixed_enable, fixed_status));207208/*209* Check for all possible Fixed Events and dispatch those that are active210*/211for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) {212213/* Both the status and enable bits must be on for this event */214215if ((fixed_status & acpi_gbl_fixed_event_info[i].216status_bit_mask)217&& (fixed_enable & acpi_gbl_fixed_event_info[i].218enable_bit_mask)) {219/*220* Found an active (signalled) event. Invoke global event221* handler if present.222*/223acpi_fixed_event_count[i]++;224if (acpi_gbl_global_event_handler) {225acpi_gbl_global_event_handler226(ACPI_EVENT_TYPE_FIXED, NULL, i,227acpi_gbl_global_event_handler_context);228}229230int_status |= acpi_ev_fixed_event_dispatch(i);231}232}233234return (int_status);235}236237/*******************************************************************************238*239* FUNCTION: acpi_ev_fixed_event_dispatch240*241* PARAMETERS: Event - Event type242*243* RETURN: INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED244*245* DESCRIPTION: Clears the status bit for the requested event, calls the246* handler that previously registered for the event.247*248******************************************************************************/249250static u32 acpi_ev_fixed_event_dispatch(u32 event)251{252253ACPI_FUNCTION_ENTRY();254255/* Clear the status bit */256257(void)acpi_write_bit_register(acpi_gbl_fixed_event_info[event].258status_register_id, ACPI_CLEAR_STATUS);259260/*261* Make sure we've got a handler. If not, report an error. The event is262* disabled to prevent further interrupts.263*/264if (NULL == acpi_gbl_fixed_event_handlers[event].handler) {265(void)acpi_write_bit_register(acpi_gbl_fixed_event_info[event].266enable_register_id,267ACPI_DISABLE_EVENT);268269ACPI_ERROR((AE_INFO,270"No installed handler for fixed event [0x%08X]",271event));272273return (ACPI_INTERRUPT_NOT_HANDLED);274}275276/* Invoke the Fixed Event handler */277278return ((acpi_gbl_fixed_event_handlers[event].279handler) (acpi_gbl_fixed_event_handlers[event].context));280}281282283