evxface.c revision 71867
1124758Semax/******************************************************************************
2124758Semax *
3124758Semax * Module Name: evxface - External interfaces for ACPI events
4124758Semax *              $Revision: 101 $
5124758Semax *
6124758Semax *****************************************************************************/
7124758Semax
8124758Semax/******************************************************************************
9124758Semax *
10124758Semax * 1. Copyright Notice
11124758Semax *
12124758Semax * Some or all of this work - Copyright (c) 1999, 2000, 2001, Intel Corp.
13124758Semax * All rights reserved.
14124758Semax *
15124758Semax * 2. License
16124758Semax *
17124758Semax * 2.1. This is your license from Intel Corp. under its intellectual property
18124758Semax * rights.  You may have additional license terms from the party that provided
19124758Semax * you this software, covering your right to use that party's intellectual
20124758Semax * property rights.
21124758Semax *
22124758Semax * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
23124758Semax * copy of the source code appearing in this file ("Covered Code") an
24124758Semax * irrevocable, perpetual, worldwide license under Intel's copyrights in the
25124758Semax * base code distributed originally by Intel ("Original Intel Code") to copy,
26124758Semax * make derivatives, distribute, use and display any portion of the Covered
27124758Semax * Code in any form, with the right to sublicense such rights; and
28124758Semax *
29124758Semax * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
30124758Semax * license (with the right to sublicense), under only those claims of Intel
31124758Semax * patents that are infringed by the Original Intel Code, to make, use, sell,
32124758Semax * offer to sell, and import the Covered Code and derivative works thereof
33124758Semax * solely to the minimum extent necessary to exercise the above copyright
34124758Semax * license, and in no event shall the patent license extend to any additions
35124758Semax * to or modifications of the Original Intel Code.  No other license or right
36124758Semax * is granted directly or by implication, estoppel or otherwise;
37124758Semax *
38124758Semax * The above copyright and patent license is granted only if the following
39124758Semax * conditions are met:
40124758Semax *
41124758Semax * 3. Conditions
42124758Semax *
43124758Semax * 3.1. Redistribution of Source with Rights to Further Distribute Source.
44153176Semax * Redistribution of source code of any substantial prton of the Covered
45153176Semax * Code or modification with rights to further distribute source must include
46124758Semax * the above Copyright Notice, the above License, this list of Conditions,
47124758Semax * and the following Disclaimer and Export Compliance provision.  In addition,
48124758Semax * Licensee must cause all Covered Code to which Licensee contributes to
49124758Semax * contain a file documenting the changes Licensee made to create that Covered
50124758Semax * Code and the date of any change.  Licensee must include in that file the
51124758Semax * documentation of any changes made by any predecessor Licensee.  Licensee
52124758Semax * must include a prominent statement that the modification is derived,
53124758Semax * directly or indirectly, from Original Intel Code.
54124758Semax *
55124758Semax * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
56124758Semax * Redistribution of source code of any substantial portion of the Covered
57124758Semax * Code or modification without rights to further distribute source must
58124758Semax * include the following Disclaimer and Export Compliance provision in the
59124758Semax * documentation and/or other materials provided with distribution.  In
60124758Semax * addition, Licensee may not authorize further sublicense of source of any
61124758Semax * portion of the Covered Code, and must include terms to the effect that the
62124758Semax * license from Licensee to its licensee is limited to the intellectual
63124758Semax * property embodied in the software Licensee provides to its licensee, and
64124758Semax * not to intellectual property embodied in modifications its licensee may
65124758Semax * make.
66124758Semax *
67124758Semax * 3.3. Redistribution of Executable. Redistribution in executable form of any
68124758Semax * substantial portion of the Covered Code or modification must reproduce the
69124758Semax * above Copyright Notice, and the following Disclaimer and Export Compliance
70124758Semax * provision in the documentation and/or other materials provided with the
71124758Semax * distribution.
72124758Semax *
73124758Semax * 3.4. Intel retains all right, title, and interest in and to the Original
74124758Semax * Intel Code.
75124758Semax *
76124758Semax * 3.5. Neither the name Intel nor any other trademark owned or controlled by
77124758Semax * Intel shall be used in advertising or otherwise to promote the sale, use or
78124758Semax * other dealings in products derived from or relating to the Covered Code
79124758Semax * without prior written authorization from Intel.
80124758Semax *
81124758Semax * 4. Disclaimer and Export Compliance
82124758Semax *
83124758Semax * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
84124758Semax * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
85124758Semax * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
86124758Semax * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
87124758Semax * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
88124758Semax * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
89124758Semax * PARTICULAR PURPOSE.
90124758Semax *
91124758Semax * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
92124758Semax * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
93124758Semax * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
94124758Semax * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
95124758Semax * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
96124758Semax * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
97124758Semax * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
98124758Semax * LIMITED REMEDY.
99124758Semax *
100124758Semax * 4.3. Licensee shall not export, either directly or indirectly, any of this
101124758Semax * software or system incorporating such software without first obtaining any
102124758Semax * required license or other approval from the U. S. Department of Commerce or
103 * any other agency or department of the United States Government.  In the
104 * event Licensee exports any such software from the United States or
105 * re-exports any such software from a foreign destination, Licensee shall
106 * ensure that the distribution and export/re-export of the software is in
107 * compliance with all laws, regulations, orders, or other restrictions of the
108 * U.S. Export Administration Regulations. Licensee agrees that neither it nor
109 * any of its subsidiaries will export/re-export any technical data, process,
110 * software, or service, directly or indirectly, to any country for which the
111 * United States government or any agency thereof requires an export license,
112 * other governmental approval, or letter of assurance, without first obtaining
113 * such license, approval or letter.
114 *
115 *****************************************************************************/
116
117
118#define __EVXFACE_C__
119
120#include "acpi.h"
121#include "achware.h"
122#include "acnamesp.h"
123#include "acevents.h"
124#include "amlcode.h"
125#include "acinterp.h"
126
127#define _COMPONENT          EVENT_HANDLING
128        MODULE_NAME         ("evxface")
129
130
131/******************************************************************************
132 *
133 * FUNCTION:    AcpiInstallFixedEventHandler
134 *
135 * PARAMETERS:  Event           - Event type to enable.
136 *              Handler         - Pointer to the handler function for the
137 *                                event
138 *              Context         - Value passed to the handler on each GPE
139 *
140 * RETURN:      Status
141 *
142 * DESCRIPTION: Saves the pointer to the handler function and then enables the
143 *              event.
144 *
145 ******************************************************************************/
146
147ACPI_STATUS
148AcpiInstallFixedEventHandler (
149    UINT32                  Event,
150    FIXED_EVENT_HANDLER     Handler,
151    void                    *Context)
152{
153    ACPI_STATUS             Status = AE_OK;
154
155
156    FUNCTION_TRACE ("AcpiInstallFixedEventHandler");
157
158
159    /* Sanity check the parameters. */
160
161    if (Event >= NUM_FIXED_EVENTS)
162    {
163        return_ACPI_STATUS (AE_BAD_PARAMETER);
164    }
165
166    AcpiCmAcquireMutex (ACPI_MTX_EVENTS);
167
168    /* Don't allow two handlers. */
169
170    if (NULL != AcpiGbl_FixedEventHandlers[Event].Handler)
171    {
172        Status = AE_EXIST;
173        goto Cleanup;
174    }
175
176
177    /* Install the handler before enabling the event - just in case... */
178
179    AcpiGbl_FixedEventHandlers[Event].Handler = Handler;
180    AcpiGbl_FixedEventHandlers[Event].Context = Context;
181
182    Status = AcpiEnableEvent(Event, ACPI_EVENT_FIXED);
183
184    if (!ACPI_SUCCESS(Status))
185    {
186        DEBUG_PRINT (ACPI_WARN, ("Could not enable fixed event.\n"));
187
188        /* Remove the handler */
189
190        AcpiGbl_FixedEventHandlers[Event].Handler = NULL;
191        AcpiGbl_FixedEventHandlers[Event].Context = NULL;
192
193        Status = AE_ERROR;
194        goto Cleanup;
195    }
196
197    DEBUG_PRINT (ACPI_INFO,
198        ("Enabled fixed event %X, Handler=%p\n", Event, Handler));
199
200
201Cleanup:
202    AcpiCmReleaseMutex (ACPI_MTX_EVENTS);
203    return_ACPI_STATUS (Status);
204}
205
206
207/******************************************************************************
208 *
209 * FUNCTION:    AcpiRemoveFixedEventHandler
210 *
211 * PARAMETERS:  Event           - Event type to disable.
212 *              Handler         - Address of the handler
213 *
214 * RETURN:      Status
215 *
216 * DESCRIPTION: Disables the event and unregisters the event handler.
217 *
218 ******************************************************************************/
219
220ACPI_STATUS
221AcpiRemoveFixedEventHandler (
222    UINT32                  Event,
223    FIXED_EVENT_HANDLER     Handler)
224{
225    ACPI_STATUS             Status = AE_OK;
226
227
228    FUNCTION_TRACE ("AcpiRemoveFixedEventHandler");
229
230
231    /* Sanity check the parameters. */
232
233    if (Event >= NUM_FIXED_EVENTS)
234    {
235        return_ACPI_STATUS (AE_BAD_PARAMETER);
236    }
237
238    AcpiCmAcquireMutex (ACPI_MTX_EVENTS);
239
240    /* Disable the event before removing the handler - just in case... */
241
242    Status = AcpiDisableEvent(Event, ACPI_EVENT_FIXED);
243
244    if (!ACPI_SUCCESS(Status))
245    {
246        DEBUG_PRINT (ACPI_WARN,
247            ("Could not write to fixed event enable register.\n"));
248
249        Status = AE_ERROR;
250        AcpiCmReleaseMutex (ACPI_MTX_EVENTS);
251        return_ACPI_STATUS (Status);
252    }
253
254    /* Remove the handler */
255
256    AcpiGbl_FixedEventHandlers[Event].Handler = NULL;
257    AcpiGbl_FixedEventHandlers[Event].Context = NULL;
258
259    DEBUG_PRINT (ACPI_INFO, ("Disabled fixed event %X.\n", Event));
260
261    AcpiCmReleaseMutex (ACPI_MTX_EVENTS);
262    return_ACPI_STATUS (Status);
263}
264
265
266/******************************************************************************
267 *
268 * FUNCTION:    AcpiInstallNotifyHandler
269 *
270 * PARAMETERS:  Device          - The device for which notifies will be handled
271 *              HandlerType     - The type of handler:
272 *                                  ACPI_SYSTEM_NOTIFY: SystemHandler (00-7f)
273 *                                  ACPI_DEVICE_NOTIFY: DriverHandler (80-ff)
274 *              Handler         - Address of the handler
275 *              Context         - Value passed to the handler on each GPE
276 *
277 * RETURN:      Status
278 *
279 * DESCRIPTION: Install a handler for notifies on an ACPI device
280 *
281 ******************************************************************************/
282
283ACPI_STATUS
284AcpiInstallNotifyHandler (
285    ACPI_HANDLE             Device,
286    UINT32                  HandlerType,
287    NOTIFY_HANDLER          Handler,
288    void                    *Context)
289{
290    ACPI_OPERAND_OBJECT     *ObjDesc;
291    ACPI_OPERAND_OBJECT     *NotifyObj;
292    ACPI_NAMESPACE_NODE     *DeviceNode;
293    ACPI_STATUS             Status = AE_OK;
294
295
296    FUNCTION_TRACE ("AcpiInstallNotifyHandler");
297
298
299    /* Parameter validation */
300
301    if ((!Handler) ||
302        (HandlerType > ACPI_MAX_NOTIFY_HANDLER_TYPE))
303    {
304        return_ACPI_STATUS (AE_BAD_PARAMETER);
305    }
306
307    AcpiCmAcquireMutex (ACPI_MTX_NAMESPACE);
308
309    /* Convert and validate the device handle */
310
311    DeviceNode = AcpiNsConvertHandleToEntry (Device);
312    if (!DeviceNode)
313    {
314        Status = AE_BAD_PARAMETER;
315        goto UnlockAndExit;
316    }
317
318    /*
319     * Root Object:
320     * ------------
321     * Registering a notify handler on the root object indicates that the
322     * caller wishes to receive notifications for all objects.  Note that
323     * only one <external> global handler can be regsitered (per notify type).
324     */
325    if (Device == ACPI_ROOT_OBJECT)
326    {
327        /* Make sure the handler is not already installed */
328
329        if (((HandlerType == ACPI_SYSTEM_NOTIFY) &&
330              AcpiGbl_SysNotify.Handler) ||
331            ((HandlerType == ACPI_DEVICE_NOTIFY) &&
332              AcpiGbl_DrvNotify.Handler))
333        {
334            Status = AE_EXIST;
335            goto UnlockAndExit;
336        }
337
338        if (HandlerType == ACPI_SYSTEM_NOTIFY)
339        {
340            AcpiGbl_SysNotify.Node = DeviceNode;
341            AcpiGbl_SysNotify.Handler = Handler;
342            AcpiGbl_SysNotify.Context = Context;
343        }
344        else /* ACPI_DEVICE_NOTIFY */
345        {
346            AcpiGbl_DrvNotify.Node = DeviceNode;
347            AcpiGbl_DrvNotify.Handler = Handler;
348            AcpiGbl_DrvNotify.Context = Context;
349        }
350
351        /* Global notify handler installed */
352    }
353
354    /*
355     * Other Objects:
356     * --------------
357     * Caller will only receive notifications specific to the target object.
358     * Note that only certain object types can receive notifications.
359     */
360    else {
361        /*
362         * These are the ONLY objects that can receive ACPI notifications
363         */
364        if ((DeviceNode->Type != ACPI_TYPE_DEVICE)     &&
365            (DeviceNode->Type != ACPI_TYPE_PROCESSOR)  &&
366            (DeviceNode->Type != ACPI_TYPE_POWER)      &&
367            (DeviceNode->Type != ACPI_TYPE_THERMAL))
368        {
369            Status = AE_BAD_PARAMETER;
370            goto UnlockAndExit;
371        }
372
373        /* Check for an existing internal object */
374
375        ObjDesc = AcpiNsGetAttachedObject ((ACPI_HANDLE) DeviceNode);
376        if (ObjDesc)
377        {
378
379            /* Object exists - make sure there's no handler */
380
381            if (((HandlerType == ACPI_SYSTEM_NOTIFY) &&
382                  ObjDesc->Device.SysHandler) ||
383                ((HandlerType == ACPI_DEVICE_NOTIFY) &&
384                  ObjDesc->Device.DrvHandler))
385            {
386                Status = AE_EXIST;
387                goto UnlockAndExit;
388            }
389        }
390
391        else
392        {
393            /* Create a new object */
394
395            ObjDesc = AcpiCmCreateInternalObject (DeviceNode->Type);
396            if (!ObjDesc)
397            {
398                Status = AE_NO_MEMORY;
399                goto UnlockAndExit;
400            }
401
402            /* Attach new object to the Node */
403
404            Status = AcpiNsAttachObject (Device, ObjDesc, (UINT8) DeviceNode->Type);
405
406            if (ACPI_FAILURE (Status))
407            {
408                goto UnlockAndExit;
409            }
410        }
411
412        /* Install the handler */
413
414        NotifyObj = AcpiCmCreateInternalObject (INTERNAL_TYPE_NOTIFY);
415        if (!NotifyObj)
416        {
417            Status = AE_NO_MEMORY;
418            goto UnlockAndExit;
419        }
420
421        NotifyObj->NotifyHandler.Node = DeviceNode;
422        NotifyObj->NotifyHandler.Handler = Handler;
423        NotifyObj->NotifyHandler.Context = Context;
424
425
426        if (HandlerType == ACPI_SYSTEM_NOTIFY)
427        {
428            ObjDesc->Device.SysHandler = NotifyObj;
429        }
430        else /* ACPI_DEVICE_NOTIFY */
431        {
432            ObjDesc->Device.DrvHandler = NotifyObj;
433        }
434    }
435
436UnlockAndExit:
437    AcpiCmReleaseMutex (ACPI_MTX_NAMESPACE);
438    return_ACPI_STATUS (Status);
439}
440
441
442/*****************************************************************************
443 *
444 * FUNCTION:    AcpiRemoveNotifyHandler
445 *
446 * PARAMETERS:  Device          - The device for which notifies will be handled
447 *              HandlerType     - The type of handler:
448 *                                  ACPI_SYSTEM_NOTIFY: SystemHandler (00-7f)
449 *                                  ACPI_DEVICE_NOTIFY: DriverHandler (80-ff)
450 *              Handler         - Address of the handler
451 * RETURN:      Status
452 *
453 * DESCRIPTION: Remove a handler for notifies on an ACPI device
454 *
455 ******************************************************************************/
456
457ACPI_STATUS
458AcpiRemoveNotifyHandler (
459    ACPI_HANDLE             Device,
460    UINT32                  HandlerType,
461    NOTIFY_HANDLER          Handler)
462{
463    ACPI_OPERAND_OBJECT     *NotifyObj;
464    ACPI_OPERAND_OBJECT     *ObjDesc;
465    ACPI_NAMESPACE_NODE     *DeviceNode;
466    ACPI_STATUS             Status = AE_OK;
467
468    FUNCTION_TRACE ("AcpiRemoveNotifyHandler");
469
470    /* Parameter validation */
471
472    if ((!Handler) ||
473        (HandlerType > ACPI_MAX_NOTIFY_HANDLER_TYPE))
474    {
475        return_ACPI_STATUS (AE_BAD_PARAMETER);
476    }
477
478    AcpiCmAcquireMutex (ACPI_MTX_NAMESPACE);
479
480    /* Convert and validate the device handle */
481
482    DeviceNode = AcpiNsConvertHandleToEntry (Device);
483    if (!DeviceNode)
484    {
485        Status = AE_BAD_PARAMETER;
486        goto UnlockAndExit;
487    }
488
489    /*
490     * Root Object:
491     * ------------
492     */
493    if (Device == ACPI_ROOT_OBJECT) {
494
495        DEBUG_PRINT(ACPI_INFO, ("Removing notify handler for ROOT object.\n"));
496
497        if (((HandlerType == ACPI_SYSTEM_NOTIFY) &&
498              !AcpiGbl_SysNotify.Handler) ||
499            ((HandlerType == ACPI_DEVICE_NOTIFY) &&
500              !AcpiGbl_DrvNotify.Handler))
501        {
502            Status = AE_NOT_EXIST;
503            goto UnlockAndExit;
504        }
505
506        if (HandlerType == ACPI_SYSTEM_NOTIFY) {
507            AcpiGbl_SysNotify.Node = NULL;
508            AcpiGbl_SysNotify.Handler = NULL;
509            AcpiGbl_SysNotify.Context = NULL;
510        }
511        else {
512            AcpiGbl_DrvNotify.Node = NULL;
513            AcpiGbl_DrvNotify.Handler = NULL;
514            AcpiGbl_DrvNotify.Context = NULL;
515        }
516    }
517
518    /*
519     * Other Objects:
520     * --------------
521     */
522    else {
523        /*
524         * These are the ONLY objects that can receive ACPI notifications
525         */
526        if ((DeviceNode->Type != ACPI_TYPE_DEVICE)     &&
527            (DeviceNode->Type != ACPI_TYPE_PROCESSOR)  &&
528            (DeviceNode->Type != ACPI_TYPE_POWER)      &&
529            (DeviceNode->Type != ACPI_TYPE_THERMAL))
530        {
531            Status = AE_BAD_PARAMETER;
532            goto UnlockAndExit;
533        }
534
535        /* Check for an existing internal object */
536
537        ObjDesc = AcpiNsGetAttachedObject ((ACPI_HANDLE) DeviceNode);
538        if (!ObjDesc)
539        {
540            Status = AE_NOT_EXIST;
541            goto UnlockAndExit;
542        }
543
544        /* Object exists - make sure there's an existing handler */
545
546        if (HandlerType == ACPI_SYSTEM_NOTIFY)
547        {
548            NotifyObj = ObjDesc->Device.SysHandler;
549        }
550        else
551        {
552            NotifyObj = ObjDesc->Device.DrvHandler;
553        }
554
555        if ((!NotifyObj) ||
556            (NotifyObj->NotifyHandler.Handler != Handler))
557        {
558            Status = AE_BAD_PARAMETER;
559            goto UnlockAndExit;
560        }
561
562        /* Remove the handler */
563
564        if (HandlerType == ACPI_SYSTEM_NOTIFY)
565        {
566            ObjDesc->Device.SysHandler = NULL;
567        }
568        else
569        {
570            ObjDesc->Device.DrvHandler = NULL;
571        }
572
573        AcpiCmRemoveReference (NotifyObj);
574    }
575
576
577UnlockAndExit:
578    AcpiCmReleaseMutex (ACPI_MTX_NAMESPACE);
579    return_ACPI_STATUS (Status);
580}
581
582
583/******************************************************************************
584 *
585 * FUNCTION:    AcpiInstallGpeHandler
586 *
587 * PARAMETERS:  GpeNumber       - The GPE number.  The numbering scheme is
588 *                                bank 0 first, then bank 1.
589 *              Type            - Whether this GPE should be treated as an
590 *                                edge- or level-triggered interrupt.
591 *              Handler         - Address of the handler
592 *              Context         - Value passed to the handler on each GPE
593 *
594 * RETURN:      Status
595 *
596 * DESCRIPTION: Install a handler for a General Purpose Event.
597 *
598 ******************************************************************************/
599
600ACPI_STATUS
601AcpiInstallGpeHandler (
602    UINT32                  GpeNumber,
603    UINT32                  Type,
604    GPE_HANDLER             Handler,
605    void                    *Context)
606{
607    ACPI_STATUS             Status = AE_OK;
608
609    FUNCTION_TRACE ("AcpiInstallGpeHandler");
610
611    /* Parameter validation */
612
613    if (!Handler || (GpeNumber > NUM_GPE))
614    {
615        return_ACPI_STATUS (AE_BAD_PARAMETER);
616    }
617
618    /* Ensure that we have a valid GPE number */
619
620    if (AcpiGbl_GpeValid[GpeNumber] == ACPI_GPE_INVALID)
621    {
622        return_ACPI_STATUS (AE_BAD_PARAMETER);
623    }
624
625    AcpiCmAcquireMutex (ACPI_MTX_EVENTS);
626
627    /* Make sure that there isn't a handler there already */
628
629    if (AcpiGbl_GpeInfo[GpeNumber].Handler)
630    {
631        Status = AE_EXIST;
632        goto Cleanup;
633    }
634
635    /* Install the handler */
636
637    AcpiGbl_GpeInfo[GpeNumber].Handler = Handler;
638    AcpiGbl_GpeInfo[GpeNumber].Context = Context;
639    AcpiGbl_GpeInfo[GpeNumber].Type = (UINT8) Type;
640
641    /* Clear the GPE (of stale events), the enable it */
642
643    AcpiHwClearGpe (GpeNumber);
644    AcpiHwEnableGpe (GpeNumber);
645
646Cleanup:
647    AcpiCmReleaseMutex (ACPI_MTX_EVENTS);
648    return_ACPI_STATUS (Status);
649}
650
651
652/******************************************************************************
653 *
654 * FUNCTION:    AcpiRemoveGpeHandler
655 *
656 * PARAMETERS:  GpeNumber       - The event to remove a handler
657 *              Handler         - Address of the handler
658 *
659 * RETURN:      Status
660 *
661 * DESCRIPTION: Remove a handler for a General Purpose AcpiEvent.
662 *
663 ******************************************************************************/
664
665ACPI_STATUS
666AcpiRemoveGpeHandler (
667    UINT32                  GpeNumber,
668    GPE_HANDLER             Handler)
669{
670    ACPI_STATUS             Status = AE_OK;
671
672
673    FUNCTION_TRACE ("AcpiRemoveGpeHandler");
674
675
676    /* Parameter validation */
677
678    if (!Handler || (GpeNumber > NUM_GPE))
679    {
680        return_ACPI_STATUS (AE_BAD_PARAMETER);
681    }
682
683    /* Ensure that we have a valid GPE number */
684
685    if (AcpiGbl_GpeValid[GpeNumber] == ACPI_GPE_INVALID)
686    {
687        return_ACPI_STATUS (AE_BAD_PARAMETER);
688    }
689
690    /* Disable the GPE before removing the handler */
691
692    AcpiHwDisableGpe (GpeNumber);
693
694    AcpiCmAcquireMutex (ACPI_MTX_EVENTS);
695
696    /* Make sure that the installed handler is the same */
697
698    if (AcpiGbl_GpeInfo[GpeNumber].Handler != Handler)
699    {
700        AcpiHwEnableGpe (GpeNumber);
701        Status = AE_BAD_PARAMETER;
702        goto Cleanup;
703    }
704
705    /* Remove the handler */
706
707    AcpiGbl_GpeInfo[GpeNumber].Handler = NULL;
708    AcpiGbl_GpeInfo[GpeNumber].Context = NULL;
709
710Cleanup:
711    AcpiCmReleaseMutex (ACPI_MTX_EVENTS);
712    return_ACPI_STATUS (Status);
713}
714
715
716/******************************************************************************
717 *
718 * FUNCTION:    AcpiAcquireGlobalLock
719 *
720 * PARAMETERS:  Timeout         - How long the caller is willing to wait
721 *              OutHandle       - A handle to the lock if acquired
722 *
723 * RETURN:      Status
724 *
725 * DESCRIPTION: Acquire the ACPI Global Lock
726 *
727 ******************************************************************************/
728ACPI_STATUS
729AcpiAcquireGlobalLock (
730    void)
731{
732    ACPI_STATUS             Status;
733
734
735    AcpiAmlEnterInterpreter ();
736
737    /*
738     * TBD: [Restructure] add timeout param to internal interface, and
739     * perhaps INTERPRETER_LOCKED
740     */
741
742    Status = AcpiEvAcquireGlobalLock ();
743    AcpiAmlExitInterpreter ();
744
745    return (Status);
746}
747
748
749/******************************************************************************
750 *
751 * FUNCTION:    AcpiReleaseGlobalLock
752 *
753 * PARAMETERS:  Handle      - Returned from AcpiAcquireGlobalLock
754 *
755 * RETURN:      Status
756 *
757 * DESCRIPTION: Release the ACPI Global Lock
758 *
759 ******************************************************************************/
760
761ACPI_STATUS
762AcpiReleaseGlobalLock (
763    void)
764{
765    AcpiEvReleaseGlobalLock ();
766    return (AE_OK);
767}
768
769
770