vserver 1.9.3
[linux-2.6.git] / drivers / acpi / events / evxfevnt.c
1 /******************************************************************************
2  *
3  * Module Name: evxfevnt - External Interfaces, ACPI event disable/enable
4  *
5  *****************************************************************************/
6
7 /*
8  * Copyright (C) 2000 - 2004, R. Byron Moore
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 #include <acpi/acpi.h>
46 #include <acpi/acevents.h>
47 #include <acpi/acnamesp.h>
48
49 #define _COMPONENT          ACPI_EVENTS
50          ACPI_MODULE_NAME    ("evxfevnt")
51
52
53 /*******************************************************************************
54  *
55  * FUNCTION:    acpi_enable
56  *
57  * PARAMETERS:  None
58  *
59  * RETURN:      Status
60  *
61  * DESCRIPTION: Transfers the system into ACPI mode.
62  *
63  ******************************************************************************/
64
65 acpi_status
66 acpi_enable (void)
67 {
68         acpi_status                     status = AE_OK;
69
70
71         ACPI_FUNCTION_TRACE ("acpi_enable");
72
73
74         /* Make sure we have the FADT*/
75
76         if (!acpi_gbl_FADT) {
77                 ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "No FADT information present!\n"));
78                 return_ACPI_STATUS (AE_NO_ACPI_TABLES);
79         }
80
81         if (acpi_hw_get_mode() == ACPI_SYS_MODE_ACPI) {
82                 ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "System is already in ACPI mode\n"));
83         }
84         else {
85                 /* Transition to ACPI mode */
86
87                 status = acpi_hw_set_mode (ACPI_SYS_MODE_ACPI);
88                 if (ACPI_FAILURE (status)) {
89                         ACPI_REPORT_ERROR (("Could not transition to ACPI mode.\n"));
90                         return_ACPI_STATUS (status);
91                 }
92
93                 ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "Transition to ACPI mode successful\n"));
94         }
95
96         return_ACPI_STATUS (status);
97 }
98
99
100 /*******************************************************************************
101  *
102  * FUNCTION:    acpi_disable
103  *
104  * PARAMETERS:  None
105  *
106  * RETURN:      Status
107  *
108  * DESCRIPTION: Transfers the system into LEGACY mode.
109  *
110  ******************************************************************************/
111
112 acpi_status
113 acpi_disable (void)
114 {
115         acpi_status                     status = AE_OK;
116
117
118         ACPI_FUNCTION_TRACE ("acpi_disable");
119
120
121         if (!acpi_gbl_FADT) {
122                 ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "No FADT information present!\n"));
123                 return_ACPI_STATUS (AE_NO_ACPI_TABLES);
124         }
125
126         if (acpi_hw_get_mode() == ACPI_SYS_MODE_LEGACY) {
127                 ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "System is already in legacy (non-ACPI) mode\n"));
128         }
129         else {
130                 /* Transition to LEGACY mode */
131
132                 status = acpi_hw_set_mode (ACPI_SYS_MODE_LEGACY);
133
134                 if (ACPI_FAILURE (status)) {
135                         ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not exit ACPI mode to legacy mode"));
136                         return_ACPI_STATUS (status);
137                 }
138
139                 ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "ACPI mode disabled\n"));
140         }
141
142         return_ACPI_STATUS (status);
143 }
144
145
146 /*******************************************************************************
147  *
148  * FUNCTION:    acpi_enable_event
149  *
150  * PARAMETERS:  Event           - The fixed eventto be enabled
151  *              Flags           - Reserved
152  *
153  * RETURN:      Status
154  *
155  * DESCRIPTION: Enable an ACPI event (fixed)
156  *
157  ******************************************************************************/
158
159 acpi_status
160 acpi_enable_event (
161         u32                             event,
162         u32                             flags)
163 {
164         acpi_status                     status = AE_OK;
165         u32                             value;
166
167
168         ACPI_FUNCTION_TRACE ("acpi_enable_event");
169
170
171         /* Decode the Fixed Event */
172
173         if (event > ACPI_EVENT_MAX) {
174                 return_ACPI_STATUS (AE_BAD_PARAMETER);
175         }
176
177         /*
178          * Enable the requested fixed event (by writing a one to the
179          * enable register bit)
180          */
181         status = acpi_set_register (acpi_gbl_fixed_event_info[event].enable_register_id,
182                          1, ACPI_MTX_LOCK);
183         if (ACPI_FAILURE (status)) {
184                 return_ACPI_STATUS (status);
185         }
186
187         /* Make sure that the hardware responded */
188
189         status = acpi_get_register (acpi_gbl_fixed_event_info[event].enable_register_id,
190                           &value, ACPI_MTX_LOCK);
191         if (ACPI_FAILURE (status)) {
192                 return_ACPI_STATUS (status);
193         }
194
195         if (value != 1) {
196                 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
197                         "Could not enable %s event\n", acpi_ut_get_event_name (event)));
198                 return_ACPI_STATUS (AE_NO_HARDWARE_RESPONSE);
199         }
200
201         return_ACPI_STATUS (status);
202 }
203
204
205 /*******************************************************************************
206  *
207  * FUNCTION:    acpi_set_gpe_type
208  *
209  * PARAMETERS:  gpe_device      - Parent GPE Device
210  *              gpe_number      - GPE level within the GPE block
211  *              Type            - New GPE type
212  *
213  * RETURN:      Status
214  *
215  * DESCRIPTION: Enable an ACPI event (general purpose)
216  *
217  ******************************************************************************/
218
219 acpi_status
220 acpi_set_gpe_type (
221         acpi_handle                     gpe_device,
222         u32                             gpe_number,
223         u8                              type)
224 {
225         acpi_status                     status = AE_OK;
226         struct acpi_gpe_event_info      *gpe_event_info;
227
228
229         ACPI_FUNCTION_TRACE ("acpi_set_gpe_type");
230
231
232         /* Ensure that we have a valid GPE number */
233
234         gpe_event_info = acpi_ev_get_gpe_event_info (gpe_device, gpe_number);
235         if (!gpe_event_info) {
236                 status = AE_BAD_PARAMETER;
237                 goto unlock_and_exit;
238         }
239
240         if ((gpe_event_info->flags & ACPI_GPE_TYPE_MASK) == type) {
241                 return_ACPI_STATUS (AE_OK);
242         }
243
244         /* Set the new type (will disable GPE if currently enabled) */
245
246         status = acpi_ev_set_gpe_type (gpe_event_info, type);
247
248 unlock_and_exit:
249         return_ACPI_STATUS (status);
250 }
251
252
253 /*******************************************************************************
254  *
255  * FUNCTION:    acpi_enable_gpe
256  *
257  * PARAMETERS:  gpe_device      - Parent GPE Device
258  *              gpe_number      - GPE level within the GPE block
259  *              Flags           - Just enable, or also wake enable?
260  *                                Called from ISR or not
261  *
262  * RETURN:      Status
263  *
264  * DESCRIPTION: Enable an ACPI event (general purpose)
265  *
266  ******************************************************************************/
267
268 acpi_status
269 acpi_enable_gpe (
270         acpi_handle                     gpe_device,
271         u32                             gpe_number,
272         u32                             flags)
273 {
274         acpi_status                     status = AE_OK;
275         struct acpi_gpe_event_info      *gpe_event_info;
276
277
278         ACPI_FUNCTION_TRACE ("acpi_enable_gpe");
279
280
281         /* Use semaphore lock if not executing at interrupt level */
282
283         if (flags & ACPI_NOT_ISR) {
284                 status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
285                 if (ACPI_FAILURE (status)) {
286                         return_ACPI_STATUS (status);
287                 }
288         }
289
290         /* Ensure that we have a valid GPE number */
291
292         gpe_event_info = acpi_ev_get_gpe_event_info (gpe_device, gpe_number);
293         if (!gpe_event_info) {
294                 status = AE_BAD_PARAMETER;
295                 goto unlock_and_exit;
296         }
297
298         /* Perform the enable */
299
300         status = acpi_ev_enable_gpe (gpe_event_info, TRUE);
301
302 unlock_and_exit:
303         if (flags & ACPI_NOT_ISR) {
304                 (void) acpi_ut_release_mutex (ACPI_MTX_EVENTS);
305         }
306         return_ACPI_STATUS (status);
307 }
308
309
310 /*******************************************************************************
311  *
312  * FUNCTION:    acpi_disable_gpe
313  *
314  * PARAMETERS:  gpe_device      - Parent GPE Device
315  *              gpe_number      - GPE level within the GPE block
316  *              Flags           - Just disable, or also wake disable?
317  *                                Called from ISR or not
318  *
319  * RETURN:      Status
320  *
321  * DESCRIPTION: Disable an ACPI event (general purpose)
322  *
323  ******************************************************************************/
324
325 acpi_status
326 acpi_disable_gpe (
327         acpi_handle                     gpe_device,
328         u32                             gpe_number,
329         u32                             flags)
330 {
331         acpi_status                     status = AE_OK;
332         struct acpi_gpe_event_info      *gpe_event_info;
333
334
335         ACPI_FUNCTION_TRACE ("acpi_disable_gpe");
336
337
338         /* Use semaphore lock if not executing at interrupt level */
339
340         if (flags & ACPI_NOT_ISR) {
341                 status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
342                 if (ACPI_FAILURE (status)) {
343                         return_ACPI_STATUS (status);
344                 }
345         }
346
347         /* Ensure that we have a valid GPE number */
348
349         gpe_event_info = acpi_ev_get_gpe_event_info (gpe_device, gpe_number);
350         if (!gpe_event_info) {
351                 status = AE_BAD_PARAMETER;
352                 goto unlock_and_exit;
353         }
354
355         status = acpi_ev_disable_gpe (gpe_event_info);
356
357 unlock_and_exit:
358         if (flags & ACPI_NOT_ISR) {
359                 (void) acpi_ut_release_mutex (ACPI_MTX_EVENTS);
360         }
361         return_ACPI_STATUS (status);
362 }
363
364
365 /*******************************************************************************
366  *
367  * FUNCTION:    acpi_disable_event
368  *
369  * PARAMETERS:  Event           - The fixed eventto be enabled
370  *              Flags           - Reserved
371  *
372  * RETURN:      Status
373  *
374  * DESCRIPTION: Disable an ACPI event (fixed)
375  *
376  ******************************************************************************/
377
378 acpi_status
379 acpi_disable_event (
380         u32                             event,
381         u32                             flags)
382 {
383         acpi_status                     status = AE_OK;
384         u32                             value;
385
386
387         ACPI_FUNCTION_TRACE ("acpi_disable_event");
388
389
390         /* Decode the Fixed Event */
391
392         if (event > ACPI_EVENT_MAX) {
393                 return_ACPI_STATUS (AE_BAD_PARAMETER);
394         }
395
396         /*
397          * Disable the requested fixed event (by writing a zero to the
398          * enable register bit)
399          */
400         status = acpi_set_register (acpi_gbl_fixed_event_info[event].enable_register_id,
401                          0, ACPI_MTX_LOCK);
402         if (ACPI_FAILURE (status)) {
403                 return_ACPI_STATUS (status);
404         }
405
406         status = acpi_get_register (acpi_gbl_fixed_event_info[event].enable_register_id,
407                          &value, ACPI_MTX_LOCK);
408         if (ACPI_FAILURE (status)) {
409                 return_ACPI_STATUS (status);
410         }
411
412         if (value != 0) {
413                 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
414                         "Could not disable %s events\n", acpi_ut_get_event_name (event)));
415                 return_ACPI_STATUS (AE_NO_HARDWARE_RESPONSE);
416         }
417
418         return_ACPI_STATUS (status);
419 }
420
421
422 /*******************************************************************************
423  *
424  * FUNCTION:    acpi_clear_event
425  *
426  * PARAMETERS:  Event           - The fixed event to be cleared
427  *
428  * RETURN:      Status
429  *
430  * DESCRIPTION: Clear an ACPI event (fixed)
431  *
432  ******************************************************************************/
433
434 acpi_status
435 acpi_clear_event (
436         u32                             event)
437 {
438         acpi_status                     status = AE_OK;
439
440
441         ACPI_FUNCTION_TRACE ("acpi_clear_event");
442
443
444         /* Decode the Fixed Event */
445
446         if (event > ACPI_EVENT_MAX) {
447                 return_ACPI_STATUS (AE_BAD_PARAMETER);
448         }
449
450         /*
451          * Clear the requested fixed event (By writing a one to the
452          * status register bit)
453          */
454         status = acpi_set_register (acpi_gbl_fixed_event_info[event].status_register_id,
455                         1, ACPI_MTX_LOCK);
456
457         return_ACPI_STATUS (status);
458 }
459
460
461 /*******************************************************************************
462  *
463  * FUNCTION:    acpi_clear_gpe
464  *
465  * PARAMETERS:  gpe_device      - Parent GPE Device
466  *              gpe_number      - GPE level within the GPE block
467  *              Flags           - Called from an ISR or not
468  *
469  * RETURN:      Status
470  *
471  * DESCRIPTION: Clear an ACPI event (general purpose)
472  *
473  ******************************************************************************/
474
475 acpi_status
476 acpi_clear_gpe (
477         acpi_handle                     gpe_device,
478         u32                             gpe_number,
479         u32                             flags)
480 {
481         acpi_status                     status = AE_OK;
482         struct acpi_gpe_event_info      *gpe_event_info;
483
484
485         ACPI_FUNCTION_TRACE ("acpi_clear_gpe");
486
487
488         /* Use semaphore lock if not executing at interrupt level */
489
490         if (flags & ACPI_NOT_ISR) {
491                 status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
492                 if (ACPI_FAILURE (status)) {
493                         return_ACPI_STATUS (status);
494                 }
495         }
496
497         /* Ensure that we have a valid GPE number */
498
499         gpe_event_info = acpi_ev_get_gpe_event_info (gpe_device, gpe_number);
500         if (!gpe_event_info) {
501                 status = AE_BAD_PARAMETER;
502                 goto unlock_and_exit;
503         }
504
505         status = acpi_hw_clear_gpe (gpe_event_info);
506
507 unlock_and_exit:
508         if (flags & ACPI_NOT_ISR) {
509                 (void) acpi_ut_release_mutex (ACPI_MTX_EVENTS);
510         }
511         return_ACPI_STATUS (status);
512 }
513
514
515 /*******************************************************************************
516  *
517  * FUNCTION:    acpi_get_event_status
518  *
519  * PARAMETERS:  Event           - The fixed event
520  *              Event Status    - Where the current status of the event will
521  *                                be returned
522  *
523  * RETURN:      Status
524  *
525  * DESCRIPTION: Obtains and returns the current status of the event
526  *
527  ******************************************************************************/
528
529 acpi_status
530 acpi_get_event_status (
531         u32                             event,
532         acpi_event_status               *event_status)
533 {
534         acpi_status                     status = AE_OK;
535
536
537         ACPI_FUNCTION_TRACE ("acpi_get_event_status");
538
539
540         if (!event_status) {
541                 return_ACPI_STATUS (AE_BAD_PARAMETER);
542         }
543
544         /* Decode the Fixed Event */
545
546         if (event > ACPI_EVENT_MAX) {
547                 return_ACPI_STATUS (AE_BAD_PARAMETER);
548         }
549
550         /* Get the status of the requested fixed event */
551
552         status = acpi_get_register (acpi_gbl_fixed_event_info[event].status_register_id,
553                           event_status, ACPI_MTX_LOCK);
554
555         return_ACPI_STATUS (status);
556 }
557
558
559 /*******************************************************************************
560  *
561  * FUNCTION:    acpi_get_gpe_status
562  *
563  * PARAMETERS:  gpe_device      - Parent GPE Device
564  *              gpe_number      - GPE level within the GPE block
565  *              Flags           - Called from an ISR or not
566  *              Event Status    - Where the current status of the event will
567  *                                be returned
568  *
569  * RETURN:      Status
570  *
571  * DESCRIPTION: Get status of an event (general purpose)
572  *
573  ******************************************************************************/
574
575 acpi_status
576 acpi_get_gpe_status (
577         acpi_handle                     gpe_device,
578         u32                             gpe_number,
579         u32                             flags,
580         acpi_event_status               *event_status)
581 {
582         acpi_status                     status = AE_OK;
583         struct acpi_gpe_event_info      *gpe_event_info;
584
585
586         ACPI_FUNCTION_TRACE ("acpi_get_gpe_status");
587
588
589         /* Use semaphore lock if not executing at interrupt level */
590
591         if (flags & ACPI_NOT_ISR) {
592                 status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
593                 if (ACPI_FAILURE (status)) {
594                         return_ACPI_STATUS (status);
595                 }
596         }
597
598         /* Ensure that we have a valid GPE number */
599
600         gpe_event_info = acpi_ev_get_gpe_event_info (gpe_device, gpe_number);
601         if (!gpe_event_info) {
602                 status = AE_BAD_PARAMETER;
603                 goto unlock_and_exit;
604         }
605
606         /* Obtain status on the requested GPE number */
607
608         status = acpi_hw_get_gpe_status (gpe_event_info, event_status);
609
610 unlock_and_exit:
611         if (flags & ACPI_NOT_ISR) {
612                 (void) acpi_ut_release_mutex (ACPI_MTX_EVENTS);
613         }
614         return_ACPI_STATUS (status);
615 }
616
617
618 /*******************************************************************************
619  *
620  * FUNCTION:    acpi_install_gpe_block
621  *
622  * PARAMETERS:  gpe_device          - Handle to the parent GPE Block Device
623  *              gpe_block_address   - Address and space_iD
624  *              register_count      - Number of GPE register pairs in the block
625  *              interrupt_level     - H/W interrupt for the block
626  *
627  * RETURN:      Status
628  *
629  * DESCRIPTION: Create and Install a block of GPE registers
630  *
631  ******************************************************************************/
632
633 acpi_status
634 acpi_install_gpe_block (
635         acpi_handle                     gpe_device,
636         struct acpi_generic_address     *gpe_block_address,
637         u32                             register_count,
638         u32                             interrupt_level)
639 {
640         acpi_status                     status;
641         union acpi_operand_object       *obj_desc;
642         struct acpi_namespace_node      *node;
643         struct acpi_gpe_block_info      *gpe_block;
644
645
646         ACPI_FUNCTION_TRACE ("acpi_install_gpe_block");
647
648
649         if ((!gpe_device)      ||
650                 (!gpe_block_address) ||
651                 (!register_count)) {
652                 return_ACPI_STATUS (AE_BAD_PARAMETER);
653         }
654
655         status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
656         if (ACPI_FAILURE (status)) {
657                 return (status);
658         }
659
660         node = acpi_ns_map_handle_to_node (gpe_device);
661         if (!node) {
662                 status = AE_BAD_PARAMETER;
663                 goto unlock_and_exit;
664         }
665
666         /*
667          * For user-installed GPE Block Devices, the gpe_block_base_number
668          * is always zero
669          */
670         status = acpi_ev_create_gpe_block (node, gpe_block_address, register_count,
671                           0, interrupt_level, &gpe_block);
672         if (ACPI_FAILURE (status)) {
673                 goto unlock_and_exit;
674         }
675
676         /* Get the device_object attached to the node */
677
678         obj_desc = acpi_ns_get_attached_object (node);
679         if (!obj_desc) {
680                 /* No object, create a new one */
681
682                 obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_DEVICE);
683                 if (!obj_desc) {
684                         status = AE_NO_MEMORY;
685                         goto unlock_and_exit;
686                 }
687
688                 status = acpi_ns_attach_object (node, obj_desc, ACPI_TYPE_DEVICE);
689
690                 /* Remove local reference to the object */
691
692                 acpi_ut_remove_reference (obj_desc);
693
694                 if (ACPI_FAILURE (status)) {
695                         goto unlock_and_exit;
696                 }
697         }
698
699         /* Install the GPE block in the device_object */
700
701         obj_desc->device.gpe_block = gpe_block;
702
703
704 unlock_and_exit:
705         (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
706         return_ACPI_STATUS (status);
707 }
708
709
710 /*******************************************************************************
711  *
712  * FUNCTION:    acpi_remove_gpe_block
713  *
714  * PARAMETERS:  gpe_device          - Handle to the parent GPE Block Device
715  *
716  * RETURN:      Status
717  *
718  * DESCRIPTION: Remove a previously installed block of GPE registers
719  *
720  ******************************************************************************/
721
722 acpi_status
723 acpi_remove_gpe_block (
724         acpi_handle                     gpe_device)
725 {
726         union acpi_operand_object       *obj_desc;
727         acpi_status                     status;
728         struct acpi_namespace_node      *node;
729
730
731         ACPI_FUNCTION_TRACE ("acpi_remove_gpe_block");
732
733
734         if (!gpe_device) {
735                 return_ACPI_STATUS (AE_BAD_PARAMETER);
736         }
737
738         status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
739         if (ACPI_FAILURE (status)) {
740                 return (status);
741         }
742
743         node = acpi_ns_map_handle_to_node (gpe_device);
744         if (!node) {
745                 status = AE_BAD_PARAMETER;
746                 goto unlock_and_exit;
747         }
748
749         /* Get the device_object attached to the node */
750
751         obj_desc = acpi_ns_get_attached_object (node);
752         if (!obj_desc ||
753                 !obj_desc->device.gpe_block) {
754                 return_ACPI_STATUS (AE_NULL_OBJECT);
755         }
756
757         /* Delete the GPE block (but not the device_object) */
758
759         status = acpi_ev_delete_gpe_block (obj_desc->device.gpe_block);
760         if (ACPI_SUCCESS (status)) {
761                 obj_desc->device.gpe_block = NULL;
762         }
763
764 unlock_and_exit:
765         (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
766         return_ACPI_STATUS (status);
767 }
768