evxface.c revision 71867
167754Smsmith/****************************************************************************** 267754Smsmith * 367754Smsmith * Module Name: evxface - External interfaces for ACPI events 471867Smsmith * $Revision: 101 $ 567754Smsmith * 667754Smsmith *****************************************************************************/ 767754Smsmith 867754Smsmith/****************************************************************************** 967754Smsmith * 1067754Smsmith * 1. Copyright Notice 1167754Smsmith * 1271867Smsmith * Some or all of this work - Copyright (c) 1999, 2000, 2001, Intel Corp. 1370243Smsmith * All rights reserved. 1467754Smsmith * 1567754Smsmith * 2. License 1667754Smsmith * 1767754Smsmith * 2.1. This is your license from Intel Corp. under its intellectual property 1867754Smsmith * rights. You may have additional license terms from the party that provided 1967754Smsmith * you this software, covering your right to use that party's intellectual 2067754Smsmith * property rights. 2167754Smsmith * 2267754Smsmith * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 2367754Smsmith * copy of the source code appearing in this file ("Covered Code") an 2467754Smsmith * irrevocable, perpetual, worldwide license under Intel's copyrights in the 2567754Smsmith * base code distributed originally by Intel ("Original Intel Code") to copy, 2667754Smsmith * make derivatives, distribute, use and display any portion of the Covered 2767754Smsmith * Code in any form, with the right to sublicense such rights; and 2867754Smsmith * 2967754Smsmith * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 3067754Smsmith * license (with the right to sublicense), under only those claims of Intel 3167754Smsmith * patents that are infringed by the Original Intel Code, to make, use, sell, 3267754Smsmith * offer to sell, and import the Covered Code and derivative works thereof 3367754Smsmith * solely to the minimum extent necessary to exercise the above copyright 3467754Smsmith * license, and in no event shall the patent license extend to any additions 3567754Smsmith * to or modifications of the Original Intel Code. No other license or right 3667754Smsmith * is granted directly or by implication, estoppel or otherwise; 3767754Smsmith * 3867754Smsmith * The above copyright and patent license is granted only if the following 3967754Smsmith * conditions are met: 4067754Smsmith * 4167754Smsmith * 3. Conditions 4267754Smsmith * 4367754Smsmith * 3.1. Redistribution of Source with Rights to Further Distribute Source. 4467754Smsmith * Redistribution of source code of any substantial prton of the Covered 4567754Smsmith * Code or modification with rights to further distribute source must include 4667754Smsmith * the above Copyright Notice, the above License, this list of Conditions, 4767754Smsmith * and the following Disclaimer and Export Compliance provision. In addition, 4867754Smsmith * Licensee must cause all Covered Code to which Licensee contributes to 4967754Smsmith * contain a file documenting the changes Licensee made to create that Covered 5067754Smsmith * Code and the date of any change. Licensee must include in that file the 5167754Smsmith * documentation of any changes made by any predecessor Licensee. Licensee 5267754Smsmith * must include a prominent statement that the modification is derived, 5367754Smsmith * directly or indirectly, from Original Intel Code. 5467754Smsmith * 5567754Smsmith * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 5667754Smsmith * Redistribution of source code of any substantial portion of the Covered 5767754Smsmith * Code or modification without rights to further distribute source must 5867754Smsmith * include the following Disclaimer and Export Compliance provision in the 5967754Smsmith * documentation and/or other materials provided with distribution. In 6067754Smsmith * addition, Licensee may not authorize further sublicense of source of any 6167754Smsmith * portion of the Covered Code, and must include terms to the effect that the 6267754Smsmith * license from Licensee to its licensee is limited to the intellectual 6367754Smsmith * property embodied in the software Licensee provides to its licensee, and 6467754Smsmith * not to intellectual property embodied in modifications its licensee may 6567754Smsmith * make. 6667754Smsmith * 6767754Smsmith * 3.3. Redistribution of Executable. Redistribution in executable form of any 6867754Smsmith * substantial portion of the Covered Code or modification must reproduce the 6967754Smsmith * above Copyright Notice, and the following Disclaimer and Export Compliance 7067754Smsmith * provision in the documentation and/or other materials provided with the 7167754Smsmith * distribution. 7267754Smsmith * 7367754Smsmith * 3.4. Intel retains all right, title, and interest in and to the Original 7467754Smsmith * Intel Code. 7567754Smsmith * 7667754Smsmith * 3.5. Neither the name Intel nor any other trademark owned or controlled by 7767754Smsmith * Intel shall be used in advertising or otherwise to promote the sale, use or 7867754Smsmith * other dealings in products derived from or relating to the Covered Code 7967754Smsmith * without prior written authorization from Intel. 8067754Smsmith * 8167754Smsmith * 4. Disclaimer and Export Compliance 8267754Smsmith * 8367754Smsmith * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 8467754Smsmith * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 8567754Smsmith * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 8667754Smsmith * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 8767754Smsmith * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 8867754Smsmith * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 8967754Smsmith * PARTICULAR PURPOSE. 9067754Smsmith * 9167754Smsmith * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 9267754Smsmith * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 9367754Smsmith * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 9467754Smsmith * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 9567754Smsmith * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 9667754Smsmith * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 9767754Smsmith * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 9867754Smsmith * LIMITED REMEDY. 9967754Smsmith * 10067754Smsmith * 4.3. Licensee shall not export, either directly or indirectly, any of this 10167754Smsmith * software or system incorporating such software without first obtaining any 10267754Smsmith * required license or other approval from the U. S. Department of Commerce or 10367754Smsmith * any other agency or department of the United States Government. In the 10467754Smsmith * event Licensee exports any such software from the United States or 10567754Smsmith * re-exports any such software from a foreign destination, Licensee shall 10667754Smsmith * ensure that the distribution and export/re-export of the software is in 10767754Smsmith * compliance with all laws, regulations, orders, or other restrictions of the 10867754Smsmith * U.S. Export Administration Regulations. Licensee agrees that neither it nor 10967754Smsmith * any of its subsidiaries will export/re-export any technical data, process, 11067754Smsmith * software, or service, directly or indirectly, to any country for which the 11167754Smsmith * United States government or any agency thereof requires an export license, 11267754Smsmith * other governmental approval, or letter of assurance, without first obtaining 11367754Smsmith * such license, approval or letter. 11467754Smsmith * 11567754Smsmith *****************************************************************************/ 11667754Smsmith 11767754Smsmith 11867754Smsmith#define __EVXFACE_C__ 11967754Smsmith 12067754Smsmith#include "acpi.h" 12167754Smsmith#include "achware.h" 12267754Smsmith#include "acnamesp.h" 12367754Smsmith#include "acevents.h" 12467754Smsmith#include "amlcode.h" 12567754Smsmith#include "acinterp.h" 12667754Smsmith 12767754Smsmith#define _COMPONENT EVENT_HANDLING 12867754Smsmith MODULE_NAME ("evxface") 12967754Smsmith 13067754Smsmith 13167754Smsmith/****************************************************************************** 13267754Smsmith * 13367754Smsmith * FUNCTION: AcpiInstallFixedEventHandler 13467754Smsmith * 13567754Smsmith * PARAMETERS: Event - Event type to enable. 13667754Smsmith * Handler - Pointer to the handler function for the 13767754Smsmith * event 13867754Smsmith * Context - Value passed to the handler on each GPE 13967754Smsmith * 14067754Smsmith * RETURN: Status 14167754Smsmith * 14267754Smsmith * DESCRIPTION: Saves the pointer to the handler function and then enables the 14367754Smsmith * event. 14467754Smsmith * 14567754Smsmith ******************************************************************************/ 14667754Smsmith 14767754SmsmithACPI_STATUS 14867754SmsmithAcpiInstallFixedEventHandler ( 14967754Smsmith UINT32 Event, 15067754Smsmith FIXED_EVENT_HANDLER Handler, 15167754Smsmith void *Context) 15267754Smsmith{ 15367754Smsmith ACPI_STATUS Status = AE_OK; 15467754Smsmith 15567754Smsmith 15667754Smsmith FUNCTION_TRACE ("AcpiInstallFixedEventHandler"); 15767754Smsmith 15867754Smsmith 15967754Smsmith /* Sanity check the parameters. */ 16067754Smsmith 16167754Smsmith if (Event >= NUM_FIXED_EVENTS) 16267754Smsmith { 16367754Smsmith return_ACPI_STATUS (AE_BAD_PARAMETER); 16467754Smsmith } 16567754Smsmith 16667754Smsmith AcpiCmAcquireMutex (ACPI_MTX_EVENTS); 16767754Smsmith 16867754Smsmith /* Don't allow two handlers. */ 16967754Smsmith 17067754Smsmith if (NULL != AcpiGbl_FixedEventHandlers[Event].Handler) 17167754Smsmith { 17267754Smsmith Status = AE_EXIST; 17367754Smsmith goto Cleanup; 17467754Smsmith } 17567754Smsmith 17667754Smsmith 17767754Smsmith /* Install the handler before enabling the event - just in case... */ 17867754Smsmith 17967754Smsmith AcpiGbl_FixedEventHandlers[Event].Handler = Handler; 18067754Smsmith AcpiGbl_FixedEventHandlers[Event].Context = Context; 18167754Smsmith 18269450Smsmith Status = AcpiEnableEvent(Event, ACPI_EVENT_FIXED); 18369450Smsmith 18469450Smsmith if (!ACPI_SUCCESS(Status)) 18567754Smsmith { 18669450Smsmith DEBUG_PRINT (ACPI_WARN, ("Could not enable fixed event.\n")); 18767754Smsmith 18867754Smsmith /* Remove the handler */ 18967754Smsmith 19067754Smsmith AcpiGbl_FixedEventHandlers[Event].Handler = NULL; 19167754Smsmith AcpiGbl_FixedEventHandlers[Event].Context = NULL; 19267754Smsmith 19367754Smsmith Status = AE_ERROR; 19467754Smsmith goto Cleanup; 19567754Smsmith } 19667754Smsmith 19767754Smsmith DEBUG_PRINT (ACPI_INFO, 19869746Smsmith ("Enabled fixed event %X, Handler=%p\n", Event, Handler)); 19967754Smsmith 20067754Smsmith 20167754SmsmithCleanup: 20267754Smsmith AcpiCmReleaseMutex (ACPI_MTX_EVENTS); 20367754Smsmith return_ACPI_STATUS (Status); 20467754Smsmith} 20567754Smsmith 20667754Smsmith 20767754Smsmith/****************************************************************************** 20867754Smsmith * 20967754Smsmith * FUNCTION: AcpiRemoveFixedEventHandler 21067754Smsmith * 21167754Smsmith * PARAMETERS: Event - Event type to disable. 21267754Smsmith * Handler - Address of the handler 21367754Smsmith * 21467754Smsmith * RETURN: Status 21567754Smsmith * 21667754Smsmith * DESCRIPTION: Disables the event and unregisters the event handler. 21767754Smsmith * 21867754Smsmith ******************************************************************************/ 21967754Smsmith 22067754SmsmithACPI_STATUS 22167754SmsmithAcpiRemoveFixedEventHandler ( 22267754Smsmith UINT32 Event, 22367754Smsmith FIXED_EVENT_HANDLER Handler) 22467754Smsmith{ 22567754Smsmith ACPI_STATUS Status = AE_OK; 22667754Smsmith 22767754Smsmith 22867754Smsmith FUNCTION_TRACE ("AcpiRemoveFixedEventHandler"); 22967754Smsmith 23067754Smsmith 23167754Smsmith /* Sanity check the parameters. */ 23267754Smsmith 23367754Smsmith if (Event >= NUM_FIXED_EVENTS) 23467754Smsmith { 23567754Smsmith return_ACPI_STATUS (AE_BAD_PARAMETER); 23667754Smsmith } 23767754Smsmith 23867754Smsmith AcpiCmAcquireMutex (ACPI_MTX_EVENTS); 23967754Smsmith 24067754Smsmith /* Disable the event before removing the handler - just in case... */ 24167754Smsmith 24269450Smsmith Status = AcpiDisableEvent(Event, ACPI_EVENT_FIXED); 24369450Smsmith 24469450Smsmith if (!ACPI_SUCCESS(Status)) 24567754Smsmith { 24667754Smsmith DEBUG_PRINT (ACPI_WARN, 24767754Smsmith ("Could not write to fixed event enable register.\n")); 24869450Smsmith 24967754Smsmith Status = AE_ERROR; 25069450Smsmith AcpiCmReleaseMutex (ACPI_MTX_EVENTS); 25169450Smsmith return_ACPI_STATUS (Status); 25267754Smsmith } 25367754Smsmith 25467754Smsmith /* Remove the handler */ 25567754Smsmith 25667754Smsmith AcpiGbl_FixedEventHandlers[Event].Handler = NULL; 25767754Smsmith AcpiGbl_FixedEventHandlers[Event].Context = NULL; 25867754Smsmith 25969746Smsmith DEBUG_PRINT (ACPI_INFO, ("Disabled fixed event %X.\n", Event)); 26067754Smsmith 26167754Smsmith AcpiCmReleaseMutex (ACPI_MTX_EVENTS); 26267754Smsmith return_ACPI_STATUS (Status); 26367754Smsmith} 26467754Smsmith 26567754Smsmith 26667754Smsmith/****************************************************************************** 26767754Smsmith * 26867754Smsmith * FUNCTION: AcpiInstallNotifyHandler 26967754Smsmith * 27067754Smsmith * PARAMETERS: Device - The device for which notifies will be handled 27167754Smsmith * HandlerType - The type of handler: 27267754Smsmith * ACPI_SYSTEM_NOTIFY: SystemHandler (00-7f) 27367754Smsmith * ACPI_DEVICE_NOTIFY: DriverHandler (80-ff) 27467754Smsmith * Handler - Address of the handler 27567754Smsmith * Context - Value passed to the handler on each GPE 27667754Smsmith * 27767754Smsmith * RETURN: Status 27867754Smsmith * 27967754Smsmith * DESCRIPTION: Install a handler for notifies on an ACPI device 28067754Smsmith * 28167754Smsmith ******************************************************************************/ 28267754Smsmith 28367754SmsmithACPI_STATUS 28467754SmsmithAcpiInstallNotifyHandler ( 28567754Smsmith ACPI_HANDLE Device, 28667754Smsmith UINT32 HandlerType, 28767754Smsmith NOTIFY_HANDLER Handler, 28867754Smsmith void *Context) 28967754Smsmith{ 29067754Smsmith ACPI_OPERAND_OBJECT *ObjDesc; 29167754Smsmith ACPI_OPERAND_OBJECT *NotifyObj; 29267754Smsmith ACPI_NAMESPACE_NODE *DeviceNode; 29367754Smsmith ACPI_STATUS Status = AE_OK; 29467754Smsmith 29567754Smsmith 29667754Smsmith FUNCTION_TRACE ("AcpiInstallNotifyHandler"); 29767754Smsmith 29867754Smsmith 29967754Smsmith /* Parameter validation */ 30067754Smsmith 30167754Smsmith if ((!Handler) || 30267754Smsmith (HandlerType > ACPI_MAX_NOTIFY_HANDLER_TYPE)) 30367754Smsmith { 30467754Smsmith return_ACPI_STATUS (AE_BAD_PARAMETER); 30567754Smsmith } 30667754Smsmith 30771867Smsmith AcpiCmAcquireMutex (ACPI_MTX_NAMESPACE); 30871867Smsmith 30967754Smsmith /* Convert and validate the device handle */ 31067754Smsmith 31167754Smsmith DeviceNode = AcpiNsConvertHandleToEntry (Device); 31267754Smsmith if (!DeviceNode) 31367754Smsmith { 31467754Smsmith Status = AE_BAD_PARAMETER; 31567754Smsmith goto UnlockAndExit; 31667754Smsmith } 31767754Smsmith 31867754Smsmith /* 31971867Smsmith * Root Object: 32071867Smsmith * ------------ 32171867Smsmith * Registering a notify handler on the root object indicates that the 32271867Smsmith * caller wishes to receive notifications for all objects. Note that 32371867Smsmith * only one <external> global handler can be regsitered (per notify type). 32467754Smsmith */ 32567754Smsmith if (Device == ACPI_ROOT_OBJECT) 32667754Smsmith { 32771867Smsmith /* Make sure the handler is not already installed */ 32867754Smsmith 32967754Smsmith if (((HandlerType == ACPI_SYSTEM_NOTIFY) && 33067754Smsmith AcpiGbl_SysNotify.Handler) || 33167754Smsmith ((HandlerType == ACPI_DEVICE_NOTIFY) && 33267754Smsmith AcpiGbl_DrvNotify.Handler)) 33367754Smsmith { 33467754Smsmith Status = AE_EXIST; 33567754Smsmith goto UnlockAndExit; 33667754Smsmith } 33767754Smsmith 33867754Smsmith if (HandlerType == ACPI_SYSTEM_NOTIFY) 33967754Smsmith { 34067754Smsmith AcpiGbl_SysNotify.Node = DeviceNode; 34167754Smsmith AcpiGbl_SysNotify.Handler = Handler; 34267754Smsmith AcpiGbl_SysNotify.Context = Context; 34367754Smsmith } 34471867Smsmith else /* ACPI_DEVICE_NOTIFY */ 34567754Smsmith { 34667754Smsmith AcpiGbl_DrvNotify.Node = DeviceNode; 34767754Smsmith AcpiGbl_DrvNotify.Handler = Handler; 34867754Smsmith AcpiGbl_DrvNotify.Context = Context; 34967754Smsmith } 35067754Smsmith 35167754Smsmith /* Global notify handler installed */ 35267754Smsmith } 35367754Smsmith 35467754Smsmith /* 35571867Smsmith * Other Objects: 35671867Smsmith * -------------- 35771867Smsmith * Caller will only receive notifications specific to the target object. 35871867Smsmith * Note that only certain object types can receive notifications. 35967754Smsmith */ 36071867Smsmith else { 36167754Smsmith /* 36271867Smsmith * These are the ONLY objects that can receive ACPI notifications 36367754Smsmith */ 36471867Smsmith if ((DeviceNode->Type != ACPI_TYPE_DEVICE) && 36571867Smsmith (DeviceNode->Type != ACPI_TYPE_PROCESSOR) && 36671867Smsmith (DeviceNode->Type != ACPI_TYPE_POWER) && 36771867Smsmith (DeviceNode->Type != ACPI_TYPE_THERMAL)) 36867754Smsmith { 36971867Smsmith Status = AE_BAD_PARAMETER; 37067754Smsmith goto UnlockAndExit; 37167754Smsmith } 37267754Smsmith 37371867Smsmith /* Check for an existing internal object */ 37467754Smsmith 37571867Smsmith ObjDesc = AcpiNsGetAttachedObject ((ACPI_HANDLE) DeviceNode); 37671867Smsmith if (ObjDesc) 37767754Smsmith { 37871867Smsmith 37971867Smsmith /* Object exists - make sure there's no handler */ 38071867Smsmith 38171867Smsmith if (((HandlerType == ACPI_SYSTEM_NOTIFY) && 38271867Smsmith ObjDesc->Device.SysHandler) || 38371867Smsmith ((HandlerType == ACPI_DEVICE_NOTIFY) && 38471867Smsmith ObjDesc->Device.DrvHandler)) 38571867Smsmith { 38671867Smsmith Status = AE_EXIST; 38771867Smsmith goto UnlockAndExit; 38871867Smsmith } 38967754Smsmith } 39067754Smsmith 39171867Smsmith else 39271867Smsmith { 39371867Smsmith /* Create a new object */ 39467754Smsmith 39571867Smsmith ObjDesc = AcpiCmCreateInternalObject (DeviceNode->Type); 39671867Smsmith if (!ObjDesc) 39771867Smsmith { 39871867Smsmith Status = AE_NO_MEMORY; 39971867Smsmith goto UnlockAndExit; 40071867Smsmith } 40167754Smsmith 40271867Smsmith /* Attach new object to the Node */ 40371867Smsmith 40471867Smsmith Status = AcpiNsAttachObject (Device, ObjDesc, (UINT8) DeviceNode->Type); 40571867Smsmith 40671867Smsmith if (ACPI_FAILURE (Status)) 40771867Smsmith { 40871867Smsmith goto UnlockAndExit; 40971867Smsmith } 41071867Smsmith } 41171867Smsmith 41271867Smsmith /* Install the handler */ 41371867Smsmith 41471867Smsmith NotifyObj = AcpiCmCreateInternalObject (INTERNAL_TYPE_NOTIFY); 41571867Smsmith if (!NotifyObj) 41667754Smsmith { 41771867Smsmith Status = AE_NO_MEMORY; 41867754Smsmith goto UnlockAndExit; 41967754Smsmith } 42067754Smsmith 42171867Smsmith NotifyObj->NotifyHandler.Node = DeviceNode; 42271867Smsmith NotifyObj->NotifyHandler.Handler = Handler; 42371867Smsmith NotifyObj->NotifyHandler.Context = Context; 42467754Smsmith 42567754Smsmith 42671867Smsmith if (HandlerType == ACPI_SYSTEM_NOTIFY) 42771867Smsmith { 42871867Smsmith ObjDesc->Device.SysHandler = NotifyObj; 42971867Smsmith } 43071867Smsmith else /* ACPI_DEVICE_NOTIFY */ 43171867Smsmith { 43271867Smsmith ObjDesc->Device.DrvHandler = NotifyObj; 43371867Smsmith } 43467754Smsmith } 43567754Smsmith 43667754SmsmithUnlockAndExit: 43767754Smsmith AcpiCmReleaseMutex (ACPI_MTX_NAMESPACE); 43867754Smsmith return_ACPI_STATUS (Status); 43967754Smsmith} 44067754Smsmith 44167754Smsmith 44267754Smsmith/***************************************************************************** 44367754Smsmith * 44467754Smsmith * FUNCTION: AcpiRemoveNotifyHandler 44567754Smsmith * 44667754Smsmith * PARAMETERS: Device - The device for which notifies will be handled 44767754Smsmith * HandlerType - The type of handler: 44867754Smsmith * ACPI_SYSTEM_NOTIFY: SystemHandler (00-7f) 44967754Smsmith * ACPI_DEVICE_NOTIFY: DriverHandler (80-ff) 45067754Smsmith * Handler - Address of the handler 45167754Smsmith * RETURN: Status 45267754Smsmith * 45367754Smsmith * DESCRIPTION: Remove a handler for notifies on an ACPI device 45467754Smsmith * 45567754Smsmith ******************************************************************************/ 45667754Smsmith 45767754SmsmithACPI_STATUS 45867754SmsmithAcpiRemoveNotifyHandler ( 45967754Smsmith ACPI_HANDLE Device, 46067754Smsmith UINT32 HandlerType, 46167754Smsmith NOTIFY_HANDLER Handler) 46267754Smsmith{ 46367754Smsmith ACPI_OPERAND_OBJECT *NotifyObj; 46467754Smsmith ACPI_OPERAND_OBJECT *ObjDesc; 46567754Smsmith ACPI_NAMESPACE_NODE *DeviceNode; 46667754Smsmith ACPI_STATUS Status = AE_OK; 46767754Smsmith 46867754Smsmith FUNCTION_TRACE ("AcpiRemoveNotifyHandler"); 46967754Smsmith 47067754Smsmith /* Parameter validation */ 47167754Smsmith 47267754Smsmith if ((!Handler) || 47367754Smsmith (HandlerType > ACPI_MAX_NOTIFY_HANDLER_TYPE)) 47467754Smsmith { 47567754Smsmith return_ACPI_STATUS (AE_BAD_PARAMETER); 47667754Smsmith } 47767754Smsmith 47867754Smsmith AcpiCmAcquireMutex (ACPI_MTX_NAMESPACE); 47967754Smsmith 48067754Smsmith /* Convert and validate the device handle */ 48167754Smsmith 48267754Smsmith DeviceNode = AcpiNsConvertHandleToEntry (Device); 48367754Smsmith if (!DeviceNode) 48467754Smsmith { 48567754Smsmith Status = AE_BAD_PARAMETER; 48667754Smsmith goto UnlockAndExit; 48767754Smsmith } 48867754Smsmith 48967754Smsmith /* 49071867Smsmith * Root Object: 49171867Smsmith * ------------ 49267754Smsmith */ 49371867Smsmith if (Device == ACPI_ROOT_OBJECT) { 49467754Smsmith 49571867Smsmith DEBUG_PRINT(ACPI_INFO, ("Removing notify handler for ROOT object.\n")); 49667754Smsmith 49771867Smsmith if (((HandlerType == ACPI_SYSTEM_NOTIFY) && 49871867Smsmith !AcpiGbl_SysNotify.Handler) || 49971867Smsmith ((HandlerType == ACPI_DEVICE_NOTIFY) && 50071867Smsmith !AcpiGbl_DrvNotify.Handler)) 50171867Smsmith { 50271867Smsmith Status = AE_NOT_EXIST; 50371867Smsmith goto UnlockAndExit; 50471867Smsmith } 50567754Smsmith 50671867Smsmith if (HandlerType == ACPI_SYSTEM_NOTIFY) { 50771867Smsmith AcpiGbl_SysNotify.Node = NULL; 50871867Smsmith AcpiGbl_SysNotify.Handler = NULL; 50971867Smsmith AcpiGbl_SysNotify.Context = NULL; 51071867Smsmith } 51171867Smsmith else { 51271867Smsmith AcpiGbl_DrvNotify.Node = NULL; 51371867Smsmith AcpiGbl_DrvNotify.Handler = NULL; 51471867Smsmith AcpiGbl_DrvNotify.Context = NULL; 51571867Smsmith } 51667754Smsmith } 51767754Smsmith 51867754Smsmith /* 51971867Smsmith * Other Objects: 52071867Smsmith * -------------- 52167754Smsmith */ 52271867Smsmith else { 52371867Smsmith /* 52471867Smsmith * These are the ONLY objects that can receive ACPI notifications 52571867Smsmith */ 52671867Smsmith if ((DeviceNode->Type != ACPI_TYPE_DEVICE) && 52771867Smsmith (DeviceNode->Type != ACPI_TYPE_PROCESSOR) && 52871867Smsmith (DeviceNode->Type != ACPI_TYPE_POWER) && 52971867Smsmith (DeviceNode->Type != ACPI_TYPE_THERMAL)) 53071867Smsmith { 53171867Smsmith Status = AE_BAD_PARAMETER; 53271867Smsmith goto UnlockAndExit; 53371867Smsmith } 53467754Smsmith 53571867Smsmith /* Check for an existing internal object */ 53667754Smsmith 53771867Smsmith ObjDesc = AcpiNsGetAttachedObject ((ACPI_HANDLE) DeviceNode); 53871867Smsmith if (!ObjDesc) 53971867Smsmith { 54071867Smsmith Status = AE_NOT_EXIST; 54171867Smsmith goto UnlockAndExit; 54271867Smsmith } 54367754Smsmith 54471867Smsmith /* Object exists - make sure there's an existing handler */ 54571867Smsmith 54671867Smsmith if (HandlerType == ACPI_SYSTEM_NOTIFY) 54771867Smsmith { 54871867Smsmith NotifyObj = ObjDesc->Device.SysHandler; 54971867Smsmith } 55071867Smsmith else 55171867Smsmith { 55271867Smsmith NotifyObj = ObjDesc->Device.DrvHandler; 55371867Smsmith } 55471867Smsmith 55571867Smsmith if ((!NotifyObj) || 55671867Smsmith (NotifyObj->NotifyHandler.Handler != Handler)) 55771867Smsmith { 55871867Smsmith Status = AE_BAD_PARAMETER; 55971867Smsmith goto UnlockAndExit; 56071867Smsmith } 56171867Smsmith 56271867Smsmith /* Remove the handler */ 56371867Smsmith 56471867Smsmith if (HandlerType == ACPI_SYSTEM_NOTIFY) 56571867Smsmith { 56671867Smsmith ObjDesc->Device.SysHandler = NULL; 56771867Smsmith } 56871867Smsmith else 56971867Smsmith { 57071867Smsmith ObjDesc->Device.DrvHandler = NULL; 57171867Smsmith } 57271867Smsmith 57371867Smsmith AcpiCmRemoveReference (NotifyObj); 57467754Smsmith } 57567754Smsmith 57667754Smsmith 57767754SmsmithUnlockAndExit: 57867754Smsmith AcpiCmReleaseMutex (ACPI_MTX_NAMESPACE); 57967754Smsmith return_ACPI_STATUS (Status); 58067754Smsmith} 58167754Smsmith 58271867Smsmith 58367754Smsmith/****************************************************************************** 58467754Smsmith * 58567754Smsmith * FUNCTION: AcpiInstallGpeHandler 58667754Smsmith * 58767754Smsmith * PARAMETERS: GpeNumber - The GPE number. The numbering scheme is 58867754Smsmith * bank 0 first, then bank 1. 58967754Smsmith * Type - Whether this GPE should be treated as an 59067754Smsmith * edge- or level-triggered interrupt. 59167754Smsmith * Handler - Address of the handler 59267754Smsmith * Context - Value passed to the handler on each GPE 59367754Smsmith * 59467754Smsmith * RETURN: Status 59567754Smsmith * 59667754Smsmith * DESCRIPTION: Install a handler for a General Purpose Event. 59767754Smsmith * 59867754Smsmith ******************************************************************************/ 59967754Smsmith 60067754SmsmithACPI_STATUS 60167754SmsmithAcpiInstallGpeHandler ( 60267754Smsmith UINT32 GpeNumber, 60367754Smsmith UINT32 Type, 60467754Smsmith GPE_HANDLER Handler, 60567754Smsmith void *Context) 60667754Smsmith{ 60767754Smsmith ACPI_STATUS Status = AE_OK; 60867754Smsmith 60967754Smsmith FUNCTION_TRACE ("AcpiInstallGpeHandler"); 61067754Smsmith 61167754Smsmith /* Parameter validation */ 61267754Smsmith 61367754Smsmith if (!Handler || (GpeNumber > NUM_GPE)) 61467754Smsmith { 61567754Smsmith return_ACPI_STATUS (AE_BAD_PARAMETER); 61667754Smsmith } 61767754Smsmith 61867754Smsmith /* Ensure that we have a valid GPE number */ 61967754Smsmith 62067754Smsmith if (AcpiGbl_GpeValid[GpeNumber] == ACPI_GPE_INVALID) 62167754Smsmith { 62267754Smsmith return_ACPI_STATUS (AE_BAD_PARAMETER); 62367754Smsmith } 62467754Smsmith 62567754Smsmith AcpiCmAcquireMutex (ACPI_MTX_EVENTS); 62667754Smsmith 62767754Smsmith /* Make sure that there isn't a handler there already */ 62867754Smsmith 62967754Smsmith if (AcpiGbl_GpeInfo[GpeNumber].Handler) 63067754Smsmith { 63167754Smsmith Status = AE_EXIST; 63267754Smsmith goto Cleanup; 63367754Smsmith } 63467754Smsmith 63567754Smsmith /* Install the handler */ 63667754Smsmith 63767754Smsmith AcpiGbl_GpeInfo[GpeNumber].Handler = Handler; 63867754Smsmith AcpiGbl_GpeInfo[GpeNumber].Context = Context; 63967754Smsmith AcpiGbl_GpeInfo[GpeNumber].Type = (UINT8) Type; 64067754Smsmith 64167754Smsmith /* Clear the GPE (of stale events), the enable it */ 64267754Smsmith 64367754Smsmith AcpiHwClearGpe (GpeNumber); 64467754Smsmith AcpiHwEnableGpe (GpeNumber); 64567754Smsmith 64667754SmsmithCleanup: 64767754Smsmith AcpiCmReleaseMutex (ACPI_MTX_EVENTS); 64867754Smsmith return_ACPI_STATUS (Status); 64967754Smsmith} 65067754Smsmith 65167754Smsmith 65267754Smsmith/****************************************************************************** 65367754Smsmith * 65467754Smsmith * FUNCTION: AcpiRemoveGpeHandler 65567754Smsmith * 65667754Smsmith * PARAMETERS: GpeNumber - The event to remove a handler 65767754Smsmith * Handler - Address of the handler 65867754Smsmith * 65967754Smsmith * RETURN: Status 66067754Smsmith * 66167754Smsmith * DESCRIPTION: Remove a handler for a General Purpose AcpiEvent. 66267754Smsmith * 66367754Smsmith ******************************************************************************/ 66467754Smsmith 66567754SmsmithACPI_STATUS 66667754SmsmithAcpiRemoveGpeHandler ( 66767754Smsmith UINT32 GpeNumber, 66867754Smsmith GPE_HANDLER Handler) 66967754Smsmith{ 67067754Smsmith ACPI_STATUS Status = AE_OK; 67167754Smsmith 67267754Smsmith 67367754Smsmith FUNCTION_TRACE ("AcpiRemoveGpeHandler"); 67467754Smsmith 67567754Smsmith 67667754Smsmith /* Parameter validation */ 67767754Smsmith 67867754Smsmith if (!Handler || (GpeNumber > NUM_GPE)) 67967754Smsmith { 68067754Smsmith return_ACPI_STATUS (AE_BAD_PARAMETER); 68167754Smsmith } 68267754Smsmith 68367754Smsmith /* Ensure that we have a valid GPE number */ 68467754Smsmith 68567754Smsmith if (AcpiGbl_GpeValid[GpeNumber] == ACPI_GPE_INVALID) 68667754Smsmith { 68767754Smsmith return_ACPI_STATUS (AE_BAD_PARAMETER); 68867754Smsmith } 68967754Smsmith 69067754Smsmith /* Disable the GPE before removing the handler */ 69167754Smsmith 69267754Smsmith AcpiHwDisableGpe (GpeNumber); 69367754Smsmith 69467754Smsmith AcpiCmAcquireMutex (ACPI_MTX_EVENTS); 69567754Smsmith 69667754Smsmith /* Make sure that the installed handler is the same */ 69767754Smsmith 69867754Smsmith if (AcpiGbl_GpeInfo[GpeNumber].Handler != Handler) 69967754Smsmith { 70067754Smsmith AcpiHwEnableGpe (GpeNumber); 70167754Smsmith Status = AE_BAD_PARAMETER; 70267754Smsmith goto Cleanup; 70367754Smsmith } 70467754Smsmith 70567754Smsmith /* Remove the handler */ 70667754Smsmith 70767754Smsmith AcpiGbl_GpeInfo[GpeNumber].Handler = NULL; 70867754Smsmith AcpiGbl_GpeInfo[GpeNumber].Context = NULL; 70967754Smsmith 71067754SmsmithCleanup: 71167754Smsmith AcpiCmReleaseMutex (ACPI_MTX_EVENTS); 71267754Smsmith return_ACPI_STATUS (Status); 71367754Smsmith} 71467754Smsmith 71567754Smsmith 71667754Smsmith/****************************************************************************** 71767754Smsmith * 71867754Smsmith * FUNCTION: AcpiAcquireGlobalLock 71967754Smsmith * 72067754Smsmith * PARAMETERS: Timeout - How long the caller is willing to wait 72167754Smsmith * OutHandle - A handle to the lock if acquired 72267754Smsmith * 72367754Smsmith * RETURN: Status 72467754Smsmith * 72567754Smsmith * DESCRIPTION: Acquire the ACPI Global Lock 72667754Smsmith * 72767754Smsmith ******************************************************************************/ 72867754SmsmithACPI_STATUS 72967754SmsmithAcpiAcquireGlobalLock ( 73067754Smsmith void) 73167754Smsmith{ 73267754Smsmith ACPI_STATUS Status; 73367754Smsmith 73467754Smsmith 73567754Smsmith AcpiAmlEnterInterpreter (); 73667754Smsmith 73767754Smsmith /* 73867754Smsmith * TBD: [Restructure] add timeout param to internal interface, and 73967754Smsmith * perhaps INTERPRETER_LOCKED 74067754Smsmith */ 74167754Smsmith 74267754Smsmith Status = AcpiEvAcquireGlobalLock (); 74367754Smsmith AcpiAmlExitInterpreter (); 74467754Smsmith 74567754Smsmith return (Status); 74667754Smsmith} 74767754Smsmith 74867754Smsmith 74967754Smsmith/****************************************************************************** 75067754Smsmith * 75167754Smsmith * FUNCTION: AcpiReleaseGlobalLock 75267754Smsmith * 75367754Smsmith * PARAMETERS: Handle - Returned from AcpiAcquireGlobalLock 75467754Smsmith * 75567754Smsmith * RETURN: Status 75667754Smsmith * 75767754Smsmith * DESCRIPTION: Release the ACPI Global Lock 75867754Smsmith * 75967754Smsmith ******************************************************************************/ 76067754Smsmith 76167754SmsmithACPI_STATUS 76267754SmsmithAcpiReleaseGlobalLock ( 76367754Smsmith void) 76467754Smsmith{ 76567754Smsmith AcpiEvReleaseGlobalLock (); 76667754Smsmith return (AE_OK); 76767754Smsmith} 76867754Smsmith 76967754Smsmith 770