Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/contrib/dev/acpica/components/events/evxface.c
48526 views
1
/******************************************************************************
2
*
3
* Module Name: evxface - External interfaces for ACPI events
4
*
5
*****************************************************************************/
6
7
/******************************************************************************
8
*
9
* 1. Copyright Notice
10
*
11
* Some or all of this work - Copyright (c) 1999 - 2025, Intel Corp.
12
* All rights reserved.
13
*
14
* 2. License
15
*
16
* 2.1. This is your license from Intel Corp. under its intellectual property
17
* rights. You may have additional license terms from the party that provided
18
* you this software, covering your right to use that party's intellectual
19
* property rights.
20
*
21
* 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22
* copy of the source code appearing in this file ("Covered Code") an
23
* irrevocable, perpetual, worldwide license under Intel's copyrights in the
24
* base code distributed originally by Intel ("Original Intel Code") to copy,
25
* make derivatives, distribute, use and display any portion of the Covered
26
* Code in any form, with the right to sublicense such rights; and
27
*
28
* 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29
* license (with the right to sublicense), under only those claims of Intel
30
* patents that are infringed by the Original Intel Code, to make, use, sell,
31
* offer to sell, and import the Covered Code and derivative works thereof
32
* solely to the minimum extent necessary to exercise the above copyright
33
* license, and in no event shall the patent license extend to any additions
34
* to or modifications of the Original Intel Code. No other license or right
35
* is granted directly or by implication, estoppel or otherwise;
36
*
37
* The above copyright and patent license is granted only if the following
38
* conditions are met:
39
*
40
* 3. Conditions
41
*
42
* 3.1. Redistribution of Source with Rights to Further Distribute Source.
43
* Redistribution of source code of any substantial portion of the Covered
44
* Code or modification with rights to further distribute source must include
45
* the above Copyright Notice, the above License, this list of Conditions,
46
* and the following Disclaimer and Export Compliance provision. In addition,
47
* Licensee must cause all Covered Code to which Licensee contributes to
48
* contain a file documenting the changes Licensee made to create that Covered
49
* Code and the date of any change. Licensee must include in that file the
50
* documentation of any changes made by any predecessor Licensee. Licensee
51
* must include a prominent statement that the modification is derived,
52
* directly or indirectly, from Original Intel Code.
53
*
54
* 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55
* Redistribution of source code of any substantial portion of the Covered
56
* Code or modification without rights to further distribute source must
57
* include the following Disclaimer and Export Compliance provision in the
58
* documentation and/or other materials provided with distribution. In
59
* addition, Licensee may not authorize further sublicense of source of any
60
* portion of the Covered Code, and must include terms to the effect that the
61
* license from Licensee to its licensee is limited to the intellectual
62
* property embodied in the software Licensee provides to its licensee, and
63
* not to intellectual property embodied in modifications its licensee may
64
* make.
65
*
66
* 3.3. Redistribution of Executable. Redistribution in executable form of any
67
* substantial portion of the Covered Code or modification must reproduce the
68
* above Copyright Notice, and the following Disclaimer and Export Compliance
69
* provision in the documentation and/or other materials provided with the
70
* distribution.
71
*
72
* 3.4. Intel retains all right, title, and interest in and to the Original
73
* Intel Code.
74
*
75
* 3.5. Neither the name Intel nor any other trademark owned or controlled by
76
* Intel shall be used in advertising or otherwise to promote the sale, use or
77
* other dealings in products derived from or relating to the Covered Code
78
* without prior written authorization from Intel.
79
*
80
* 4. Disclaimer and Export Compliance
81
*
82
* 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83
* HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84
* IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85
* INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86
* UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87
* IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88
* PARTICULAR PURPOSE.
89
*
90
* 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91
* OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92
* COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93
* SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94
* CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95
* HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96
* SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97
* LIMITED REMEDY.
98
*
99
* 4.3. Licensee shall not export, either directly or indirectly, any of this
100
* software or system incorporating such software without first obtaining any
101
* required license or other approval from the U. S. Department of Commerce or
102
* any other agency or department of the United States Government. In the
103
* event Licensee exports any such software from the United States or
104
* re-exports any such software from a foreign destination, Licensee shall
105
* ensure that the distribution and export/re-export of the software is in
106
* compliance with all laws, regulations, orders, or other restrictions of the
107
* U.S. Export Administration Regulations. Licensee agrees that neither it nor
108
* any of its subsidiaries will export/re-export any technical data, process,
109
* software, or service, directly or indirectly, to any country for which the
110
* United States government or any agency thereof requires an export license,
111
* other governmental approval, or letter of assurance, without first obtaining
112
* such license, approval or letter.
113
*
114
*****************************************************************************
115
*
116
* Alternatively, you may choose to be licensed under the terms of the
117
* following license:
118
*
119
* Redistribution and use in source and binary forms, with or without
120
* modification, are permitted provided that the following conditions
121
* are met:
122
* 1. Redistributions of source code must retain the above copyright
123
* notice, this list of conditions, and the following disclaimer,
124
* without modification.
125
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
126
* substantially similar to the "NO WARRANTY" disclaimer below
127
* ("Disclaimer") and any redistribution must be conditioned upon
128
* including a substantially similar Disclaimer requirement for further
129
* binary redistribution.
130
* 3. Neither the names of the above-listed copyright holders nor the names
131
* of any contributors may be used to endorse or promote products derived
132
* from this software without specific prior written permission.
133
*
134
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
135
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
136
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
137
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
138
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
139
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
140
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
141
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
142
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
144
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145
*
146
* Alternatively, you may choose to be licensed under the terms of the
147
* GNU General Public License ("GPL") version 2 as published by the Free
148
* Software Foundation.
149
*
150
*****************************************************************************/
151
152
#define EXPORT_ACPI_INTERFACES
153
154
#include <contrib/dev/acpica/include/acpi.h>
155
#include <contrib/dev/acpica/include/accommon.h>
156
#include <contrib/dev/acpica/include/acnamesp.h>
157
#include <contrib/dev/acpica/include/acevents.h>
158
#include <contrib/dev/acpica/include/acinterp.h>
159
160
#define _COMPONENT ACPI_EVENTS
161
ACPI_MODULE_NAME ("evxface")
162
163
#if (!ACPI_REDUCED_HARDWARE)
164
165
/* Local prototypes */
166
167
static ACPI_STATUS
168
AcpiEvInstallGpeHandler (
169
ACPI_HANDLE GpeDevice,
170
UINT32 GpeNumber,
171
UINT32 Type,
172
BOOLEAN IsRawHandler,
173
ACPI_GPE_HANDLER Address,
174
void *Context);
175
176
#endif
177
178
179
/*******************************************************************************
180
*
181
* FUNCTION: AcpiInstallNotifyHandler
182
*
183
* PARAMETERS: Device - The device for which notifies will be handled
184
* HandlerType - The type of handler:
185
* ACPI_SYSTEM_NOTIFY: System Handler (00-7F)
186
* ACPI_DEVICE_NOTIFY: Device Handler (80-FF)
187
* ACPI_ALL_NOTIFY: Both System and Device
188
* Handler - Address of the handler
189
* Context - Value passed to the handler on each GPE
190
*
191
* RETURN: Status
192
*
193
* DESCRIPTION: Install a handler for notifications on an ACPI Device,
194
* ThermalZone, or Processor object.
195
*
196
* NOTES: The Root namespace object may have only one handler for each
197
* type of notify (System/Device). Device/Thermal/Processor objects
198
* may have one device notify handler, and multiple system notify
199
* handlers.
200
*
201
******************************************************************************/
202
203
ACPI_STATUS
204
AcpiInstallNotifyHandler (
205
ACPI_HANDLE Device,
206
UINT32 HandlerType,
207
ACPI_NOTIFY_HANDLER Handler,
208
void *Context)
209
{
210
ACPI_NAMESPACE_NODE *Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Device);
211
ACPI_OPERAND_OBJECT *ObjDesc;
212
ACPI_OPERAND_OBJECT *HandlerObj;
213
ACPI_STATUS Status;
214
UINT32 i;
215
216
217
ACPI_FUNCTION_TRACE (AcpiInstallNotifyHandler);
218
219
220
/* Parameter validation */
221
222
if ((!Device) || (!Handler) || (!HandlerType) ||
223
(HandlerType > ACPI_MAX_NOTIFY_HANDLER_TYPE))
224
{
225
return_ACPI_STATUS (AE_BAD_PARAMETER);
226
}
227
228
Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
229
if (ACPI_FAILURE (Status))
230
{
231
return_ACPI_STATUS (Status);
232
}
233
234
/*
235
* Root Object:
236
* Registering a notify handler on the root object indicates that the
237
* caller wishes to receive notifications for all objects. Note that
238
* only one global handler can be registered per notify type.
239
* Ensure that a handler is not already installed.
240
*/
241
if (Device == ACPI_ROOT_OBJECT)
242
{
243
for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++)
244
{
245
if (HandlerType & (i+1))
246
{
247
if (AcpiGbl_GlobalNotify[i].Handler)
248
{
249
Status = AE_ALREADY_EXISTS;
250
goto UnlockAndExit;
251
}
252
253
AcpiGbl_GlobalNotify[i].Handler = Handler;
254
AcpiGbl_GlobalNotify[i].Context = Context;
255
}
256
}
257
258
goto UnlockAndExit; /* Global notify handler installed, all done */
259
}
260
261
/*
262
* All Other Objects:
263
* Caller will only receive notifications specific to the target
264
* object. Note that only certain object types are allowed to
265
* receive notifications.
266
*/
267
268
/* Are Notifies allowed on this object? */
269
270
if (!AcpiEvIsNotifyObject (Node))
271
{
272
Status = AE_TYPE;
273
goto UnlockAndExit;
274
}
275
276
/* Check for an existing internal object, might not exist */
277
278
ObjDesc = AcpiNsGetAttachedObject (Node);
279
if (!ObjDesc)
280
{
281
/* Create a new object */
282
283
ObjDesc = AcpiUtCreateInternalObject (Node->Type);
284
if (!ObjDesc)
285
{
286
Status = AE_NO_MEMORY;
287
goto UnlockAndExit;
288
}
289
290
/* Attach new object to the Node, remove local reference */
291
292
Status = AcpiNsAttachObject (Device, ObjDesc, Node->Type);
293
AcpiUtRemoveReference (ObjDesc);
294
if (ACPI_FAILURE (Status))
295
{
296
goto UnlockAndExit;
297
}
298
}
299
300
/* Ensure that the handler is not already installed in the lists */
301
302
for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++)
303
{
304
if (HandlerType & (i+1))
305
{
306
HandlerObj = ObjDesc->CommonNotify.NotifyList[i];
307
while (HandlerObj)
308
{
309
if (HandlerObj->Notify.Handler == Handler)
310
{
311
Status = AE_ALREADY_EXISTS;
312
goto UnlockAndExit;
313
}
314
315
HandlerObj = HandlerObj->Notify.Next[i];
316
}
317
}
318
}
319
320
/* Create and populate a new notify handler object */
321
322
HandlerObj = AcpiUtCreateInternalObject (ACPI_TYPE_LOCAL_NOTIFY);
323
if (!HandlerObj)
324
{
325
Status = AE_NO_MEMORY;
326
goto UnlockAndExit;
327
}
328
329
HandlerObj->Notify.Node = Node;
330
HandlerObj->Notify.HandlerType = HandlerType;
331
HandlerObj->Notify.Handler = Handler;
332
HandlerObj->Notify.Context = Context;
333
334
/* Install the handler at the list head(s) */
335
336
for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++)
337
{
338
if (HandlerType & (i+1))
339
{
340
HandlerObj->Notify.Next[i] =
341
ObjDesc->CommonNotify.NotifyList[i];
342
343
ObjDesc->CommonNotify.NotifyList[i] = HandlerObj;
344
}
345
}
346
347
/* Add an extra reference if handler was installed in both lists */
348
349
if (HandlerType == ACPI_ALL_NOTIFY)
350
{
351
AcpiUtAddReference (HandlerObj);
352
}
353
354
355
UnlockAndExit:
356
(void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
357
return_ACPI_STATUS (Status);
358
}
359
360
ACPI_EXPORT_SYMBOL (AcpiInstallNotifyHandler)
361
362
363
/*******************************************************************************
364
*
365
* FUNCTION: AcpiRemoveNotifyHandler
366
*
367
* PARAMETERS: Device - The device for which the handler is installed
368
* HandlerType - The type of handler:
369
* ACPI_SYSTEM_NOTIFY: System Handler (00-7F)
370
* ACPI_DEVICE_NOTIFY: Device Handler (80-FF)
371
* ACPI_ALL_NOTIFY: Both System and Device
372
* Handler - Address of the handler
373
*
374
* RETURN: Status
375
*
376
* DESCRIPTION: Remove a handler for notifies on an ACPI device
377
*
378
******************************************************************************/
379
380
ACPI_STATUS
381
AcpiRemoveNotifyHandler (
382
ACPI_HANDLE Device,
383
UINT32 HandlerType,
384
ACPI_NOTIFY_HANDLER Handler)
385
{
386
ACPI_NAMESPACE_NODE *Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Device);
387
ACPI_OPERAND_OBJECT *ObjDesc;
388
ACPI_OPERAND_OBJECT *HandlerObj;
389
ACPI_OPERAND_OBJECT *PreviousHandlerObj;
390
ACPI_STATUS Status = AE_OK;
391
UINT32 i;
392
393
394
ACPI_FUNCTION_TRACE (AcpiRemoveNotifyHandler);
395
396
397
/* Parameter validation */
398
399
if ((!Device) || (!Handler) || (!HandlerType) ||
400
(HandlerType > ACPI_MAX_NOTIFY_HANDLER_TYPE))
401
{
402
return_ACPI_STATUS (AE_BAD_PARAMETER);
403
}
404
405
/* Root Object. Global handlers are removed here */
406
407
if (Device == ACPI_ROOT_OBJECT)
408
{
409
for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++)
410
{
411
if (HandlerType & (i+1))
412
{
413
Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
414
if (ACPI_FAILURE (Status))
415
{
416
return_ACPI_STATUS (Status);
417
}
418
419
if (!AcpiGbl_GlobalNotify[i].Handler ||
420
(AcpiGbl_GlobalNotify[i].Handler != Handler))
421
{
422
Status = AE_NOT_EXIST;
423
goto UnlockAndExit;
424
}
425
426
ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
427
"Removing global notify handler\n"));
428
429
AcpiGbl_GlobalNotify[i].Handler = NULL;
430
AcpiGbl_GlobalNotify[i].Context = NULL;
431
432
(void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
433
434
/* Make sure all deferred notify tasks are completed */
435
436
AcpiOsWaitEventsComplete ();
437
}
438
}
439
440
return_ACPI_STATUS (AE_OK);
441
}
442
443
/* All other objects: Are Notifies allowed on this object? */
444
445
if (!AcpiEvIsNotifyObject (Node))
446
{
447
return_ACPI_STATUS (AE_TYPE);
448
}
449
450
/* Must have an existing internal object */
451
452
ObjDesc = AcpiNsGetAttachedObject (Node);
453
if (!ObjDesc)
454
{
455
return_ACPI_STATUS (AE_NOT_EXIST);
456
}
457
458
/* Internal object exists. Find the handler and remove it */
459
460
for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++)
461
{
462
if (HandlerType & (i+1))
463
{
464
Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
465
if (ACPI_FAILURE (Status))
466
{
467
return_ACPI_STATUS (Status);
468
}
469
470
HandlerObj = ObjDesc->CommonNotify.NotifyList[i];
471
PreviousHandlerObj = NULL;
472
473
/* Attempt to find the handler in the handler list */
474
475
while (HandlerObj &&
476
(HandlerObj->Notify.Handler != Handler))
477
{
478
PreviousHandlerObj = HandlerObj;
479
HandlerObj = HandlerObj->Notify.Next[i];
480
}
481
482
if (!HandlerObj)
483
{
484
Status = AE_NOT_EXIST;
485
goto UnlockAndExit;
486
}
487
488
/* Remove the handler object from the list */
489
490
if (PreviousHandlerObj) /* Handler is not at the list head */
491
{
492
PreviousHandlerObj->Notify.Next[i] =
493
HandlerObj->Notify.Next[i];
494
}
495
else /* Handler is at the list head */
496
{
497
ObjDesc->CommonNotify.NotifyList[i] =
498
HandlerObj->Notify.Next[i];
499
}
500
501
(void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
502
503
/* Make sure all deferred notify tasks are completed */
504
505
AcpiOsWaitEventsComplete ();
506
AcpiUtRemoveReference (HandlerObj);
507
}
508
}
509
510
return_ACPI_STATUS (Status);
511
512
513
UnlockAndExit:
514
(void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
515
return_ACPI_STATUS (Status);
516
}
517
518
ACPI_EXPORT_SYMBOL (AcpiRemoveNotifyHandler)
519
520
521
/*******************************************************************************
522
*
523
* FUNCTION: AcpiInstallExceptionHandler
524
*
525
* PARAMETERS: Handler - Pointer to the handler function for the
526
* event
527
*
528
* RETURN: Status
529
*
530
* DESCRIPTION: Saves the pointer to the handler function
531
*
532
******************************************************************************/
533
534
ACPI_STATUS
535
AcpiInstallExceptionHandler (
536
ACPI_EXCEPTION_HANDLER Handler)
537
{
538
ACPI_STATUS Status;
539
540
541
ACPI_FUNCTION_TRACE (AcpiInstallExceptionHandler);
542
543
544
Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
545
if (ACPI_FAILURE (Status))
546
{
547
return_ACPI_STATUS (Status);
548
}
549
550
/* Don't allow two handlers. */
551
552
if (AcpiGbl_ExceptionHandler)
553
{
554
Status = AE_ALREADY_EXISTS;
555
goto Cleanup;
556
}
557
558
/* Install the handler */
559
560
AcpiGbl_ExceptionHandler = Handler;
561
562
Cleanup:
563
(void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
564
return_ACPI_STATUS (Status);
565
}
566
567
ACPI_EXPORT_SYMBOL (AcpiInstallExceptionHandler)
568
569
570
#if (!ACPI_REDUCED_HARDWARE)
571
/*******************************************************************************
572
*
573
* FUNCTION: AcpiInstallSciHandler
574
*
575
* PARAMETERS: Address - Address of the handler
576
* Context - Value passed to the handler on each SCI
577
*
578
* RETURN: Status
579
*
580
* DESCRIPTION: Install a handler for a System Control Interrupt.
581
*
582
******************************************************************************/
583
584
ACPI_STATUS
585
AcpiInstallSciHandler (
586
ACPI_SCI_HANDLER Address,
587
void *Context)
588
{
589
ACPI_SCI_HANDLER_INFO *NewSciHandler;
590
ACPI_SCI_HANDLER_INFO *SciHandler;
591
ACPI_CPU_FLAGS Flags;
592
ACPI_STATUS Status;
593
594
595
ACPI_FUNCTION_TRACE (AcpiInstallSciHandler);
596
597
598
if (!Address)
599
{
600
return_ACPI_STATUS (AE_BAD_PARAMETER);
601
}
602
603
/* Allocate and init a handler object */
604
605
NewSciHandler = ACPI_ALLOCATE (sizeof (ACPI_SCI_HANDLER_INFO));
606
if (!NewSciHandler)
607
{
608
return_ACPI_STATUS (AE_NO_MEMORY);
609
}
610
611
NewSciHandler->Address = Address;
612
NewSciHandler->Context = Context;
613
614
Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
615
if (ACPI_FAILURE (Status))
616
{
617
goto Exit;
618
}
619
620
/* Lock list during installation */
621
622
Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
623
SciHandler = AcpiGbl_SciHandlerList;
624
625
/* Ensure handler does not already exist */
626
627
while (SciHandler)
628
{
629
if (Address == SciHandler->Address)
630
{
631
Status = AE_ALREADY_EXISTS;
632
goto UnlockAndExit;
633
}
634
635
SciHandler = SciHandler->Next;
636
}
637
638
/* Install the new handler into the global list (at head) */
639
640
NewSciHandler->Next = AcpiGbl_SciHandlerList;
641
AcpiGbl_SciHandlerList = NewSciHandler;
642
643
644
UnlockAndExit:
645
646
AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
647
(void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
648
649
Exit:
650
if (ACPI_FAILURE (Status))
651
{
652
ACPI_FREE (NewSciHandler);
653
}
654
return_ACPI_STATUS (Status);
655
}
656
657
ACPI_EXPORT_SYMBOL (AcpiInstallSciHandler)
658
659
660
/*******************************************************************************
661
*
662
* FUNCTION: AcpiRemoveSciHandler
663
*
664
* PARAMETERS: Address - Address of the handler
665
*
666
* RETURN: Status
667
*
668
* DESCRIPTION: Remove a handler for a System Control Interrupt.
669
*
670
******************************************************************************/
671
672
ACPI_STATUS
673
AcpiRemoveSciHandler (
674
ACPI_SCI_HANDLER Address)
675
{
676
ACPI_SCI_HANDLER_INFO *PrevSciHandler;
677
ACPI_SCI_HANDLER_INFO *NextSciHandler;
678
ACPI_CPU_FLAGS Flags;
679
ACPI_STATUS Status;
680
681
682
ACPI_FUNCTION_TRACE (AcpiRemoveSciHandler);
683
684
685
if (!Address)
686
{
687
return_ACPI_STATUS (AE_BAD_PARAMETER);
688
}
689
690
Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
691
if (ACPI_FAILURE (Status))
692
{
693
return_ACPI_STATUS (Status);
694
}
695
696
/* Remove the SCI handler with lock */
697
698
Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
699
700
PrevSciHandler = NULL;
701
NextSciHandler = AcpiGbl_SciHandlerList;
702
while (NextSciHandler)
703
{
704
if (NextSciHandler->Address == Address)
705
{
706
/* Unlink and free the SCI handler info block */
707
708
if (PrevSciHandler)
709
{
710
PrevSciHandler->Next = NextSciHandler->Next;
711
}
712
else
713
{
714
AcpiGbl_SciHandlerList = NextSciHandler->Next;
715
}
716
717
AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
718
ACPI_FREE (NextSciHandler);
719
goto UnlockAndExit;
720
}
721
722
PrevSciHandler = NextSciHandler;
723
NextSciHandler = NextSciHandler->Next;
724
}
725
726
AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
727
Status = AE_NOT_EXIST;
728
729
730
UnlockAndExit:
731
(void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
732
return_ACPI_STATUS (Status);
733
}
734
735
ACPI_EXPORT_SYMBOL (AcpiRemoveSciHandler)
736
737
738
/*******************************************************************************
739
*
740
* FUNCTION: AcpiInstallGlobalEventHandler
741
*
742
* PARAMETERS: Handler - Pointer to the global event handler function
743
* Context - Value passed to the handler on each event
744
*
745
* RETURN: Status
746
*
747
* DESCRIPTION: Saves the pointer to the handler function. The global handler
748
* is invoked upon each incoming GPE and Fixed Event. It is
749
* invoked at interrupt level at the time of the event dispatch.
750
* Can be used to update event counters, etc.
751
*
752
******************************************************************************/
753
754
ACPI_STATUS
755
AcpiInstallGlobalEventHandler (
756
ACPI_GBL_EVENT_HANDLER Handler,
757
void *Context)
758
{
759
ACPI_STATUS Status;
760
761
762
ACPI_FUNCTION_TRACE (AcpiInstallGlobalEventHandler);
763
764
765
/* Parameter validation */
766
767
if (!Handler)
768
{
769
return_ACPI_STATUS (AE_BAD_PARAMETER);
770
}
771
772
Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
773
if (ACPI_FAILURE (Status))
774
{
775
return_ACPI_STATUS (Status);
776
}
777
778
/* Don't allow two handlers. */
779
780
if (AcpiGbl_GlobalEventHandler)
781
{
782
Status = AE_ALREADY_EXISTS;
783
goto Cleanup;
784
}
785
786
AcpiGbl_GlobalEventHandler = Handler;
787
AcpiGbl_GlobalEventHandlerContext = Context;
788
789
790
Cleanup:
791
(void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
792
return_ACPI_STATUS (Status);
793
}
794
795
ACPI_EXPORT_SYMBOL (AcpiInstallGlobalEventHandler)
796
797
798
/*******************************************************************************
799
*
800
* FUNCTION: AcpiInstallFixedEventHandler
801
*
802
* PARAMETERS: Event - Event type to enable.
803
* Handler - Pointer to the handler function for the
804
* event
805
* Context - Value passed to the handler on each GPE
806
*
807
* RETURN: Status
808
*
809
* DESCRIPTION: Saves the pointer to the handler function and then enables the
810
* event.
811
*
812
******************************************************************************/
813
814
ACPI_STATUS
815
AcpiInstallFixedEventHandler (
816
UINT32 Event,
817
ACPI_EVENT_HANDLER Handler,
818
void *Context)
819
{
820
ACPI_STATUS Status;
821
822
823
ACPI_FUNCTION_TRACE (AcpiInstallFixedEventHandler);
824
825
826
/* Parameter validation */
827
828
if (Event > ACPI_EVENT_MAX)
829
{
830
return_ACPI_STATUS (AE_BAD_PARAMETER);
831
}
832
833
Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
834
if (ACPI_FAILURE (Status))
835
{
836
return_ACPI_STATUS (Status);
837
}
838
839
/* Do not allow multiple handlers */
840
841
if (AcpiGbl_FixedEventHandlers[Event].Handler)
842
{
843
Status = AE_ALREADY_EXISTS;
844
goto Cleanup;
845
}
846
847
/* Install the handler before enabling the event */
848
849
AcpiGbl_FixedEventHandlers[Event].Handler = Handler;
850
AcpiGbl_FixedEventHandlers[Event].Context = Context;
851
852
Status = AcpiEnableEvent (Event, 0);
853
if (ACPI_FAILURE (Status))
854
{
855
ACPI_WARNING ((AE_INFO,
856
"Could not enable fixed event - %s (%u)",
857
AcpiUtGetEventName (Event), Event));
858
859
/* Remove the handler */
860
861
AcpiGbl_FixedEventHandlers[Event].Handler = NULL;
862
AcpiGbl_FixedEventHandlers[Event].Context = NULL;
863
}
864
else
865
{
866
ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
867
"Enabled fixed event %s (%X), Handler=%p\n",
868
AcpiUtGetEventName (Event), Event, Handler));
869
}
870
871
872
Cleanup:
873
(void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
874
return_ACPI_STATUS (Status);
875
}
876
877
ACPI_EXPORT_SYMBOL (AcpiInstallFixedEventHandler)
878
879
880
/*******************************************************************************
881
*
882
* FUNCTION: AcpiRemoveFixedEventHandler
883
*
884
* PARAMETERS: Event - Event type to disable.
885
* Handler - Address of the handler
886
*
887
* RETURN: Status
888
*
889
* DESCRIPTION: Disables the event and unregisters the event handler.
890
*
891
******************************************************************************/
892
893
ACPI_STATUS
894
AcpiRemoveFixedEventHandler (
895
UINT32 Event,
896
ACPI_EVENT_HANDLER Handler)
897
{
898
ACPI_STATUS Status = AE_OK;
899
900
901
ACPI_FUNCTION_TRACE (AcpiRemoveFixedEventHandler);
902
903
904
/* Parameter validation */
905
906
if (Event > ACPI_EVENT_MAX)
907
{
908
return_ACPI_STATUS (AE_BAD_PARAMETER);
909
}
910
911
Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
912
if (ACPI_FAILURE (Status))
913
{
914
return_ACPI_STATUS (Status);
915
}
916
917
/* Disable the event before removing the handler */
918
919
Status = AcpiDisableEvent (Event, 0);
920
921
/* Always Remove the handler */
922
923
AcpiGbl_FixedEventHandlers[Event].Handler = NULL;
924
AcpiGbl_FixedEventHandlers[Event].Context = NULL;
925
926
if (ACPI_FAILURE (Status))
927
{
928
ACPI_WARNING ((AE_INFO,
929
"Could not disable fixed event - %s (%u)",
930
AcpiUtGetEventName (Event), Event));
931
}
932
else
933
{
934
ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
935
"Disabled fixed event - %s (%X)\n",
936
AcpiUtGetEventName (Event), Event));
937
}
938
939
(void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
940
return_ACPI_STATUS (Status);
941
}
942
943
ACPI_EXPORT_SYMBOL (AcpiRemoveFixedEventHandler)
944
945
946
/*******************************************************************************
947
*
948
* FUNCTION: AcpiEvInstallGpeHandler
949
*
950
* PARAMETERS: GpeDevice - Namespace node for the GPE (NULL for FADT
951
* defined GPEs)
952
* GpeNumber - The GPE number within the GPE block
953
* Type - Whether this GPE should be treated as an
954
* edge- or level-triggered interrupt.
955
* IsRawHandler - Whether this GPE should be handled using
956
* the special GPE handler mode.
957
* Address - Address of the handler
958
* Context - Value passed to the handler on each GPE
959
*
960
* RETURN: Status
961
*
962
* DESCRIPTION: Internal function to install a handler for a General Purpose
963
* Event.
964
*
965
******************************************************************************/
966
967
static ACPI_STATUS
968
AcpiEvInstallGpeHandler (
969
ACPI_HANDLE GpeDevice,
970
UINT32 GpeNumber,
971
UINT32 Type,
972
BOOLEAN IsRawHandler,
973
ACPI_GPE_HANDLER Address,
974
void *Context)
975
{
976
ACPI_GPE_EVENT_INFO *GpeEventInfo;
977
ACPI_GPE_HANDLER_INFO *Handler;
978
ACPI_STATUS Status;
979
ACPI_CPU_FLAGS Flags;
980
981
982
ACPI_FUNCTION_TRACE (EvInstallGpeHandler);
983
984
985
/* Parameter validation */
986
987
if ((!Address) || (Type & ~ACPI_GPE_XRUPT_TYPE_MASK))
988
{
989
return_ACPI_STATUS (AE_BAD_PARAMETER);
990
}
991
992
Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
993
if (ACPI_FAILURE (Status))
994
{
995
return_ACPI_STATUS (Status);
996
}
997
998
/* Allocate and init handler object (before lock) */
999
1000
Handler = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_GPE_HANDLER_INFO));
1001
if (!Handler)
1002
{
1003
Status = AE_NO_MEMORY;
1004
goto UnlockAndExit;
1005
}
1006
1007
Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
1008
1009
/* Ensure that we have a valid GPE number */
1010
1011
GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
1012
if (!GpeEventInfo)
1013
{
1014
Status = AE_BAD_PARAMETER;
1015
goto FreeAndExit;
1016
}
1017
1018
/* Make sure that there isn't a handler there already */
1019
1020
if ((ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) ==
1021
ACPI_GPE_DISPATCH_HANDLER) ||
1022
(ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) ==
1023
ACPI_GPE_DISPATCH_RAW_HANDLER))
1024
{
1025
Status = AE_ALREADY_EXISTS;
1026
goto FreeAndExit;
1027
}
1028
1029
Handler->Address = Address;
1030
Handler->Context = Context;
1031
Handler->MethodNode = GpeEventInfo->Dispatch.MethodNode;
1032
Handler->OriginalFlags = (UINT8) (GpeEventInfo->Flags &
1033
(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK));
1034
1035
/*
1036
* If the GPE is associated with a method, it may have been enabled
1037
* automatically during initialization, in which case it has to be
1038
* disabled now to avoid spurious execution of the handler.
1039
*/
1040
if (((ACPI_GPE_DISPATCH_TYPE (Handler->OriginalFlags) ==
1041
ACPI_GPE_DISPATCH_METHOD) ||
1042
(ACPI_GPE_DISPATCH_TYPE (Handler->OriginalFlags) ==
1043
ACPI_GPE_DISPATCH_NOTIFY)) &&
1044
GpeEventInfo->RuntimeCount)
1045
{
1046
Handler->OriginallyEnabled = TRUE;
1047
(void) AcpiEvRemoveGpeReference (GpeEventInfo);
1048
1049
/* Sanity check of original type against new type */
1050
1051
if (Type != (UINT32) (GpeEventInfo->Flags & ACPI_GPE_XRUPT_TYPE_MASK))
1052
{
1053
ACPI_WARNING ((AE_INFO, "GPE type mismatch (level/edge)"));
1054
}
1055
}
1056
1057
/* Install the handler */
1058
1059
GpeEventInfo->Dispatch.Handler = Handler;
1060
1061
/* Setup up dispatch flags to indicate handler (vs. method/notify) */
1062
1063
GpeEventInfo->Flags &= ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK);
1064
GpeEventInfo->Flags |= (UINT8) (Type | (IsRawHandler ?
1065
ACPI_GPE_DISPATCH_RAW_HANDLER : ACPI_GPE_DISPATCH_HANDLER));
1066
1067
AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
1068
1069
1070
UnlockAndExit:
1071
(void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
1072
return_ACPI_STATUS (Status);
1073
1074
FreeAndExit:
1075
AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
1076
ACPI_FREE (Handler);
1077
goto UnlockAndExit;
1078
}
1079
1080
1081
/*******************************************************************************
1082
*
1083
* FUNCTION: AcpiInstallGpeHandler
1084
*
1085
* PARAMETERS: GpeDevice - Namespace node for the GPE (NULL for FADT
1086
* defined GPEs)
1087
* GpeNumber - The GPE number within the GPE block
1088
* Type - Whether this GPE should be treated as an
1089
* edge- or level-triggered interrupt.
1090
* Address - Address of the handler
1091
* Context - Value passed to the handler on each GPE
1092
*
1093
* RETURN: Status
1094
*
1095
* DESCRIPTION: Install a handler for a General Purpose Event.
1096
*
1097
******************************************************************************/
1098
1099
ACPI_STATUS
1100
AcpiInstallGpeHandler (
1101
ACPI_HANDLE GpeDevice,
1102
UINT32 GpeNumber,
1103
UINT32 Type,
1104
ACPI_GPE_HANDLER Address,
1105
void *Context)
1106
{
1107
ACPI_STATUS Status;
1108
1109
1110
ACPI_FUNCTION_TRACE (AcpiInstallGpeHandler);
1111
1112
1113
Status = AcpiEvInstallGpeHandler (GpeDevice, GpeNumber, Type,
1114
FALSE, Address, Context);
1115
1116
return_ACPI_STATUS (Status);
1117
}
1118
1119
ACPI_EXPORT_SYMBOL (AcpiInstallGpeHandler)
1120
1121
1122
/*******************************************************************************
1123
*
1124
* FUNCTION: AcpiInstallGpeRawHandler
1125
*
1126
* PARAMETERS: GpeDevice - Namespace node for the GPE (NULL for FADT
1127
* defined GPEs)
1128
* GpeNumber - The GPE number within the GPE block
1129
* Type - Whether this GPE should be treated as an
1130
* edge- or level-triggered interrupt.
1131
* Address - Address of the handler
1132
* Context - Value passed to the handler on each GPE
1133
*
1134
* RETURN: Status
1135
*
1136
* DESCRIPTION: Install a handler for a General Purpose Event.
1137
*
1138
******************************************************************************/
1139
1140
ACPI_STATUS
1141
AcpiInstallGpeRawHandler (
1142
ACPI_HANDLE GpeDevice,
1143
UINT32 GpeNumber,
1144
UINT32 Type,
1145
ACPI_GPE_HANDLER Address,
1146
void *Context)
1147
{
1148
ACPI_STATUS Status;
1149
1150
1151
ACPI_FUNCTION_TRACE (AcpiInstallGpeRawHandler);
1152
1153
1154
Status = AcpiEvInstallGpeHandler (GpeDevice, GpeNumber, Type,
1155
TRUE, Address, Context);
1156
1157
return_ACPI_STATUS (Status);
1158
}
1159
1160
ACPI_EXPORT_SYMBOL (AcpiInstallGpeRawHandler)
1161
1162
1163
/*******************************************************************************
1164
*
1165
* FUNCTION: AcpiRemoveGpeHandler
1166
*
1167
* PARAMETERS: GpeDevice - Namespace node for the GPE (NULL for FADT
1168
* defined GPEs)
1169
* GpeNumber - The event to remove a handler
1170
* Address - Address of the handler
1171
*
1172
* RETURN: Status
1173
*
1174
* DESCRIPTION: Remove a handler for a General Purpose AcpiEvent.
1175
*
1176
******************************************************************************/
1177
1178
ACPI_STATUS
1179
AcpiRemoveGpeHandler (
1180
ACPI_HANDLE GpeDevice,
1181
UINT32 GpeNumber,
1182
ACPI_GPE_HANDLER Address)
1183
{
1184
ACPI_GPE_EVENT_INFO *GpeEventInfo;
1185
ACPI_GPE_HANDLER_INFO *Handler;
1186
ACPI_STATUS Status;
1187
ACPI_CPU_FLAGS Flags;
1188
1189
1190
ACPI_FUNCTION_TRACE (AcpiRemoveGpeHandler);
1191
1192
1193
/* Parameter validation */
1194
1195
if (!Address)
1196
{
1197
return_ACPI_STATUS (AE_BAD_PARAMETER);
1198
}
1199
1200
Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
1201
if (ACPI_FAILURE (Status))
1202
{
1203
return_ACPI_STATUS (Status);
1204
}
1205
1206
Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
1207
1208
/* Ensure that we have a valid GPE number */
1209
1210
GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
1211
if (!GpeEventInfo)
1212
{
1213
Status = AE_BAD_PARAMETER;
1214
goto UnlockAndExit;
1215
}
1216
1217
/* Make sure that a handler is indeed installed */
1218
1219
if ((ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) !=
1220
ACPI_GPE_DISPATCH_HANDLER) &&
1221
(ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) !=
1222
ACPI_GPE_DISPATCH_RAW_HANDLER))
1223
{
1224
Status = AE_NOT_EXIST;
1225
goto UnlockAndExit;
1226
}
1227
1228
/* Make sure that the installed handler is the same */
1229
1230
if (GpeEventInfo->Dispatch.Handler->Address != Address)
1231
{
1232
Status = AE_BAD_PARAMETER;
1233
goto UnlockAndExit;
1234
}
1235
1236
/* Remove the handler */
1237
1238
Handler = GpeEventInfo->Dispatch.Handler;
1239
GpeEventInfo->Dispatch.Handler = NULL;
1240
1241
/* Restore Method node (if any), set dispatch flags */
1242
1243
GpeEventInfo->Dispatch.MethodNode = Handler->MethodNode;
1244
GpeEventInfo->Flags &=
1245
~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK);
1246
GpeEventInfo->Flags |= Handler->OriginalFlags;
1247
1248
/*
1249
* If the GPE was previously associated with a method and it was
1250
* enabled, it should be enabled at this point to restore the
1251
* post-initialization configuration.
1252
*/
1253
if (((ACPI_GPE_DISPATCH_TYPE (Handler->OriginalFlags) ==
1254
ACPI_GPE_DISPATCH_METHOD) ||
1255
(ACPI_GPE_DISPATCH_TYPE (Handler->OriginalFlags) ==
1256
ACPI_GPE_DISPATCH_NOTIFY)) &&
1257
Handler->OriginallyEnabled)
1258
{
1259
(void) AcpiEvAddGpeReference (GpeEventInfo, FALSE);
1260
if (ACPI_GPE_IS_POLLING_NEEDED (GpeEventInfo))
1261
{
1262
/* Poll edge triggered GPEs to handle existing events */
1263
1264
AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
1265
(void) AcpiEvDetectGpe (
1266
GpeDevice, GpeEventInfo, GpeNumber);
1267
Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
1268
}
1269
}
1270
1271
AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
1272
(void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
1273
1274
/* Make sure all deferred GPE tasks are completed */
1275
1276
AcpiOsWaitEventsComplete ();
1277
1278
/* Now we can free the handler object */
1279
1280
ACPI_FREE (Handler);
1281
return_ACPI_STATUS (Status);
1282
1283
UnlockAndExit:
1284
AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
1285
(void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
1286
return_ACPI_STATUS (Status);
1287
}
1288
1289
ACPI_EXPORT_SYMBOL (AcpiRemoveGpeHandler)
1290
1291
1292
/*******************************************************************************
1293
*
1294
* FUNCTION: AcpiAcquireGlobalLock
1295
*
1296
* PARAMETERS: Timeout - How long the caller is willing to wait
1297
* Handle - Where the handle to the lock is returned
1298
* (if acquired)
1299
*
1300
* RETURN: Status
1301
*
1302
* DESCRIPTION: Acquire the ACPI Global Lock
1303
*
1304
* Note: Allows callers with the same thread ID to acquire the global lock
1305
* multiple times. In other words, externally, the behavior of the global lock
1306
* is identical to an AML mutex. On the first acquire, a new handle is
1307
* returned. On any subsequent calls to acquire by the same thread, the same
1308
* handle is returned.
1309
*
1310
******************************************************************************/
1311
1312
ACPI_STATUS
1313
AcpiAcquireGlobalLock (
1314
UINT16 Timeout,
1315
UINT32 *Handle)
1316
{
1317
ACPI_STATUS Status;
1318
1319
1320
if (!Handle)
1321
{
1322
return (AE_BAD_PARAMETER);
1323
}
1324
1325
/* Must lock interpreter to prevent race conditions */
1326
1327
AcpiExEnterInterpreter ();
1328
1329
Status = AcpiExAcquireMutexObject (Timeout,
1330
AcpiGbl_GlobalLockMutex, AcpiOsGetThreadId ());
1331
1332
if (ACPI_SUCCESS (Status))
1333
{
1334
/* Return the global lock handle (updated in AcpiEvAcquireGlobalLock) */
1335
1336
*Handle = AcpiGbl_GlobalLockHandle;
1337
}
1338
1339
AcpiExExitInterpreter ();
1340
return (Status);
1341
}
1342
1343
ACPI_EXPORT_SYMBOL (AcpiAcquireGlobalLock)
1344
1345
1346
/*******************************************************************************
1347
*
1348
* FUNCTION: AcpiReleaseGlobalLock
1349
*
1350
* PARAMETERS: Handle - Returned from AcpiAcquireGlobalLock
1351
*
1352
* RETURN: Status
1353
*
1354
* DESCRIPTION: Release the ACPI Global Lock. The handle must be valid.
1355
*
1356
******************************************************************************/
1357
1358
ACPI_STATUS
1359
AcpiReleaseGlobalLock (
1360
UINT32 Handle)
1361
{
1362
ACPI_STATUS Status;
1363
1364
1365
if (!Handle || (Handle != AcpiGbl_GlobalLockHandle))
1366
{
1367
return (AE_NOT_ACQUIRED);
1368
}
1369
1370
Status = AcpiExReleaseMutexObject (AcpiGbl_GlobalLockMutex);
1371
return (Status);
1372
}
1373
1374
ACPI_EXPORT_SYMBOL (AcpiReleaseGlobalLock)
1375
1376
#endif /* !ACPI_REDUCED_HARDWARE */
1377
1378