]> git.karo-electronics.de Git - mv-sheeva.git/blob - drivers/acpi/acpica/evxfevnt.c
ACPICA: simplify SCI_EN workaround
[mv-sheeva.git] / drivers / acpi / acpica / evxfevnt.c
1 /******************************************************************************
2  *
3  * Module Name: evxfevnt - External Interfaces, ACPI event disable/enable
4  *
5  *****************************************************************************/
6
7 /*
8  * Copyright (C) 2000 - 2010, 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 #include <acpi/acpi.h>
45 #include "accommon.h"
46 #include "acevents.h"
47 #include "acnamesp.h"
48 #include "actables.h"
49
50 #define _COMPONENT          ACPI_EVENTS
51 ACPI_MODULE_NAME("evxfevnt")
52
53 /* Local prototypes */
54 static acpi_status
55 acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
56                        struct acpi_gpe_block_info *gpe_block, void *context);
57
58 /*******************************************************************************
59  *
60  * FUNCTION:    acpi_enable
61  *
62  * PARAMETERS:  None
63  *
64  * RETURN:      Status
65  *
66  * DESCRIPTION: Transfers the system into ACPI mode.
67  *
68  ******************************************************************************/
69
70 acpi_status acpi_enable(void)
71 {
72         acpi_status status;
73
74         ACPI_FUNCTION_TRACE(acpi_enable);
75
76         /* ACPI tables must be present */
77
78         if (!acpi_tb_tables_loaded()) {
79                 return_ACPI_STATUS(AE_NO_ACPI_TABLES);
80         }
81
82         /* Check current mode */
83
84         if (acpi_hw_get_mode() == ACPI_SYS_MODE_ACPI) {
85                 ACPI_DEBUG_PRINT((ACPI_DB_INIT,
86                                   "System is already in ACPI mode\n"));
87                 return_ACPI_STATUS(AE_OK);
88         }
89
90         /* Transition to ACPI mode */
91
92         status = acpi_hw_set_mode(ACPI_SYS_MODE_ACPI);
93         if (ACPI_FAILURE(status)) {
94                 ACPI_ERROR((AE_INFO,
95                             "Could not transition to ACPI mode"));
96                 return_ACPI_STATUS(status);
97         }
98
99         /* Sanity check that transition succeeded */
100
101         if (acpi_hw_get_mode() != ACPI_SYS_MODE_ACPI) {
102                 ACPI_ERROR((AE_INFO,
103                             "Hardware did not enter ACPI mode"));
104                 return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE);
105         }
106
107         ACPI_DEBUG_PRINT((ACPI_DB_INIT,
108                           "Transition to ACPI mode successful\n"));
109
110         return_ACPI_STATUS(AE_OK);
111 }
112
113 ACPI_EXPORT_SYMBOL(acpi_enable)
114
115 /*******************************************************************************
116  *
117  * FUNCTION:    acpi_disable
118  *
119  * PARAMETERS:  None
120  *
121  * RETURN:      Status
122  *
123  * DESCRIPTION: Transfers the system into LEGACY (non-ACPI) mode.
124  *
125  ******************************************************************************/
126 acpi_status acpi_disable(void)
127 {
128         acpi_status status = AE_OK;
129
130         ACPI_FUNCTION_TRACE(acpi_disable);
131
132         if (acpi_hw_get_mode() == ACPI_SYS_MODE_LEGACY) {
133                 ACPI_DEBUG_PRINT((ACPI_DB_INIT,
134                                   "System is already in legacy (non-ACPI) mode\n"));
135         } else {
136                 /* Transition to LEGACY mode */
137
138                 status = acpi_hw_set_mode(ACPI_SYS_MODE_LEGACY);
139
140                 if (ACPI_FAILURE(status)) {
141                         ACPI_ERROR((AE_INFO,
142                                     "Could not exit ACPI mode to legacy mode"));
143                         return_ACPI_STATUS(status);
144                 }
145
146                 ACPI_DEBUG_PRINT((ACPI_DB_INIT, "ACPI mode disabled\n"));
147         }
148
149         return_ACPI_STATUS(status);
150 }
151
152 ACPI_EXPORT_SYMBOL(acpi_disable)
153
154 /*******************************************************************************
155  *
156  * FUNCTION:    acpi_enable_event
157  *
158  * PARAMETERS:  Event           - The fixed eventto be enabled
159  *              Flags           - Reserved
160  *
161  * RETURN:      Status
162  *
163  * DESCRIPTION: Enable an ACPI event (fixed)
164  *
165  ******************************************************************************/
166 acpi_status acpi_enable_event(u32 event, u32 flags)
167 {
168         acpi_status status = AE_OK;
169         u32 value;
170
171         ACPI_FUNCTION_TRACE(acpi_enable_event);
172
173         /* Decode the Fixed Event */
174
175         if (event > ACPI_EVENT_MAX) {
176                 return_ACPI_STATUS(AE_BAD_PARAMETER);
177         }
178
179         /*
180          * Enable the requested fixed event (by writing a one to the enable
181          * register bit)
182          */
183         status =
184             acpi_write_bit_register(acpi_gbl_fixed_event_info[event].
185                                     enable_register_id, ACPI_ENABLE_EVENT);
186         if (ACPI_FAILURE(status)) {
187                 return_ACPI_STATUS(status);
188         }
189
190         /* Make sure that the hardware responded */
191
192         status =
193             acpi_read_bit_register(acpi_gbl_fixed_event_info[event].
194                                    enable_register_id, &value);
195         if (ACPI_FAILURE(status)) {
196                 return_ACPI_STATUS(status);
197         }
198
199         if (value != 1) {
200                 ACPI_ERROR((AE_INFO,
201                             "Could not enable %s event",
202                             acpi_ut_get_event_name(event)));
203                 return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE);
204         }
205
206         return_ACPI_STATUS(status);
207 }
208
209 ACPI_EXPORT_SYMBOL(acpi_enable_event)
210
211 /*******************************************************************************
212  *
213  * FUNCTION:    acpi_set_gpe
214  *
215  * PARAMETERS:  gpe_device      - Parent GPE Device
216  *              gpe_number      - GPE level within the GPE block
217  *              action          - Enable or disable
218  *                                Called from ISR or not
219  *
220  * RETURN:      Status
221  *
222  * DESCRIPTION: Enable or disable an ACPI event (general purpose)
223  *
224  ******************************************************************************/
225 acpi_status acpi_set_gpe(acpi_handle gpe_device, u32 gpe_number, u8 action)
226 {
227         acpi_status status = AE_OK;
228         acpi_cpu_flags flags;
229         struct acpi_gpe_event_info *gpe_event_info;
230
231         ACPI_FUNCTION_TRACE(acpi_set_gpe);
232
233         flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
234
235         /* Ensure that we have a valid GPE number */
236
237         gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
238         if (!gpe_event_info) {
239                 status = AE_BAD_PARAMETER;
240                 goto unlock_and_exit;
241         }
242
243         /* Perform the action */
244
245         switch (action) {
246         case ACPI_GPE_ENABLE:
247                 status = acpi_ev_enable_gpe(gpe_event_info);
248                 break;
249
250         case ACPI_GPE_DISABLE:
251                 status = acpi_ev_disable_gpe(gpe_event_info);
252                 break;
253
254         default:
255                 ACPI_ERROR((AE_INFO, "Invalid action\n"));
256                 status = AE_BAD_PARAMETER;
257                 break;
258         }
259
260       unlock_and_exit:
261         acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
262         return_ACPI_STATUS(status);
263 }
264
265 ACPI_EXPORT_SYMBOL(acpi_set_gpe)
266
267 /*******************************************************************************
268  *
269  * FUNCTION:    acpi_enable_gpe
270  *
271  * PARAMETERS:  gpe_device      - Parent GPE Device
272  *              gpe_number      - GPE level within the GPE block
273  *              type            - Purpose the GPE will be used for
274  *
275  * RETURN:      Status
276  *
277  * DESCRIPTION: Take a reference to a GPE and enable it if necessary
278  *
279  ******************************************************************************/
280 acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number, u8 type)
281 {
282         acpi_status status = AE_OK;
283         acpi_cpu_flags flags;
284         struct acpi_gpe_event_info *gpe_event_info;
285
286         ACPI_FUNCTION_TRACE(acpi_enable_gpe);
287
288         if (type & ~ACPI_GPE_TYPE_WAKE_RUN)
289                 return_ACPI_STATUS(AE_BAD_PARAMETER);
290
291         flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
292
293         /* Ensure that we have a valid GPE number */
294
295         gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
296         if (!gpe_event_info) {
297                 status = AE_BAD_PARAMETER;
298                 goto unlock_and_exit;
299         }
300
301         if (type & ACPI_GPE_TYPE_RUNTIME) {
302                 if (++gpe_event_info->runtime_count == 1) {
303                         status = acpi_ev_enable_gpe(gpe_event_info);
304                         if (ACPI_FAILURE(status))
305                                 gpe_event_info->runtime_count--;
306                 }
307         }
308
309         if (type & ACPI_GPE_TYPE_WAKE) {
310                 if (!(gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) {
311                         status = AE_BAD_PARAMETER;
312                         goto unlock_and_exit;
313                 }
314
315                 /*
316                  * Wake-up GPEs are only enabled right prior to putting the
317                  * system into a sleep state.
318                  */
319                 if (++gpe_event_info->wakeup_count == 1)
320                         acpi_ev_update_gpe_enable_masks(gpe_event_info);
321         }
322
323 unlock_and_exit:
324         acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
325         return_ACPI_STATUS(status);
326 }
327 ACPI_EXPORT_SYMBOL(acpi_enable_gpe)
328
329 /*******************************************************************************
330  *
331  * FUNCTION:    acpi_disable_gpe
332  *
333  * PARAMETERS:  gpe_device      - Parent GPE Device
334  *              gpe_number      - GPE level within the GPE block
335  *              type            - Purpose the GPE won't be used for any more
336  *
337  * RETURN:      Status
338  *
339  * DESCRIPTION: Release a reference to a GPE and disable it if necessary
340  *
341  ******************************************************************************/
342 acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number, u8 type)
343 {
344         acpi_status status = AE_OK;
345         acpi_cpu_flags flags;
346         struct acpi_gpe_event_info *gpe_event_info;
347
348         ACPI_FUNCTION_TRACE(acpi_disable_gpe);
349
350         if (type & ~ACPI_GPE_TYPE_WAKE_RUN)
351                 return_ACPI_STATUS(AE_BAD_PARAMETER);
352
353         flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
354         /* Ensure that we have a valid GPE number */
355
356         gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
357         if (!gpe_event_info) {
358                 status = AE_BAD_PARAMETER;
359                 goto unlock_and_exit;
360         }
361
362         if ((type & ACPI_GPE_TYPE_RUNTIME) && gpe_event_info->runtime_count) {
363                 if (--gpe_event_info->runtime_count == 0)
364                         status = acpi_ev_disable_gpe(gpe_event_info);
365         }
366
367         if ((type & ACPI_GPE_TYPE_WAKE) && gpe_event_info->wakeup_count) {
368                 /*
369                  * Wake-up GPEs are not enabled after leaving system sleep
370                  * states, so we don't need to disable them here.
371                  */
372                 if (--gpe_event_info->wakeup_count == 0)
373                         acpi_ev_update_gpe_enable_masks(gpe_event_info);
374         }
375
376 unlock_and_exit:
377         acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
378         return_ACPI_STATUS(status);
379 }
380 ACPI_EXPORT_SYMBOL(acpi_disable_gpe)
381
382 /*******************************************************************************
383  *
384  * FUNCTION:    acpi_disable_event
385  *
386  * PARAMETERS:  Event           - The fixed eventto be enabled
387  *              Flags           - Reserved
388  *
389  * RETURN:      Status
390  *
391  * DESCRIPTION: Disable an ACPI event (fixed)
392  *
393  ******************************************************************************/
394 acpi_status acpi_disable_event(u32 event, u32 flags)
395 {
396         acpi_status status = AE_OK;
397         u32 value;
398
399         ACPI_FUNCTION_TRACE(acpi_disable_event);
400
401         /* Decode the Fixed Event */
402
403         if (event > ACPI_EVENT_MAX) {
404                 return_ACPI_STATUS(AE_BAD_PARAMETER);
405         }
406
407         /*
408          * Disable the requested fixed event (by writing a zero to the enable
409          * register bit)
410          */
411         status =
412             acpi_write_bit_register(acpi_gbl_fixed_event_info[event].
413                                     enable_register_id, ACPI_DISABLE_EVENT);
414         if (ACPI_FAILURE(status)) {
415                 return_ACPI_STATUS(status);
416         }
417
418         status =
419             acpi_read_bit_register(acpi_gbl_fixed_event_info[event].
420                                    enable_register_id, &value);
421         if (ACPI_FAILURE(status)) {
422                 return_ACPI_STATUS(status);
423         }
424
425         if (value != 0) {
426                 ACPI_ERROR((AE_INFO,
427                             "Could not disable %s events",
428                             acpi_ut_get_event_name(event)));
429                 return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE);
430         }
431
432         return_ACPI_STATUS(status);
433 }
434
435 ACPI_EXPORT_SYMBOL(acpi_disable_event)
436
437 /*******************************************************************************
438  *
439  * FUNCTION:    acpi_clear_event
440  *
441  * PARAMETERS:  Event           - The fixed event to be cleared
442  *
443  * RETURN:      Status
444  *
445  * DESCRIPTION: Clear an ACPI event (fixed)
446  *
447  ******************************************************************************/
448 acpi_status acpi_clear_event(u32 event)
449 {
450         acpi_status status = AE_OK;
451
452         ACPI_FUNCTION_TRACE(acpi_clear_event);
453
454         /* Decode the Fixed Event */
455
456         if (event > ACPI_EVENT_MAX) {
457                 return_ACPI_STATUS(AE_BAD_PARAMETER);
458         }
459
460         /*
461          * Clear the requested fixed event (By writing a one to the status
462          * register bit)
463          */
464         status =
465             acpi_write_bit_register(acpi_gbl_fixed_event_info[event].
466                                     status_register_id, ACPI_CLEAR_STATUS);
467
468         return_ACPI_STATUS(status);
469 }
470
471 ACPI_EXPORT_SYMBOL(acpi_clear_event)
472
473 /*******************************************************************************
474  *
475  * FUNCTION:    acpi_clear_gpe
476  *
477  * PARAMETERS:  gpe_device      - Parent GPE Device
478  *              gpe_number      - GPE level within the GPE block
479  *              Flags           - Called from an ISR or not
480  *
481  * RETURN:      Status
482  *
483  * DESCRIPTION: Clear an ACPI event (general purpose)
484  *
485  ******************************************************************************/
486 acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags)
487 {
488         acpi_status status = AE_OK;
489         struct acpi_gpe_event_info *gpe_event_info;
490
491         ACPI_FUNCTION_TRACE(acpi_clear_gpe);
492
493         /* Use semaphore lock if not executing at interrupt level */
494
495         if (flags & ACPI_NOT_ISR) {
496                 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
497                 if (ACPI_FAILURE(status)) {
498                         return_ACPI_STATUS(status);
499                 }
500         }
501
502         /* Ensure that we have a valid GPE number */
503
504         gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
505         if (!gpe_event_info) {
506                 status = AE_BAD_PARAMETER;
507                 goto unlock_and_exit;
508         }
509
510         status = acpi_hw_clear_gpe(gpe_event_info);
511
512       unlock_and_exit:
513         if (flags & ACPI_NOT_ISR) {
514                 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
515         }
516         return_ACPI_STATUS(status);
517 }
518
519 ACPI_EXPORT_SYMBOL(acpi_clear_gpe)
520 /*******************************************************************************
521  *
522  * FUNCTION:    acpi_get_event_status
523  *
524  * PARAMETERS:  Event           - The fixed event
525  *              event_status    - Where the current status of the event will
526  *                                be returned
527  *
528  * RETURN:      Status
529  *
530  * DESCRIPTION: Obtains and returns the current status of the event
531  *
532  ******************************************************************************/
533 acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status)
534 {
535         acpi_status status = AE_OK;
536         u32 value;
537
538         ACPI_FUNCTION_TRACE(acpi_get_event_status);
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 =
553             acpi_read_bit_register(acpi_gbl_fixed_event_info[event].
554                               enable_register_id, &value);
555         if (ACPI_FAILURE(status))
556                 return_ACPI_STATUS(status);
557
558         *event_status = value;
559
560         status =
561             acpi_read_bit_register(acpi_gbl_fixed_event_info[event].
562                               status_register_id, &value);
563         if (ACPI_FAILURE(status))
564                 return_ACPI_STATUS(status);
565
566         if (value)
567                 *event_status |= ACPI_EVENT_FLAG_SET;
568
569         if (acpi_gbl_fixed_event_handlers[event].handler)
570                 *event_status |= ACPI_EVENT_FLAG_HANDLE;
571
572         return_ACPI_STATUS(status);
573 }
574
575 ACPI_EXPORT_SYMBOL(acpi_get_event_status)
576
577 /*******************************************************************************
578  *
579  * FUNCTION:    acpi_get_gpe_status
580  *
581  * PARAMETERS:  gpe_device      - Parent GPE Device
582  *              gpe_number      - GPE level within the GPE block
583  *              Flags           - Called from an ISR or not
584  *              event_status    - Where the current status of the event will
585  *                                be returned
586  *
587  * RETURN:      Status
588  *
589  * DESCRIPTION: Get status of an event (general purpose)
590  *
591  ******************************************************************************/
592 acpi_status
593 acpi_get_gpe_status(acpi_handle gpe_device,
594                     u32 gpe_number, u32 flags, acpi_event_status * event_status)
595 {
596         acpi_status status = AE_OK;
597         struct acpi_gpe_event_info *gpe_event_info;
598
599         ACPI_FUNCTION_TRACE(acpi_get_gpe_status);
600
601         /* Use semaphore lock if not executing at interrupt level */
602
603         if (flags & ACPI_NOT_ISR) {
604                 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
605                 if (ACPI_FAILURE(status)) {
606                         return_ACPI_STATUS(status);
607                 }
608         }
609
610         /* Ensure that we have a valid GPE number */
611
612         gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
613         if (!gpe_event_info) {
614                 status = AE_BAD_PARAMETER;
615                 goto unlock_and_exit;
616         }
617
618         /* Obtain status on the requested GPE number */
619
620         status = acpi_hw_get_gpe_status(gpe_event_info, event_status);
621
622         if (gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK)
623                 *event_status |= ACPI_EVENT_FLAG_HANDLE;
624
625       unlock_and_exit:
626         if (flags & ACPI_NOT_ISR) {
627                 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
628         }
629         return_ACPI_STATUS(status);
630 }
631
632 ACPI_EXPORT_SYMBOL(acpi_get_gpe_status)
633 /*******************************************************************************
634  *
635  * FUNCTION:    acpi_install_gpe_block
636  *
637  * PARAMETERS:  gpe_device          - Handle to the parent GPE Block Device
638  *              gpe_block_address   - Address and space_iD
639  *              register_count      - Number of GPE register pairs in the block
640  *              interrupt_number    - H/W interrupt for the block
641  *
642  * RETURN:      Status
643  *
644  * DESCRIPTION: Create and Install a block of GPE registers
645  *
646  ******************************************************************************/
647 acpi_status
648 acpi_install_gpe_block(acpi_handle gpe_device,
649                        struct acpi_generic_address *gpe_block_address,
650                        u32 register_count, u32 interrupt_number)
651 {
652         acpi_status status;
653         union acpi_operand_object *obj_desc;
654         struct acpi_namespace_node *node;
655         struct acpi_gpe_block_info *gpe_block;
656
657         ACPI_FUNCTION_TRACE(acpi_install_gpe_block);
658
659         if ((!gpe_device) || (!gpe_block_address) || (!register_count)) {
660                 return_ACPI_STATUS(AE_BAD_PARAMETER);
661         }
662
663         status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
664         if (ACPI_FAILURE(status)) {
665                 return (status);
666         }
667
668         node = acpi_ns_validate_handle(gpe_device);
669         if (!node) {
670                 status = AE_BAD_PARAMETER;
671                 goto unlock_and_exit;
672         }
673
674         /*
675          * For user-installed GPE Block Devices, the gpe_block_base_number
676          * is always zero
677          */
678         status =
679             acpi_ev_create_gpe_block(node, gpe_block_address, register_count, 0,
680                                      interrupt_number, &gpe_block);
681         if (ACPI_FAILURE(status)) {
682                 goto unlock_and_exit;
683         }
684
685         /* Run the _PRW methods and enable the GPEs */
686
687         status = acpi_ev_initialize_gpe_block(node, gpe_block);
688         if (ACPI_FAILURE(status)) {
689                 goto unlock_and_exit;
690         }
691
692         /* Get the device_object attached to the node */
693
694         obj_desc = acpi_ns_get_attached_object(node);
695         if (!obj_desc) {
696
697                 /* No object, create a new one */
698
699                 obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_DEVICE);
700                 if (!obj_desc) {
701                         status = AE_NO_MEMORY;
702                         goto unlock_and_exit;
703                 }
704
705                 status =
706                     acpi_ns_attach_object(node, obj_desc, ACPI_TYPE_DEVICE);
707
708                 /* Remove local reference to the object */
709
710                 acpi_ut_remove_reference(obj_desc);
711
712                 if (ACPI_FAILURE(status)) {
713                         goto unlock_and_exit;
714                 }
715         }
716
717         /* Install the GPE block in the device_object */
718
719         obj_desc->device.gpe_block = gpe_block;
720
721       unlock_and_exit:
722         (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
723         return_ACPI_STATUS(status);
724 }
725
726 ACPI_EXPORT_SYMBOL(acpi_install_gpe_block)
727
728 /*******************************************************************************
729  *
730  * FUNCTION:    acpi_remove_gpe_block
731  *
732  * PARAMETERS:  gpe_device          - Handle to the parent GPE Block Device
733  *
734  * RETURN:      Status
735  *
736  * DESCRIPTION: Remove a previously installed block of GPE registers
737  *
738  ******************************************************************************/
739 acpi_status acpi_remove_gpe_block(acpi_handle gpe_device)
740 {
741         union acpi_operand_object *obj_desc;
742         acpi_status status;
743         struct acpi_namespace_node *node;
744
745         ACPI_FUNCTION_TRACE(acpi_remove_gpe_block);
746
747         if (!gpe_device) {
748                 return_ACPI_STATUS(AE_BAD_PARAMETER);
749         }
750
751         status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
752         if (ACPI_FAILURE(status)) {
753                 return (status);
754         }
755
756         node = acpi_ns_validate_handle(gpe_device);
757         if (!node) {
758                 status = AE_BAD_PARAMETER;
759                 goto unlock_and_exit;
760         }
761
762         /* Get the device_object attached to the node */
763
764         obj_desc = acpi_ns_get_attached_object(node);
765         if (!obj_desc || !obj_desc->device.gpe_block) {
766                 return_ACPI_STATUS(AE_NULL_OBJECT);
767         }
768
769         /* Delete the GPE block (but not the device_object) */
770
771         status = acpi_ev_delete_gpe_block(obj_desc->device.gpe_block);
772         if (ACPI_SUCCESS(status)) {
773                 obj_desc->device.gpe_block = NULL;
774         }
775
776       unlock_and_exit:
777         (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
778         return_ACPI_STATUS(status);
779 }
780
781 ACPI_EXPORT_SYMBOL(acpi_remove_gpe_block)
782
783 /*******************************************************************************
784  *
785  * FUNCTION:    acpi_get_gpe_device
786  *
787  * PARAMETERS:  Index               - System GPE index (0-current_gpe_count)
788  *              gpe_device          - Where the parent GPE Device is returned
789  *
790  * RETURN:      Status
791  *
792  * DESCRIPTION: Obtain the GPE device associated with the input index. A NULL
793  *              gpe device indicates that the gpe number is contained in one of
794  *              the FADT-defined gpe blocks. Otherwise, the GPE block device.
795  *
796  ******************************************************************************/
797 acpi_status
798 acpi_get_gpe_device(u32 index, acpi_handle *gpe_device)
799 {
800         struct acpi_gpe_device_info info;
801         acpi_status status;
802
803         ACPI_FUNCTION_TRACE(acpi_get_gpe_device);
804
805         if (!gpe_device) {
806                 return_ACPI_STATUS(AE_BAD_PARAMETER);
807         }
808
809         if (index >= acpi_current_gpe_count) {
810                 return_ACPI_STATUS(AE_NOT_EXIST);
811         }
812
813         /* Setup and walk the GPE list */
814
815         info.index = index;
816         info.status = AE_NOT_EXIST;
817         info.gpe_device = NULL;
818         info.next_block_base_index = 0;
819
820         status = acpi_ev_walk_gpe_list(acpi_ev_get_gpe_device, &info);
821         if (ACPI_FAILURE(status)) {
822                 return_ACPI_STATUS(status);
823         }
824
825         *gpe_device = info.gpe_device;
826         return_ACPI_STATUS(info.status);
827 }
828
829 ACPI_EXPORT_SYMBOL(acpi_get_gpe_device)
830
831 /*******************************************************************************
832  *
833  * FUNCTION:    acpi_ev_get_gpe_device
834  *
835  * PARAMETERS:  GPE_WALK_CALLBACK
836  *
837  * RETURN:      Status
838  *
839  * DESCRIPTION: Matches the input GPE index (0-current_gpe_count) with a GPE
840  *              block device. NULL if the GPE is one of the FADT-defined GPEs.
841  *
842  ******************************************************************************/
843 static acpi_status
844 acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
845                        struct acpi_gpe_block_info *gpe_block, void *context)
846 {
847         struct acpi_gpe_device_info *info = context;
848
849         /* Increment Index by the number of GPEs in this block */
850
851         info->next_block_base_index +=
852             (gpe_block->register_count * ACPI_GPE_REGISTER_WIDTH);
853
854         if (info->index < info->next_block_base_index) {
855                 /*
856                  * The GPE index is within this block, get the node. Leave the node
857                  * NULL for the FADT-defined GPEs
858                  */
859                 if ((gpe_block->node)->type == ACPI_TYPE_DEVICE) {
860                         info->gpe_device = gpe_block->node;
861                 }
862
863                 info->status = AE_OK;
864                 return (AE_CTRL_END);
865         }
866
867         return (AE_OK);
868 }
869
870 /******************************************************************************
871  *
872  * FUNCTION:    acpi_disable_all_gpes
873  *
874  * PARAMETERS:  None
875  *
876  * RETURN:      Status
877  *
878  * DESCRIPTION: Disable and clear all GPEs in all GPE blocks
879  *
880  ******************************************************************************/
881
882 acpi_status acpi_disable_all_gpes(void)
883 {
884         acpi_status status;
885
886         ACPI_FUNCTION_TRACE(acpi_disable_all_gpes);
887
888         status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
889         if (ACPI_FAILURE(status)) {
890                 return_ACPI_STATUS(status);
891         }
892
893         status = acpi_hw_disable_all_gpes();
894         (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
895
896         return_ACPI_STATUS(status);
897 }
898
899 /******************************************************************************
900  *
901  * FUNCTION:    acpi_enable_all_runtime_gpes
902  *
903  * PARAMETERS:  None
904  *
905  * RETURN:      Status
906  *
907  * DESCRIPTION: Enable all "runtime" GPEs, in all GPE blocks
908  *
909  ******************************************************************************/
910
911 acpi_status acpi_enable_all_runtime_gpes(void)
912 {
913         acpi_status status;
914
915         ACPI_FUNCTION_TRACE(acpi_enable_all_runtime_gpes);
916
917         status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
918         if (ACPI_FAILURE(status)) {
919                 return_ACPI_STATUS(status);
920         }
921
922         status = acpi_hw_enable_all_runtime_gpes();
923         (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
924
925         return_ACPI_STATUS(status);
926 }