Merge branch 'acpica-gpe' into release
[sfrench/cifs-2.6.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         int retry;
74
75         ACPI_FUNCTION_TRACE(acpi_enable);
76
77         /* ACPI tables must be present */
78
79         if (!acpi_tb_tables_loaded()) {
80                 return_ACPI_STATUS(AE_NO_ACPI_TABLES);
81         }
82
83         /* Check current mode */
84
85         if (acpi_hw_get_mode() == ACPI_SYS_MODE_ACPI) {
86                 ACPI_DEBUG_PRINT((ACPI_DB_INIT,
87                                   "System is already in ACPI mode\n"));
88                 return_ACPI_STATUS(AE_OK);
89         }
90
91         /* Transition to ACPI mode */
92
93         status = acpi_hw_set_mode(ACPI_SYS_MODE_ACPI);
94         if (ACPI_FAILURE(status)) {
95                 ACPI_ERROR((AE_INFO,
96                             "Could not transition to ACPI mode"));
97                 return_ACPI_STATUS(status);
98         }
99
100         /* Sanity check that transition succeeded */
101
102         for (retry = 0; retry < 30000; ++retry) {
103                 if (acpi_hw_get_mode() == ACPI_SYS_MODE_ACPI) {
104                         if (retry != 0)
105                                 ACPI_WARNING((AE_INFO,
106                                 "Platform took > %d00 usec to enter ACPI mode", retry));
107                         return_ACPI_STATUS(AE_OK);
108                 }
109                 acpi_os_stall(100);     /* 100 usec */
110         }
111
112         ACPI_ERROR((AE_INFO, "Hardware did not enter ACPI mode"));
113         return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE);
114 }
115
116 ACPI_EXPORT_SYMBOL(acpi_enable)
117
118 /*******************************************************************************
119  *
120  * FUNCTION:    acpi_disable
121  *
122  * PARAMETERS:  None
123  *
124  * RETURN:      Status
125  *
126  * DESCRIPTION: Transfers the system into LEGACY (non-ACPI) mode.
127  *
128  ******************************************************************************/
129 acpi_status acpi_disable(void)
130 {
131         acpi_status status = AE_OK;
132
133         ACPI_FUNCTION_TRACE(acpi_disable);
134
135         if (acpi_hw_get_mode() == ACPI_SYS_MODE_LEGACY) {
136                 ACPI_DEBUG_PRINT((ACPI_DB_INIT,
137                                   "System is already in legacy (non-ACPI) mode\n"));
138         } else {
139                 /* Transition to LEGACY mode */
140
141                 status = acpi_hw_set_mode(ACPI_SYS_MODE_LEGACY);
142
143                 if (ACPI_FAILURE(status)) {
144                         ACPI_ERROR((AE_INFO,
145                                     "Could not exit ACPI mode to legacy mode"));
146                         return_ACPI_STATUS(status);
147                 }
148
149                 ACPI_DEBUG_PRINT((ACPI_DB_INIT, "ACPI mode disabled\n"));
150         }
151
152         return_ACPI_STATUS(status);
153 }
154
155 ACPI_EXPORT_SYMBOL(acpi_disable)
156
157 /*******************************************************************************
158  *
159  * FUNCTION:    acpi_enable_event
160  *
161  * PARAMETERS:  Event           - The fixed eventto be enabled
162  *              Flags           - Reserved
163  *
164  * RETURN:      Status
165  *
166  * DESCRIPTION: Enable an ACPI event (fixed)
167  *
168  ******************************************************************************/
169 acpi_status acpi_enable_event(u32 event, u32 flags)
170 {
171         acpi_status status = AE_OK;
172         u32 value;
173
174         ACPI_FUNCTION_TRACE(acpi_enable_event);
175
176         /* Decode the Fixed Event */
177
178         if (event > ACPI_EVENT_MAX) {
179                 return_ACPI_STATUS(AE_BAD_PARAMETER);
180         }
181
182         /*
183          * Enable the requested fixed event (by writing a one to the enable
184          * register bit)
185          */
186         status =
187             acpi_write_bit_register(acpi_gbl_fixed_event_info[event].
188                                     enable_register_id, ACPI_ENABLE_EVENT);
189         if (ACPI_FAILURE(status)) {
190                 return_ACPI_STATUS(status);
191         }
192
193         /* Make sure that the hardware responded */
194
195         status =
196             acpi_read_bit_register(acpi_gbl_fixed_event_info[event].
197                                    enable_register_id, &value);
198         if (ACPI_FAILURE(status)) {
199                 return_ACPI_STATUS(status);
200         }
201
202         if (value != 1) {
203                 ACPI_ERROR((AE_INFO,
204                             "Could not enable %s event",
205                             acpi_ut_get_event_name(event)));
206                 return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE);
207         }
208
209         return_ACPI_STATUS(status);
210 }
211
212 ACPI_EXPORT_SYMBOL(acpi_enable_event)
213
214 /*******************************************************************************
215  *
216  * FUNCTION:    acpi_gpe_wakeup
217  *
218  * PARAMETERS:  gpe_device      - Parent GPE Device. NULL for GPE0/GPE1
219  *              gpe_number      - GPE level within the GPE block
220  *              Action          - Enable or Disable
221  *
222  * RETURN:      Status
223  *
224  * DESCRIPTION: Set or clear the GPE's wakeup enable mask bit.
225  *
226  ******************************************************************************/
227 acpi_status acpi_gpe_wakeup(acpi_handle gpe_device, u32 gpe_number, u8 action)
228 {
229         acpi_status status = AE_OK;
230         struct acpi_gpe_event_info *gpe_event_info;
231         struct acpi_gpe_register_info *gpe_register_info;
232         acpi_cpu_flags flags;
233         u32 register_bit;
234
235         ACPI_FUNCTION_TRACE(acpi_gpe_wakeup);
236
237         flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
238
239         /* Ensure that we have a valid GPE number */
240
241         gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
242         if (!gpe_event_info || !(gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) {
243                 status = AE_BAD_PARAMETER;
244                 goto unlock_and_exit;
245         }
246
247         gpe_register_info = gpe_event_info->register_info;
248         if (!gpe_register_info) {
249                 status = AE_NOT_EXIST;
250                 goto unlock_and_exit;
251         }
252
253         register_bit =
254             acpi_hw_get_gpe_register_bit(gpe_event_info, gpe_register_info);
255
256         /* Perform the action */
257
258         switch (action) {
259         case ACPI_GPE_ENABLE:
260                 ACPI_SET_BIT(gpe_register_info->enable_for_wake,
261                              (u8)register_bit);
262                 break;
263
264         case ACPI_GPE_DISABLE:
265                 ACPI_CLEAR_BIT(gpe_register_info->enable_for_wake,
266                                (u8)register_bit);
267                 break;
268
269         default:
270                 ACPI_ERROR((AE_INFO, "%u, Invalid action", action));
271                 status = AE_BAD_PARAMETER;
272                 break;
273         }
274
275 unlock_and_exit:
276         acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
277         return_ACPI_STATUS(status);
278 }
279
280 ACPI_EXPORT_SYMBOL(acpi_gpe_wakeup)
281
282 /*******************************************************************************
283  *
284  * FUNCTION:    acpi_enable_gpe
285  *
286  * PARAMETERS:  gpe_device      - Parent GPE Device. NULL for GPE0/GPE1
287  *              gpe_number      - GPE level within the GPE block
288  *
289  * RETURN:      Status
290  *
291  * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is
292  *              hardware-enabled.
293  *
294  ******************************************************************************/
295 acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number)
296 {
297         acpi_status status = AE_BAD_PARAMETER;
298         struct acpi_gpe_event_info *gpe_event_info;
299         acpi_cpu_flags flags;
300
301         ACPI_FUNCTION_TRACE(acpi_enable_gpe);
302
303         flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
304
305         /* Ensure that we have a valid GPE number */
306
307         gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
308         if (gpe_event_info) {
309                 status = acpi_raw_enable_gpe(gpe_event_info);
310         }
311
312         acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
313         return_ACPI_STATUS(status);
314 }
315 ACPI_EXPORT_SYMBOL(acpi_enable_gpe)
316
317 /*******************************************************************************
318  *
319  * FUNCTION:    acpi_disable_gpe
320  *
321  * PARAMETERS:  gpe_device      - Parent GPE Device. NULL for GPE0/GPE1
322  *              gpe_number      - GPE level within the GPE block
323  *
324  * RETURN:      Status
325  *
326  * DESCRIPTION: Remove a reference to a GPE. When the last reference is
327  *              removed, only then is the GPE disabled (for runtime GPEs), or
328  *              the GPE mask bit disabled (for wake GPEs)
329  *
330  ******************************************************************************/
331 acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number)
332 {
333         acpi_status status = AE_BAD_PARAMETER;
334         struct acpi_gpe_event_info *gpe_event_info;
335         acpi_cpu_flags flags;
336
337         ACPI_FUNCTION_TRACE(acpi_disable_gpe);
338
339         flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
340
341         /* Ensure that we have a valid GPE number */
342
343         gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
344         if (gpe_event_info) {
345                 status = acpi_raw_disable_gpe(gpe_event_info) ;
346         }
347
348         acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
349         return_ACPI_STATUS(status);
350 }
351 ACPI_EXPORT_SYMBOL(acpi_disable_gpe)
352
353 /*******************************************************************************
354  *
355  * FUNCTION:    acpi_gpe_can_wake
356  *
357  * PARAMETERS:  gpe_device      - Parent GPE Device. NULL for GPE0/GPE1
358  *              gpe_number      - GPE level within the GPE block
359  *
360  * RETURN:      Status
361  *
362  * DESCRIPTION: Set the ACPI_GPE_CAN_WAKE flag for the given GPE.  If the GPE
363  *              has a corresponding method and is currently enabled, disable it
364  *              (GPEs with corresponding methods are enabled unconditionally
365  *              during initialization, but GPEs that can wake up are expected
366  *              to be initially disabled).
367  *
368  ******************************************************************************/
369 acpi_status acpi_gpe_can_wake(acpi_handle gpe_device, u32 gpe_number)
370 {
371         acpi_status status = AE_OK;
372         struct acpi_gpe_event_info *gpe_event_info;
373         acpi_cpu_flags flags;
374
375         ACPI_FUNCTION_TRACE(acpi_gpe_can_wake);
376
377         flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
378
379         /* Ensure that we have a valid GPE number */
380
381         gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
382         if (!gpe_event_info) {
383                 status = AE_BAD_PARAMETER;
384                 goto unlock_and_exit;
385         }
386
387         if (gpe_event_info->flags & ACPI_GPE_CAN_WAKE) {
388                 goto unlock_and_exit;
389         }
390
391         gpe_event_info->flags |= ACPI_GPE_CAN_WAKE;
392         if (gpe_event_info->flags & ACPI_GPE_DISPATCH_METHOD) {
393                 (void)acpi_raw_disable_gpe(gpe_event_info);
394         }
395
396 unlock_and_exit:
397         acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
398         return_ACPI_STATUS(status);
399 }
400 ACPI_EXPORT_SYMBOL(acpi_gpe_can_wake)
401
402 /*******************************************************************************
403  *
404  * FUNCTION:    acpi_disable_event
405  *
406  * PARAMETERS:  Event           - The fixed eventto be enabled
407  *              Flags           - Reserved
408  *
409  * RETURN:      Status
410  *
411  * DESCRIPTION: Disable an ACPI event (fixed)
412  *
413  ******************************************************************************/
414 acpi_status acpi_disable_event(u32 event, u32 flags)
415 {
416         acpi_status status = AE_OK;
417         u32 value;
418
419         ACPI_FUNCTION_TRACE(acpi_disable_event);
420
421         /* Decode the Fixed Event */
422
423         if (event > ACPI_EVENT_MAX) {
424                 return_ACPI_STATUS(AE_BAD_PARAMETER);
425         }
426
427         /*
428          * Disable the requested fixed event (by writing a zero to the enable
429          * register bit)
430          */
431         status =
432             acpi_write_bit_register(acpi_gbl_fixed_event_info[event].
433                                     enable_register_id, ACPI_DISABLE_EVENT);
434         if (ACPI_FAILURE(status)) {
435                 return_ACPI_STATUS(status);
436         }
437
438         status =
439             acpi_read_bit_register(acpi_gbl_fixed_event_info[event].
440                                    enable_register_id, &value);
441         if (ACPI_FAILURE(status)) {
442                 return_ACPI_STATUS(status);
443         }
444
445         if (value != 0) {
446                 ACPI_ERROR((AE_INFO,
447                             "Could not disable %s events",
448                             acpi_ut_get_event_name(event)));
449                 return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE);
450         }
451
452         return_ACPI_STATUS(status);
453 }
454
455 ACPI_EXPORT_SYMBOL(acpi_disable_event)
456
457 /*******************************************************************************
458  *
459  * FUNCTION:    acpi_clear_event
460  *
461  * PARAMETERS:  Event           - The fixed event to be cleared
462  *
463  * RETURN:      Status
464  *
465  * DESCRIPTION: Clear an ACPI event (fixed)
466  *
467  ******************************************************************************/
468 acpi_status acpi_clear_event(u32 event)
469 {
470         acpi_status status = AE_OK;
471
472         ACPI_FUNCTION_TRACE(acpi_clear_event);
473
474         /* Decode the Fixed Event */
475
476         if (event > ACPI_EVENT_MAX) {
477                 return_ACPI_STATUS(AE_BAD_PARAMETER);
478         }
479
480         /*
481          * Clear the requested fixed event (By writing a one to the status
482          * register bit)
483          */
484         status =
485             acpi_write_bit_register(acpi_gbl_fixed_event_info[event].
486                                     status_register_id, ACPI_CLEAR_STATUS);
487
488         return_ACPI_STATUS(status);
489 }
490
491 ACPI_EXPORT_SYMBOL(acpi_clear_event)
492
493 /*******************************************************************************
494  *
495  * FUNCTION:    acpi_clear_gpe
496  *
497  * PARAMETERS:  gpe_device      - Parent GPE Device. NULL for GPE0/GPE1
498  *              gpe_number      - GPE level within the GPE block
499  *
500  * RETURN:      Status
501  *
502  * DESCRIPTION: Clear an ACPI event (general purpose)
503  *
504  ******************************************************************************/
505 acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number)
506 {
507         acpi_status status = AE_OK;
508         struct acpi_gpe_event_info *gpe_event_info;
509         acpi_cpu_flags flags;
510
511         ACPI_FUNCTION_TRACE(acpi_clear_gpe);
512
513         flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
514
515         /* Ensure that we have a valid GPE number */
516
517         gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
518         if (!gpe_event_info) {
519                 status = AE_BAD_PARAMETER;
520                 goto unlock_and_exit;
521         }
522
523         status = acpi_hw_clear_gpe(gpe_event_info);
524
525       unlock_and_exit:
526         acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
527         return_ACPI_STATUS(status);
528 }
529
530 ACPI_EXPORT_SYMBOL(acpi_clear_gpe)
531 /*******************************************************************************
532  *
533  * FUNCTION:    acpi_get_event_status
534  *
535  * PARAMETERS:  Event           - The fixed event
536  *              event_status    - Where the current status of the event will
537  *                                be returned
538  *
539  * RETURN:      Status
540  *
541  * DESCRIPTION: Obtains and returns the current status of the event
542  *
543  ******************************************************************************/
544 acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status)
545 {
546         acpi_status status = AE_OK;
547         u32 value;
548
549         ACPI_FUNCTION_TRACE(acpi_get_event_status);
550
551         if (!event_status) {
552                 return_ACPI_STATUS(AE_BAD_PARAMETER);
553         }
554
555         /* Decode the Fixed Event */
556
557         if (event > ACPI_EVENT_MAX) {
558                 return_ACPI_STATUS(AE_BAD_PARAMETER);
559         }
560
561         /* Get the status of the requested fixed event */
562
563         status =
564             acpi_read_bit_register(acpi_gbl_fixed_event_info[event].
565                               enable_register_id, &value);
566         if (ACPI_FAILURE(status))
567                 return_ACPI_STATUS(status);
568
569         *event_status = value;
570
571         status =
572             acpi_read_bit_register(acpi_gbl_fixed_event_info[event].
573                               status_register_id, &value);
574         if (ACPI_FAILURE(status))
575                 return_ACPI_STATUS(status);
576
577         if (value)
578                 *event_status |= ACPI_EVENT_FLAG_SET;
579
580         if (acpi_gbl_fixed_event_handlers[event].handler)
581                 *event_status |= ACPI_EVENT_FLAG_HANDLE;
582
583         return_ACPI_STATUS(status);
584 }
585
586 ACPI_EXPORT_SYMBOL(acpi_get_event_status)
587
588 /*******************************************************************************
589  *
590  * FUNCTION:    acpi_get_gpe_status
591  *
592  * PARAMETERS:  gpe_device      - Parent GPE Device. NULL for GPE0/GPE1
593  *              gpe_number      - GPE level within the GPE block
594  *              event_status    - Where the current status of the event will
595  *                                be returned
596  *
597  * RETURN:      Status
598  *
599  * DESCRIPTION: Get status of an event (general purpose)
600  *
601  ******************************************************************************/
602 acpi_status
603 acpi_get_gpe_status(acpi_handle gpe_device,
604                     u32 gpe_number, acpi_event_status *event_status)
605 {
606         acpi_status status = AE_OK;
607         struct acpi_gpe_event_info *gpe_event_info;
608         acpi_cpu_flags flags;
609
610         ACPI_FUNCTION_TRACE(acpi_get_gpe_status);
611
612         flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
613
614         /* Ensure that we have a valid GPE number */
615
616         gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
617         if (!gpe_event_info) {
618                 status = AE_BAD_PARAMETER;
619                 goto unlock_and_exit;
620         }
621
622         /* Obtain status on the requested GPE number */
623
624         status = acpi_hw_get_gpe_status(gpe_event_info, event_status);
625
626         if (gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK)
627                 *event_status |= ACPI_EVENT_FLAG_HANDLE;
628
629       unlock_and_exit:
630         acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
631         return_ACPI_STATUS(status);
632 }
633
634 ACPI_EXPORT_SYMBOL(acpi_get_gpe_status)
635 /*******************************************************************************
636  *
637  * FUNCTION:    acpi_install_gpe_block
638  *
639  * PARAMETERS:  gpe_device          - Handle to the parent GPE Block Device
640  *              gpe_block_address   - Address and space_iD
641  *              register_count      - Number of GPE register pairs in the block
642  *              interrupt_number    - H/W interrupt for the block
643  *
644  * RETURN:      Status
645  *
646  * DESCRIPTION: Create and Install a block of GPE registers
647  *
648  ******************************************************************************/
649 acpi_status
650 acpi_install_gpe_block(acpi_handle gpe_device,
651                        struct acpi_generic_address *gpe_block_address,
652                        u32 register_count, u32 interrupt_number)
653 {
654         acpi_status status;
655         union acpi_operand_object *obj_desc;
656         struct acpi_namespace_node *node;
657         struct acpi_gpe_block_info *gpe_block;
658
659         ACPI_FUNCTION_TRACE(acpi_install_gpe_block);
660
661         if ((!gpe_device) || (!gpe_block_address) || (!register_count)) {
662                 return_ACPI_STATUS(AE_BAD_PARAMETER);
663         }
664
665         status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
666         if (ACPI_FAILURE(status)) {
667                 return (status);
668         }
669
670         node = acpi_ns_validate_handle(gpe_device);
671         if (!node) {
672                 status = AE_BAD_PARAMETER;
673                 goto unlock_and_exit;
674         }
675
676         /*
677          * For user-installed GPE Block Devices, the gpe_block_base_number
678          * is always zero
679          */
680         status =
681             acpi_ev_create_gpe_block(node, gpe_block_address, register_count, 0,
682                                      interrupt_number, &gpe_block);
683         if (ACPI_FAILURE(status)) {
684                 goto unlock_and_exit;
685         }
686
687         /* Install block in the device_object attached to the node */
688
689         obj_desc = acpi_ns_get_attached_object(node);
690         if (!obj_desc) {
691
692                 /*
693                  * No object, create a new one (Device nodes do not always have
694                  * an attached object)
695                  */
696                 obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_DEVICE);
697                 if (!obj_desc) {
698                         status = AE_NO_MEMORY;
699                         goto unlock_and_exit;
700                 }
701
702                 status =
703                     acpi_ns_attach_object(node, obj_desc, ACPI_TYPE_DEVICE);
704
705                 /* Remove local reference to the object */
706
707                 acpi_ut_remove_reference(obj_desc);
708
709                 if (ACPI_FAILURE(status)) {
710                         goto unlock_and_exit;
711                 }
712         }
713
714         /* Now install the GPE block in the device_object */
715
716         obj_desc->device.gpe_block = gpe_block;
717
718         /* Enable the runtime GPEs in the new block */
719
720         status = acpi_ev_initialize_gpe_block(node, gpe_block);
721
722       unlock_and_exit:
723         (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
724         return_ACPI_STATUS(status);
725 }
726
727 ACPI_EXPORT_SYMBOL(acpi_install_gpe_block)
728
729 /*******************************************************************************
730  *
731  * FUNCTION:    acpi_remove_gpe_block
732  *
733  * PARAMETERS:  gpe_device          - Handle to the parent GPE Block Device
734  *
735  * RETURN:      Status
736  *
737  * DESCRIPTION: Remove a previously installed block of GPE registers
738  *
739  ******************************************************************************/
740 acpi_status acpi_remove_gpe_block(acpi_handle gpe_device)
741 {
742         union acpi_operand_object *obj_desc;
743         acpi_status status;
744         struct acpi_namespace_node *node;
745
746         ACPI_FUNCTION_TRACE(acpi_remove_gpe_block);
747
748         if (!gpe_device) {
749                 return_ACPI_STATUS(AE_BAD_PARAMETER);
750         }
751
752         status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
753         if (ACPI_FAILURE(status)) {
754                 return (status);
755         }
756
757         node = acpi_ns_validate_handle(gpe_device);
758         if (!node) {
759                 status = AE_BAD_PARAMETER;
760                 goto unlock_and_exit;
761         }
762
763         /* Get the device_object attached to the node */
764
765         obj_desc = acpi_ns_get_attached_object(node);
766         if (!obj_desc || !obj_desc->device.gpe_block) {
767                 return_ACPI_STATUS(AE_NULL_OBJECT);
768         }
769
770         /* Delete the GPE block (but not the device_object) */
771
772         status = acpi_ev_delete_gpe_block(obj_desc->device.gpe_block);
773         if (ACPI_SUCCESS(status)) {
774                 obj_desc->device.gpe_block = NULL;
775         }
776
777       unlock_and_exit:
778         (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
779         return_ACPI_STATUS(status);
780 }
781
782 ACPI_EXPORT_SYMBOL(acpi_remove_gpe_block)
783
784 /*******************************************************************************
785  *
786  * FUNCTION:    acpi_get_gpe_device
787  *
788  * PARAMETERS:  Index               - System GPE index (0-current_gpe_count)
789  *              gpe_device          - Where the parent GPE Device is returned
790  *
791  * RETURN:      Status
792  *
793  * DESCRIPTION: Obtain the GPE device associated with the input index. A NULL
794  *              gpe device indicates that the gpe number is contained in one of
795  *              the FADT-defined gpe blocks. Otherwise, the GPE block device.
796  *
797  ******************************************************************************/
798 acpi_status
799 acpi_get_gpe_device(u32 index, acpi_handle *gpe_device)
800 {
801         struct acpi_gpe_device_info info;
802         acpi_status status;
803
804         ACPI_FUNCTION_TRACE(acpi_get_gpe_device);
805
806         if (!gpe_device) {
807                 return_ACPI_STATUS(AE_BAD_PARAMETER);
808         }
809
810         if (index >= acpi_current_gpe_count) {
811                 return_ACPI_STATUS(AE_NOT_EXIST);
812         }
813
814         /* Setup and walk the GPE list */
815
816         info.index = index;
817         info.status = AE_NOT_EXIST;
818         info.gpe_device = NULL;
819         info.next_block_base_index = 0;
820
821         status = acpi_ev_walk_gpe_list(acpi_ev_get_gpe_device, &info);
822         if (ACPI_FAILURE(status)) {
823                 return_ACPI_STATUS(status);
824         }
825
826         *gpe_device = info.gpe_device;
827         return_ACPI_STATUS(info.status);
828 }
829
830 ACPI_EXPORT_SYMBOL(acpi_get_gpe_device)
831
832 /*******************************************************************************
833  *
834  * FUNCTION:    acpi_ev_get_gpe_device
835  *
836  * PARAMETERS:  GPE_WALK_CALLBACK
837  *
838  * RETURN:      Status
839  *
840  * DESCRIPTION: Matches the input GPE index (0-current_gpe_count) with a GPE
841  *              block device. NULL if the GPE is one of the FADT-defined GPEs.
842  *
843  ******************************************************************************/
844 static acpi_status
845 acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
846                        struct acpi_gpe_block_info *gpe_block, void *context)
847 {
848         struct acpi_gpe_device_info *info = context;
849
850         /* Increment Index by the number of GPEs in this block */
851
852         info->next_block_base_index += gpe_block->gpe_count;
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 }