utxface.c revision 1.1.1.2 1 /******************************************************************************
2 *
3 * Module Name: utxface - External interfaces for "global" ACPI functions
4 *
5 *****************************************************************************/
6
7 /*
8 * Copyright (C) 2000 - 2011, Intel Corp.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44
45 #define __UTXFACE_C__
46
47 #include "acpi.h"
48 #include "accommon.h"
49 #include "acevents.h"
50 #include "acnamesp.h"
51 #include "acdebug.h"
52 #include "actables.h"
53
54 #define _COMPONENT ACPI_UTILITIES
55 ACPI_MODULE_NAME ("utxface")
56
57
58 #ifndef ACPI_ASL_COMPILER
59
60 /*******************************************************************************
61 *
62 * FUNCTION: AcpiInitializeSubsystem
63 *
64 * PARAMETERS: None
65 *
66 * RETURN: Status
67 *
68 * DESCRIPTION: Initializes all global variables. This is the first function
69 * called, so any early initialization belongs here.
70 *
71 ******************************************************************************/
72
73 ACPI_STATUS
74 AcpiInitializeSubsystem (
75 void)
76 {
77 ACPI_STATUS Status;
78
79
80 ACPI_FUNCTION_TRACE (AcpiInitializeSubsystem);
81
82
83 AcpiGbl_StartupFlags = ACPI_SUBSYSTEM_INITIALIZE;
84 ACPI_DEBUG_EXEC (AcpiUtInitStackPtrTrace ());
85
86 /* Initialize the OS-Dependent layer */
87
88 Status = AcpiOsInitialize ();
89 if (ACPI_FAILURE (Status))
90 {
91 ACPI_EXCEPTION ((AE_INFO, Status, "During OSL initialization"));
92 return_ACPI_STATUS (Status);
93 }
94
95 /* Initialize all globals used by the subsystem */
96
97 Status = AcpiUtInitGlobals ();
98 if (ACPI_FAILURE (Status))
99 {
100 ACPI_EXCEPTION ((AE_INFO, Status, "During initialization of globals"));
101 return_ACPI_STATUS (Status);
102 }
103
104 /* Create the default mutex objects */
105
106 Status = AcpiUtMutexInitialize ();
107 if (ACPI_FAILURE (Status))
108 {
109 ACPI_EXCEPTION ((AE_INFO, Status, "During Global Mutex creation"));
110 return_ACPI_STATUS (Status);
111 }
112
113 /*
114 * Initialize the namespace manager and
115 * the root of the namespace tree
116 */
117 Status = AcpiNsRootInitialize ();
118 if (ACPI_FAILURE (Status))
119 {
120 ACPI_EXCEPTION ((AE_INFO, Status, "During Namespace initialization"));
121 return_ACPI_STATUS (Status);
122 }
123
124 /* Initialize the global OSI interfaces list with the static names */
125
126 Status = AcpiUtInitializeInterfaces ();
127 if (ACPI_FAILURE (Status))
128 {
129 ACPI_EXCEPTION ((AE_INFO, Status, "During OSI interfaces initialization"));
130 return_ACPI_STATUS (Status);
131 }
132
133 /* If configured, initialize the AML debugger */
134
135 ACPI_DEBUGGER_EXEC (Status = AcpiDbInitialize ());
136 return_ACPI_STATUS (Status);
137 }
138
139 ACPI_EXPORT_SYMBOL (AcpiInitializeSubsystem)
140
141
142 /*******************************************************************************
143 *
144 * FUNCTION: AcpiEnableSubsystem
145 *
146 * PARAMETERS: Flags - Init/enable Options
147 *
148 * RETURN: Status
149 *
150 * DESCRIPTION: Completes the subsystem initialization including hardware.
151 * Puts system into ACPI mode if it isn't already.
152 *
153 ******************************************************************************/
154
155 ACPI_STATUS
156 AcpiEnableSubsystem (
157 UINT32 Flags)
158 {
159 ACPI_STATUS Status = AE_OK;
160
161
162 ACPI_FUNCTION_TRACE (AcpiEnableSubsystem);
163
164
165 /* Enable ACPI mode */
166
167 if (!(Flags & ACPI_NO_ACPI_ENABLE))
168 {
169 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Going into ACPI mode\n"));
170
171 AcpiGbl_OriginalMode = AcpiHwGetMode();
172
173 Status = AcpiEnable ();
174 if (ACPI_FAILURE (Status))
175 {
176 ACPI_WARNING ((AE_INFO, "AcpiEnable failed"));
177 return_ACPI_STATUS (Status);
178 }
179 }
180
181 /*
182 * Obtain a permanent mapping for the FACS. This is required for the
183 * Global Lock and the Firmware Waking Vector
184 */
185 Status = AcpiTbInitializeFacs ();
186 if (ACPI_FAILURE (Status))
187 {
188 ACPI_WARNING ((AE_INFO, "Could not map the FACS table"));
189 return_ACPI_STATUS (Status);
190 }
191
192 /*
193 * Install the default OpRegion handlers. These are installed unless
194 * other handlers have already been installed via the
195 * InstallAddressSpaceHandler interface.
196 */
197 if (!(Flags & ACPI_NO_ADDRESS_SPACE_INIT))
198 {
199 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
200 "[Init] Installing default address space handlers\n"));
201
202 Status = AcpiEvInstallRegionHandlers ();
203 if (ACPI_FAILURE (Status))
204 {
205 return_ACPI_STATUS (Status);
206 }
207 }
208
209 /*
210 * Initialize ACPI Event handling (Fixed and General Purpose)
211 *
212 * Note1: We must have the hardware and events initialized before we can
213 * execute any control methods safely. Any control method can require
214 * ACPI hardware support, so the hardware must be fully initialized before
215 * any method execution!
216 *
217 * Note2: Fixed events are initialized and enabled here. GPEs are
218 * initialized, but cannot be enabled until after the hardware is
219 * completely initialized (SCI and GlobalLock activated) and the various
220 * initialization control methods are run (_REG, _STA, _INI) on the
221 * entire namespace.
222 */
223 if (!(Flags & ACPI_NO_EVENT_INIT))
224 {
225 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
226 "[Init] Initializing ACPI events\n"));
227
228 Status = AcpiEvInitializeEvents ();
229 if (ACPI_FAILURE (Status))
230 {
231 return_ACPI_STATUS (Status);
232 }
233 }
234
235 /*
236 * Install the SCI handler and Global Lock handler. This completes the
237 * hardware initialization.
238 */
239 if (!(Flags & ACPI_NO_HANDLER_INIT))
240 {
241 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
242 "[Init] Installing SCI/GL handlers\n"));
243
244 Status = AcpiEvInstallXruptHandlers ();
245 if (ACPI_FAILURE (Status))
246 {
247 return_ACPI_STATUS (Status);
248 }
249 }
250
251 return_ACPI_STATUS (Status);
252 }
253
254 ACPI_EXPORT_SYMBOL (AcpiEnableSubsystem)
255
256
257 /*******************************************************************************
258 *
259 * FUNCTION: AcpiInitializeObjects
260 *
261 * PARAMETERS: Flags - Init/enable Options
262 *
263 * RETURN: Status
264 *
265 * DESCRIPTION: Completes namespace initialization by initializing device
266 * objects and executing AML code for Regions, buffers, etc.
267 *
268 ******************************************************************************/
269
270 ACPI_STATUS
271 AcpiInitializeObjects (
272 UINT32 Flags)
273 {
274 ACPI_STATUS Status = AE_OK;
275
276
277 ACPI_FUNCTION_TRACE (AcpiInitializeObjects);
278
279
280 /*
281 * Run all _REG methods
282 *
283 * Note: Any objects accessed by the _REG methods will be automatically
284 * initialized, even if they contain executable AML (see the call to
285 * AcpiNsInitializeObjects below).
286 */
287 if (!(Flags & ACPI_NO_ADDRESS_SPACE_INIT))
288 {
289 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
290 "[Init] Executing _REG OpRegion methods\n"));
291
292 Status = AcpiEvInitializeOpRegions ();
293 if (ACPI_FAILURE (Status))
294 {
295 return_ACPI_STATUS (Status);
296 }
297 }
298
299 /*
300 * Execute any module-level code that was detected during the table load
301 * phase. Although illegal since ACPI 2.0, there are many machines that
302 * contain this type of code. Each block of detected executable AML code
303 * outside of any control method is wrapped with a temporary control
304 * method object and placed on a global list. The methods on this list
305 * are executed below.
306 */
307 AcpiNsExecModuleCodeList ();
308
309 /*
310 * Initialize the objects that remain uninitialized. This runs the
311 * executable AML that may be part of the declaration of these objects:
312 * OperationRegions, BufferFields, Buffers, and Packages.
313 */
314 if (!(Flags & ACPI_NO_OBJECT_INIT))
315 {
316 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
317 "[Init] Completing Initialization of ACPI Objects\n"));
318
319 Status = AcpiNsInitializeObjects ();
320 if (ACPI_FAILURE (Status))
321 {
322 return_ACPI_STATUS (Status);
323 }
324 }
325
326 /*
327 * Initialize all device objects in the namespace. This runs the device
328 * _STA and _INI methods.
329 */
330 if (!(Flags & ACPI_NO_DEVICE_INIT))
331 {
332 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
333 "[Init] Initializing ACPI Devices\n"));
334
335 Status = AcpiNsInitializeDevices ();
336 if (ACPI_FAILURE (Status))
337 {
338 return_ACPI_STATUS (Status);
339 }
340 }
341
342 /*
343 * Empty the caches (delete the cached objects) on the assumption that
344 * the table load filled them up more than they will be at runtime --
345 * thus wasting non-paged memory.
346 */
347 Status = AcpiPurgeCachedObjects ();
348
349 AcpiGbl_StartupFlags |= ACPI_INITIALIZED_OK;
350 return_ACPI_STATUS (Status);
351 }
352
353 ACPI_EXPORT_SYMBOL (AcpiInitializeObjects)
354
355
356 #endif
357
358 /*******************************************************************************
359 *
360 * FUNCTION: AcpiTerminate
361 *
362 * PARAMETERS: None
363 *
364 * RETURN: Status
365 *
366 * DESCRIPTION: Shutdown the ACPICA subsystem and release all resources.
367 *
368 ******************************************************************************/
369
370 ACPI_STATUS
371 AcpiTerminate (
372 void)
373 {
374 ACPI_STATUS Status;
375
376
377 ACPI_FUNCTION_TRACE (AcpiTerminate);
378
379
380 /* Just exit if subsystem is already shutdown */
381
382 if (AcpiGbl_Shutdown)
383 {
384 ACPI_ERROR ((AE_INFO, "ACPI Subsystem is already terminated"));
385 return_ACPI_STATUS (AE_OK);
386 }
387
388 /* Subsystem appears active, go ahead and shut it down */
389
390 AcpiGbl_Shutdown = TRUE;
391 AcpiGbl_StartupFlags = 0;
392 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Shutting down ACPI Subsystem\n"));
393
394 /* Terminate the AML Debugger if present */
395
396 ACPI_DEBUGGER_EXEC (AcpiGbl_DbTerminateThreads = TRUE);
397
398 /* Shutdown and free all resources */
399
400 AcpiUtSubsystemShutdown ();
401
402 /* Free the mutex objects */
403
404 AcpiUtMutexTerminate ();
405
406
407 #ifdef ACPI_DEBUGGER
408
409 /* Shut down the debugger */
410
411 AcpiDbTerminate ();
412 #endif
413
414 /* Now we can shutdown the OS-dependent layer */
415
416 Status = AcpiOsTerminate ();
417 return_ACPI_STATUS (Status);
418 }
419
420 ACPI_EXPORT_SYMBOL (AcpiTerminate)
421
422
423 #ifndef ACPI_ASL_COMPILER
424 /*******************************************************************************
425 *
426 * FUNCTION: AcpiSubsystemStatus
427 *
428 * PARAMETERS: None
429 *
430 * RETURN: Status of the ACPI subsystem
431 *
432 * DESCRIPTION: Other drivers that use the ACPI subsystem should call this
433 * before making any other calls, to ensure the subsystem
434 * initialized successfully.
435 *
436 ******************************************************************************/
437
438 ACPI_STATUS
439 AcpiSubsystemStatus (
440 void)
441 {
442
443 if (AcpiGbl_StartupFlags & ACPI_INITIALIZED_OK)
444 {
445 return (AE_OK);
446 }
447 else
448 {
449 return (AE_ERROR);
450 }
451 }
452
453 ACPI_EXPORT_SYMBOL (AcpiSubsystemStatus)
454
455
456 /*******************************************************************************
457 *
458 * FUNCTION: AcpiGetSystemInfo
459 *
460 * PARAMETERS: OutBuffer - A buffer to receive the resources for the
461 * device
462 *
463 * RETURN: Status - the status of the call
464 *
465 * DESCRIPTION: This function is called to get information about the current
466 * state of the ACPI subsystem. It will return system information
467 * in the OutBuffer.
468 *
469 * If the function fails an appropriate status will be returned
470 * and the value of OutBuffer is undefined.
471 *
472 ******************************************************************************/
473
474 ACPI_STATUS
475 AcpiGetSystemInfo (
476 ACPI_BUFFER *OutBuffer)
477 {
478 ACPI_SYSTEM_INFO *InfoPtr;
479 ACPI_STATUS Status;
480
481
482 ACPI_FUNCTION_TRACE (AcpiGetSystemInfo);
483
484
485 /* Parameter validation */
486
487 Status = AcpiUtValidateBuffer (OutBuffer);
488 if (ACPI_FAILURE (Status))
489 {
490 return_ACPI_STATUS (Status);
491 }
492
493 /* Validate/Allocate/Clear caller buffer */
494
495 Status = AcpiUtInitializeBuffer (OutBuffer, sizeof (ACPI_SYSTEM_INFO));
496 if (ACPI_FAILURE (Status))
497 {
498 return_ACPI_STATUS (Status);
499 }
500
501 /*
502 * Populate the return buffer
503 */
504 InfoPtr = (ACPI_SYSTEM_INFO *) OutBuffer->Pointer;
505
506 InfoPtr->AcpiCaVersion = ACPI_CA_VERSION;
507
508 /* System flags (ACPI capabilities) */
509
510 InfoPtr->Flags = ACPI_SYS_MODE_ACPI;
511
512 /* Timer resolution - 24 or 32 bits */
513
514 if (AcpiGbl_FADT.Flags & ACPI_FADT_32BIT_TIMER)
515 {
516 InfoPtr->TimerResolution = 24;
517 }
518 else
519 {
520 InfoPtr->TimerResolution = 32;
521 }
522
523 /* Clear the reserved fields */
524
525 InfoPtr->Reserved1 = 0;
526 InfoPtr->Reserved2 = 0;
527
528 /* Current debug levels */
529
530 InfoPtr->DebugLayer = AcpiDbgLayer;
531 InfoPtr->DebugLevel = AcpiDbgLevel;
532
533 return_ACPI_STATUS (AE_OK);
534 }
535
536 ACPI_EXPORT_SYMBOL (AcpiGetSystemInfo)
537
538
539 /*******************************************************************************
540 *
541 * FUNCTION: AcpiGetStatistics
542 *
543 * PARAMETERS: Stats - Where the statistics are returned
544 *
545 * RETURN: Status - the status of the call
546 *
547 * DESCRIPTION: Get the contents of the various system counters
548 *
549 ******************************************************************************/
550
551 ACPI_STATUS
552 AcpiGetStatistics (
553 ACPI_STATISTICS *Stats)
554 {
555 ACPI_FUNCTION_TRACE (AcpiGetStatistics);
556
557
558 /* Parameter validation */
559
560 if (!Stats)
561 {
562 return_ACPI_STATUS (AE_BAD_PARAMETER);
563 }
564
565 /* Various interrupt-based event counters */
566
567 Stats->SciCount = AcpiSciCount;
568 Stats->GpeCount = AcpiGpeCount;
569
570 ACPI_MEMCPY (Stats->FixedEventCount, AcpiFixedEventCount,
571 sizeof (AcpiFixedEventCount));
572
573
574 /* Other counters */
575
576 Stats->MethodCount = AcpiMethodCount;
577
578 return_ACPI_STATUS (AE_OK);
579 }
580
581 ACPI_EXPORT_SYMBOL (AcpiGetStatistics)
582
583
584 /*****************************************************************************
585 *
586 * FUNCTION: AcpiInstallInitializationHandler
587 *
588 * PARAMETERS: Handler - Callback procedure
589 * Function - Not (currently) used, see below
590 *
591 * RETURN: Status
592 *
593 * DESCRIPTION: Install an initialization handler
594 *
595 * TBD: When a second function is added, must save the Function also.
596 *
597 ****************************************************************************/
598
599 ACPI_STATUS
600 AcpiInstallInitializationHandler (
601 ACPI_INIT_HANDLER Handler,
602 UINT32 Function)
603 {
604
605 if (!Handler)
606 {
607 return (AE_BAD_PARAMETER);
608 }
609
610 if (AcpiGbl_InitHandler)
611 {
612 return (AE_ALREADY_EXISTS);
613 }
614
615 AcpiGbl_InitHandler = Handler;
616 return AE_OK;
617 }
618
619 ACPI_EXPORT_SYMBOL (AcpiInstallInitializationHandler)
620
621
622 /*****************************************************************************
623 *
624 * FUNCTION: AcpiPurgeCachedObjects
625 *
626 * PARAMETERS: None
627 *
628 * RETURN: Status
629 *
630 * DESCRIPTION: Empty all caches (delete the cached objects)
631 *
632 ****************************************************************************/
633
634 ACPI_STATUS
635 AcpiPurgeCachedObjects (
636 void)
637 {
638 ACPI_FUNCTION_TRACE (AcpiPurgeCachedObjects);
639
640 (void) AcpiOsPurgeCache (AcpiGbl_StateCache);
641 (void) AcpiOsPurgeCache (AcpiGbl_OperandCache);
642 (void) AcpiOsPurgeCache (AcpiGbl_PsNodeCache);
643 (void) AcpiOsPurgeCache (AcpiGbl_PsNodeExtCache);
644 return_ACPI_STATUS (AE_OK);
645 }
646
647 ACPI_EXPORT_SYMBOL (AcpiPurgeCachedObjects)
648
649
650 /*****************************************************************************
651 *
652 * FUNCTION: AcpiInstallInterface
653 *
654 * PARAMETERS: InterfaceName - The interface to install
655 *
656 * RETURN: Status
657 *
658 * DESCRIPTION: Install an _OSI interface to the global list
659 *
660 ****************************************************************************/
661
662 ACPI_STATUS
663 AcpiInstallInterface (
664 ACPI_STRING InterfaceName)
665 {
666 ACPI_STATUS Status;
667 ACPI_INTERFACE_INFO *InterfaceInfo;
668
669
670 /* Parameter validation */
671
672 if (!InterfaceName || (ACPI_STRLEN (InterfaceName) == 0))
673 {
674 return (AE_BAD_PARAMETER);
675 }
676
677 (void) AcpiOsAcquireMutex (AcpiGbl_OsiMutex, ACPI_WAIT_FOREVER);
678
679 /* Check if the interface name is already in the global list */
680
681 InterfaceInfo = AcpiUtGetInterface (InterfaceName);
682 if (InterfaceInfo)
683 {
684 /*
685 * The interface already exists in the list. This is OK if the
686 * interface has been marked invalid -- just clear the bit.
687 */
688 if (InterfaceInfo->Flags & ACPI_OSI_INVALID)
689 {
690 InterfaceInfo->Flags &= ~ACPI_OSI_INVALID;
691 Status = AE_OK;
692 }
693 else
694 {
695 Status = AE_ALREADY_EXISTS;
696 }
697 }
698 else
699 {
700 /* New interface name, install into the global list */
701
702 Status = AcpiUtInstallInterface (InterfaceName);
703 }
704
705 AcpiOsReleaseMutex (AcpiGbl_OsiMutex);
706 return (Status);
707 }
708
709 ACPI_EXPORT_SYMBOL (AcpiInstallInterface)
710
711
712 /*****************************************************************************
713 *
714 * FUNCTION: AcpiRemoveInterface
715 *
716 * PARAMETERS: InterfaceName - The interface to remove
717 *
718 * RETURN: Status
719 *
720 * DESCRIPTION: Remove an _OSI interface from the global list
721 *
722 ****************************************************************************/
723
724 ACPI_STATUS
725 AcpiRemoveInterface (
726 ACPI_STRING InterfaceName)
727 {
728 ACPI_STATUS Status;
729
730
731 /* Parameter validation */
732
733 if (!InterfaceName || (ACPI_STRLEN (InterfaceName) == 0))
734 {
735 return (AE_BAD_PARAMETER);
736 }
737
738 (void) AcpiOsAcquireMutex (AcpiGbl_OsiMutex, ACPI_WAIT_FOREVER);
739
740 Status = AcpiUtRemoveInterface (InterfaceName);
741
742 AcpiOsReleaseMutex (AcpiGbl_OsiMutex);
743 return (Status);
744 }
745
746 ACPI_EXPORT_SYMBOL (AcpiRemoveInterface)
747
748
749 /*****************************************************************************
750 *
751 * FUNCTION: AcpiInstallInterfaceHandler
752 *
753 * PARAMETERS: Handler - The _OSI interface handler to install
754 * NULL means "remove existing handler"
755 *
756 * RETURN: Status
757 *
758 * DESCRIPTION: Install a handler for the predefined _OSI ACPI method.
759 * invoked during execution of the internal implementation of
760 * _OSI. A NULL handler simply removes any existing handler.
761 *
762 ****************************************************************************/
763
764 ACPI_STATUS
765 AcpiInstallInterfaceHandler (
766 ACPI_INTERFACE_HANDLER Handler)
767 {
768 ACPI_STATUS Status = AE_OK;
769
770
771 (void) AcpiOsAcquireMutex (AcpiGbl_OsiMutex, ACPI_WAIT_FOREVER);
772
773 if (Handler && AcpiGbl_InterfaceHandler)
774 {
775 Status = AE_ALREADY_EXISTS;
776 }
777 else
778 {
779 AcpiGbl_InterfaceHandler = Handler;
780 }
781
782 AcpiOsReleaseMutex (AcpiGbl_OsiMutex);
783 return (Status);
784 }
785
786 ACPI_EXPORT_SYMBOL (AcpiInstallInterfaceHandler)
787
788 #endif /* !ACPI_ASL_COMPILER */
789
790