]> git.karo-electronics.de Git - linux-beck.git/blob - drivers/acpi/acpica/evxfevnt.c
ACPICA: Use low-level GPE enable during GPE block initialization
[linux-beck.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. NULL for GPE0/GPE1
216  *              gpe_number      - GPE level within the GPE block
217  *              action          - ACPI_GPE_ENABLE or ACPI_GPE_DISABLE
218  *
219  * RETURN:      Status
220  *
221  * DESCRIPTION: Enable or disable an individual GPE. This function bypasses
222  *              the reference count mechanism used in the acpi_enable_gpe and
223  *              acpi_disable_gpe interfaces -- and should be used with care.
224  *
225  * Note: Typically used to disable a runtime GPE for short period of time,
226  * then re-enable it, without disturbing the existing reference counts. This
227  * is useful, for example, in the Embedded Controller (EC) driver.
228  *
229  ******************************************************************************/
230 acpi_status acpi_set_gpe(acpi_handle gpe_device, u32 gpe_number, u8 action)
231 {
232         struct acpi_gpe_event_info *gpe_event_info;
233         acpi_status status;
234         acpi_cpu_flags flags;
235
236         ACPI_FUNCTION_TRACE(acpi_set_gpe);
237
238         flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
239
240         /* Ensure that we have a valid GPE number */
241
242         gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
243         if (!gpe_event_info) {
244                 status = AE_BAD_PARAMETER;
245                 goto unlock_and_exit;
246         }
247
248         /* Perform the action */
249
250         switch (action) {
251         case ACPI_GPE_ENABLE:
252                 status = acpi_ev_enable_gpe(gpe_event_info);
253                 break;
254
255         case ACPI_GPE_DISABLE:
256                 status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE);
257                 break;
258
259         default:
260                 status = AE_BAD_PARAMETER;
261                 break;
262         }
263
264       unlock_and_exit:
265         acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
266         return_ACPI_STATUS(status);
267 }
268
269 ACPI_EXPORT_SYMBOL(acpi_set_gpe)
270
271 /*******************************************************************************
272  *
273  * FUNCTION:    acpi_gpe_wakeup
274  *
275  * PARAMETERS:  gpe_device      - Parent GPE Device. NULL for GPE0/GPE1
276  *              gpe_number      - GPE level within the GPE block
277  *              Action          - Enable or Disable
278  *
279  * RETURN:      Status
280  *
281  * DESCRIPTION: Set or clear the GPE's wakeup enable mask bit.
282  *
283  ******************************************************************************/
284 acpi_status acpi_gpe_wakeup(acpi_handle gpe_device, u32 gpe_number, u8 action)
285 {
286         acpi_status status = AE_OK;
287         struct acpi_gpe_event_info *gpe_event_info;
288         struct acpi_gpe_register_info *gpe_register_info;
289         acpi_cpu_flags flags;
290         u32 register_bit;
291
292         ACPI_FUNCTION_TRACE(acpi_gpe_wakeup);
293
294         flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
295
296         /* Ensure that we have a valid GPE number */
297
298         gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
299         if (!gpe_event_info) {
300                 status = AE_BAD_PARAMETER;
301                 goto unlock_and_exit;
302         }
303
304         gpe_register_info = gpe_event_info->register_info;
305         if (!gpe_register_info) {
306                 status = AE_NOT_EXIST;
307                 goto unlock_and_exit;
308         }
309
310         register_bit =
311             acpi_hw_get_gpe_register_bit(gpe_event_info, gpe_register_info);
312
313         /* Perform the action */
314
315         switch (action) {
316         case ACPI_GPE_ENABLE:
317                 ACPI_SET_BIT(gpe_register_info->enable_for_wake,
318                              (u8)register_bit);
319                 break;
320
321         case ACPI_GPE_DISABLE:
322                 ACPI_CLEAR_BIT(gpe_register_info->enable_for_wake,
323                                (u8)register_bit);
324                 break;
325
326         default:
327                 ACPI_ERROR((AE_INFO, "%u, Invalid action", action));
328                 status = AE_BAD_PARAMETER;
329                 break;
330         }
331
332 unlock_and_exit:
333         acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
334         return_ACPI_STATUS(status);
335 }
336
337 ACPI_EXPORT_SYMBOL(acpi_gpe_wakeup)
338
339 /*******************************************************************************
340  *
341  * FUNCTION:    acpi_enable_gpe
342  *
343  * PARAMETERS:  gpe_device      - Parent GPE Device. NULL for GPE0/GPE1
344  *              gpe_number      - GPE level within the GPE block
345  *
346  * RETURN:      Status
347  *
348  * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is
349  *              hardware-enabled.
350  *
351  ******************************************************************************/
352 acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number)
353 {
354         acpi_status status = AE_OK;
355         struct acpi_gpe_event_info *gpe_event_info;
356         acpi_cpu_flags flags;
357
358         ACPI_FUNCTION_TRACE(acpi_enable_gpe);
359
360         flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
361
362         /* Ensure that we have a valid GPE number */
363
364         gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
365         if (!gpe_event_info) {
366                 status = AE_BAD_PARAMETER;
367                 goto unlock_and_exit;
368         }
369
370         if (gpe_event_info->runtime_count == ACPI_UINT8_MAX) {
371                 status = AE_LIMIT;      /* Too many references */
372                 goto unlock_and_exit;
373         }
374
375         gpe_event_info->runtime_count++;
376         if (gpe_event_info->runtime_count == 1) {
377                 status = acpi_ev_update_gpe_enable_mask(gpe_event_info);
378                 if (ACPI_SUCCESS(status)) {
379                         status = acpi_ev_enable_gpe(gpe_event_info);
380                 }
381                 if (ACPI_FAILURE(status)) {
382                         gpe_event_info->runtime_count--;
383                 }
384         }
385
386 unlock_and_exit:
387         acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
388         return_ACPI_STATUS(status);
389 }
390 ACPI_EXPORT_SYMBOL(acpi_enable_gpe)
391
392 /*******************************************************************************
393  *
394  * FUNCTION:    acpi_disable_gpe
395  *
396  * PARAMETERS:  gpe_device      - Parent GPE Device. NULL for GPE0/GPE1
397  *              gpe_number      - GPE level within the GPE block
398  *
399  * RETURN:      Status
400  *
401  * DESCRIPTION: Remove a reference to a GPE. When the last reference is
402  *              removed, only then is the GPE disabled (for runtime GPEs), or
403  *              the GPE mask bit disabled (for wake GPEs)
404  *
405  ******************************************************************************/
406 acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number)
407 {
408         acpi_status status = AE_OK;
409         struct acpi_gpe_event_info *gpe_event_info;
410         acpi_cpu_flags flags;
411
412         ACPI_FUNCTION_TRACE(acpi_disable_gpe);
413
414         flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
415
416         /* Ensure that we have a valid GPE number */
417
418         gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
419         if (!gpe_event_info) {
420                 status = AE_BAD_PARAMETER;
421                 goto unlock_and_exit;
422         }
423
424         /* Hardware-disable a runtime GPE on removal of the last reference */
425
426         if (!gpe_event_info->runtime_count) {
427                 status = AE_LIMIT;      /* There are no references to remove */
428                 goto unlock_and_exit;
429         }
430
431         gpe_event_info->runtime_count--;
432         if (!gpe_event_info->runtime_count) {
433                 status = acpi_ev_update_gpe_enable_mask(gpe_event_info);
434                 if (ACPI_SUCCESS(status)) {
435                         status =
436                             acpi_hw_low_set_gpe(gpe_event_info,
437                                                 ACPI_GPE_DISABLE);
438                 }
439                 if (ACPI_FAILURE(status)) {
440                         gpe_event_info->runtime_count++;
441                 }
442         }
443
444 unlock_and_exit:
445         acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
446         return_ACPI_STATUS(status);
447 }
448 ACPI_EXPORT_SYMBOL(acpi_disable_gpe)
449
450 /*******************************************************************************
451  *
452  * FUNCTION:    acpi_disable_event
453  *
454  * PARAMETERS:  Event           - The fixed eventto be enabled
455  *              Flags           - Reserved
456  *
457  * RETURN:      Status
458  *
459  * DESCRIPTION: Disable an ACPI event (fixed)
460  *
461  ******************************************************************************/
462 acpi_status acpi_disable_event(u32 event, u32 flags)
463 {
464         acpi_status status = AE_OK;
465         u32 value;
466
467         ACPI_FUNCTION_TRACE(acpi_disable_event);
468
469         /* Decode the Fixed Event */
470
471         if (event > ACPI_EVENT_MAX) {
472                 return_ACPI_STATUS(AE_BAD_PARAMETER);
473         }
474
475         /*
476          * Disable the requested fixed event (by writing a zero to the enable
477          * register bit)
478          */
479         status =
480             acpi_write_bit_register(acpi_gbl_fixed_event_info[event].
481                                     enable_register_id, ACPI_DISABLE_EVENT);
482         if (ACPI_FAILURE(status)) {
483                 return_ACPI_STATUS(status);
484         }
485
486         status =
487             acpi_read_bit_register(acpi_gbl_fixed_event_info[event].
488                                    enable_register_id, &value);
489         if (ACPI_FAILURE(status)) {
490                 return_ACPI_STATUS(status);
491         }
492
493         if (value != 0) {
494                 ACPI_ERROR((AE_INFO,
495                             "Could not disable %s events",
496                             acpi_ut_get_event_name(event)));
497                 return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE);
498         }
499
500         return_ACPI_STATUS(status);
501 }
502
503 ACPI_EXPORT_SYMBOL(acpi_disable_event)
504
505 /*******************************************************************************
506  *
507  * FUNCTION:    acpi_clear_event
508  *
509  * PARAMETERS:  Event           - The fixed event to be cleared
510  *
511  * RETURN:      Status
512  *
513  * DESCRIPTION: Clear an ACPI event (fixed)
514  *
515  ******************************************************************************/
516 acpi_status acpi_clear_event(u32 event)
517 {
518         acpi_status status = AE_OK;
519
520         ACPI_FUNCTION_TRACE(acpi_clear_event);
521
522         /* Decode the Fixed Event */
523
524         if (event > ACPI_EVENT_MAX) {
525                 return_ACPI_STATUS(AE_BAD_PARAMETER);
526         }
527
528         /*
529          * Clear the requested fixed event (By writing a one to the status
530          * register bit)
531          */
532         status =
533             acpi_write_bit_register(acpi_gbl_fixed_event_info[event].
534                                     status_register_id, ACPI_CLEAR_STATUS);
535
536         return_ACPI_STATUS(status);
537 }
538
539 ACPI_EXPORT_SYMBOL(acpi_clear_event)
540
541 /*******************************************************************************
542  *
543  * FUNCTION:    acpi_clear_gpe
544  *
545  * PARAMETERS:  gpe_device      - Parent GPE Device. NULL for GPE0/GPE1
546  *              gpe_number      - GPE level within the GPE block
547  *
548  * RETURN:      Status
549  *
550  * DESCRIPTION: Clear an ACPI event (general purpose)
551  *
552  ******************************************************************************/
553 acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number)
554 {
555         acpi_status status = AE_OK;
556         struct acpi_gpe_event_info *gpe_event_info;
557         acpi_cpu_flags flags;
558
559         ACPI_FUNCTION_TRACE(acpi_clear_gpe);
560
561         flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
562
563         /* Ensure that we have a valid GPE number */
564
565         gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
566         if (!gpe_event_info) {
567                 status = AE_BAD_PARAMETER;
568                 goto unlock_and_exit;
569         }
570
571         status = acpi_hw_clear_gpe(gpe_event_info);
572
573       unlock_and_exit:
574         acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
575         return_ACPI_STATUS(status);
576 }
577
578 ACPI_EXPORT_SYMBOL(acpi_clear_gpe)
579 /*******************************************************************************
580  *
581  * FUNCTION:    acpi_get_event_status
582  *
583  * PARAMETERS:  Event           - The fixed event
584  *              event_status    - Where the current status of the event will
585  *                                be returned
586  *
587  * RETURN:      Status
588  *
589  * DESCRIPTION: Obtains and returns the current status of the event
590  *
591  ******************************************************************************/
592 acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status)
593 {
594         acpi_status status = AE_OK;
595         u32 value;
596
597         ACPI_FUNCTION_TRACE(acpi_get_event_status);
598
599         if (!event_status) {
600                 return_ACPI_STATUS(AE_BAD_PARAMETER);
601         }
602
603         /* Decode the Fixed Event */
604
605         if (event > ACPI_EVENT_MAX) {
606                 return_ACPI_STATUS(AE_BAD_PARAMETER);
607         }
608
609         /* Get the status of the requested fixed event */
610
611         status =
612             acpi_read_bit_register(acpi_gbl_fixed_event_info[event].
613                               enable_register_id, &value);
614         if (ACPI_FAILURE(status))
615                 return_ACPI_STATUS(status);
616
617         *event_status = value;
618
619         status =
620             acpi_read_bit_register(acpi_gbl_fixed_event_info[event].
621                               status_register_id, &value);
622         if (ACPI_FAILURE(status))
623                 return_ACPI_STATUS(status);
624
625         if (value)
626                 *event_status |= ACPI_EVENT_FLAG_SET;
627
628         if (acpi_gbl_fixed_event_handlers[event].handler)
629                 *event_status |= ACPI_EVENT_FLAG_HANDLE;
630
631         return_ACPI_STATUS(status);
632 }
633
634 ACPI_EXPORT_SYMBOL(acpi_get_event_status)
635
636 /*******************************************************************************
637  *
638  * FUNCTION:    acpi_get_gpe_status
639  *
640  * PARAMETERS:  gpe_device      - Parent GPE Device. NULL for GPE0/GPE1
641  *              gpe_number      - GPE level within the GPE block
642  *              event_status    - Where the current status of the event will
643  *                                be returned
644  *
645  * RETURN:      Status
646  *
647  * DESCRIPTION: Get status of an event (general purpose)
648  *
649  ******************************************************************************/
650 acpi_status
651 acpi_get_gpe_status(acpi_handle gpe_device,
652                     u32 gpe_number, acpi_event_status *event_status)
653 {
654         acpi_status status = AE_OK;
655         struct acpi_gpe_event_info *gpe_event_info;
656         acpi_cpu_flags flags;
657
658         ACPI_FUNCTION_TRACE(acpi_get_gpe_status);
659
660         flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
661
662         /* Ensure that we have a valid GPE number */
663
664         gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
665         if (!gpe_event_info) {
666                 status = AE_BAD_PARAMETER;
667                 goto unlock_and_exit;
668         }
669
670         /* Obtain status on the requested GPE number */
671
672         status = acpi_hw_get_gpe_status(gpe_event_info, event_status);
673
674         if (gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK)
675                 *event_status |= ACPI_EVENT_FLAG_HANDLE;
676
677       unlock_and_exit:
678         acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
679         return_ACPI_STATUS(status);
680 }
681
682 ACPI_EXPORT_SYMBOL(acpi_get_gpe_status)
683 /*******************************************************************************
684  *
685  * FUNCTION:    acpi_install_gpe_block
686  *
687  * PARAMETERS:  gpe_device          - Handle to the parent GPE Block Device
688  *              gpe_block_address   - Address and space_iD
689  *              register_count      - Number of GPE register pairs in the block
690  *              interrupt_number    - H/W interrupt for the block
691  *
692  * RETURN:      Status
693  *
694  * DESCRIPTION: Create and Install a block of GPE registers
695  *
696  ******************************************************************************/
697 acpi_status
698 acpi_install_gpe_block(acpi_handle gpe_device,
699                        struct acpi_generic_address *gpe_block_address,
700                        u32 register_count, u32 interrupt_number)
701 {
702         acpi_status status;
703         union acpi_operand_object *obj_desc;
704         struct acpi_namespace_node *node;
705         struct acpi_gpe_block_info *gpe_block;
706
707         ACPI_FUNCTION_TRACE(acpi_install_gpe_block);
708
709         if ((!gpe_device) || (!gpe_block_address) || (!register_count)) {
710                 return_ACPI_STATUS(AE_BAD_PARAMETER);
711         }
712
713         status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
714         if (ACPI_FAILURE(status)) {
715                 return (status);
716         }
717
718         node = acpi_ns_validate_handle(gpe_device);
719         if (!node) {
720                 status = AE_BAD_PARAMETER;
721                 goto unlock_and_exit;
722         }
723
724         /*
725          * For user-installed GPE Block Devices, the gpe_block_base_number
726          * is always zero
727          */
728         status =
729             acpi_ev_create_gpe_block(node, gpe_block_address, register_count, 0,
730                                      interrupt_number, &gpe_block);
731         if (ACPI_FAILURE(status)) {
732                 goto unlock_and_exit;
733         }
734
735         /* Install block in the device_object attached to the node */
736
737         obj_desc = acpi_ns_get_attached_object(node);
738         if (!obj_desc) {
739
740                 /*
741                  * No object, create a new one (Device nodes do not always have
742                  * an attached object)
743                  */
744                 obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_DEVICE);
745                 if (!obj_desc) {
746                         status = AE_NO_MEMORY;
747                         goto unlock_and_exit;
748                 }
749
750                 status =
751                     acpi_ns_attach_object(node, obj_desc, ACPI_TYPE_DEVICE);
752
753                 /* Remove local reference to the object */
754
755                 acpi_ut_remove_reference(obj_desc);
756
757                 if (ACPI_FAILURE(status)) {
758                         goto unlock_and_exit;
759                 }
760         }
761
762         /* Now install the GPE block in the device_object */
763
764         obj_desc->device.gpe_block = gpe_block;
765
766         /* Run the _PRW methods and enable the runtime GPEs in the new block */
767
768         status = acpi_ev_initialize_gpe_block(node, gpe_block);
769
770       unlock_and_exit:
771         (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
772         return_ACPI_STATUS(status);
773 }
774
775 ACPI_EXPORT_SYMBOL(acpi_install_gpe_block)
776
777 /*******************************************************************************
778  *
779  * FUNCTION:    acpi_remove_gpe_block
780  *
781  * PARAMETERS:  gpe_device          - Handle to the parent GPE Block Device
782  *
783  * RETURN:      Status
784  *
785  * DESCRIPTION: Remove a previously installed block of GPE registers
786  *
787  ******************************************************************************/
788 acpi_status acpi_remove_gpe_block(acpi_handle gpe_device)
789 {
790         union acpi_operand_object *obj_desc;
791         acpi_status status;
792         struct acpi_namespace_node *node;
793
794         ACPI_FUNCTION_TRACE(acpi_remove_gpe_block);
795
796         if (!gpe_device) {
797                 return_ACPI_STATUS(AE_BAD_PARAMETER);
798         }
799
800         status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
801         if (ACPI_FAILURE(status)) {
802                 return (status);
803         }
804
805         node = acpi_ns_validate_handle(gpe_device);
806         if (!node) {
807                 status = AE_BAD_PARAMETER;
808                 goto unlock_and_exit;
809         }
810
811         /* Get the device_object attached to the node */
812
813         obj_desc = acpi_ns_get_attached_object(node);
814         if (!obj_desc || !obj_desc->device.gpe_block) {
815                 return_ACPI_STATUS(AE_NULL_OBJECT);
816         }
817
818         /* Delete the GPE block (but not the device_object) */
819
820         status = acpi_ev_delete_gpe_block(obj_desc->device.gpe_block);
821         if (ACPI_SUCCESS(status)) {
822                 obj_desc->device.gpe_block = NULL;
823         }
824
825       unlock_and_exit:
826         (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
827         return_ACPI_STATUS(status);
828 }
829
830 ACPI_EXPORT_SYMBOL(acpi_remove_gpe_block)
831
832 /*******************************************************************************
833  *
834  * FUNCTION:    acpi_get_gpe_device
835  *
836  * PARAMETERS:  Index               - System GPE index (0-current_gpe_count)
837  *              gpe_device          - Where the parent GPE Device is returned
838  *
839  * RETURN:      Status
840  *
841  * DESCRIPTION: Obtain the GPE device associated with the input index. A NULL
842  *              gpe device indicates that the gpe number is contained in one of
843  *              the FADT-defined gpe blocks. Otherwise, the GPE block device.
844  *
845  ******************************************************************************/
846 acpi_status
847 acpi_get_gpe_device(u32 index, acpi_handle *gpe_device)
848 {
849         struct acpi_gpe_device_info info;
850         acpi_status status;
851
852         ACPI_FUNCTION_TRACE(acpi_get_gpe_device);
853
854         if (!gpe_device) {
855                 return_ACPI_STATUS(AE_BAD_PARAMETER);
856         }
857
858         if (index >= acpi_current_gpe_count) {
859                 return_ACPI_STATUS(AE_NOT_EXIST);
860         }
861
862         /* Setup and walk the GPE list */
863
864         info.index = index;
865         info.status = AE_NOT_EXIST;
866         info.gpe_device = NULL;
867         info.next_block_base_index = 0;
868
869         status = acpi_ev_walk_gpe_list(acpi_ev_get_gpe_device, &info);
870         if (ACPI_FAILURE(status)) {
871                 return_ACPI_STATUS(status);
872         }
873
874         *gpe_device = info.gpe_device;
875         return_ACPI_STATUS(info.status);
876 }
877
878 ACPI_EXPORT_SYMBOL(acpi_get_gpe_device)
879
880 /*******************************************************************************
881  *
882  * FUNCTION:    acpi_ev_get_gpe_device
883  *
884  * PARAMETERS:  GPE_WALK_CALLBACK
885  *
886  * RETURN:      Status
887  *
888  * DESCRIPTION: Matches the input GPE index (0-current_gpe_count) with a GPE
889  *              block device. NULL if the GPE is one of the FADT-defined GPEs.
890  *
891  ******************************************************************************/
892 static acpi_status
893 acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
894                        struct acpi_gpe_block_info *gpe_block, void *context)
895 {
896         struct acpi_gpe_device_info *info = context;
897
898         /* Increment Index by the number of GPEs in this block */
899
900         info->next_block_base_index += gpe_block->gpe_count;
901
902         if (info->index < info->next_block_base_index) {
903                 /*
904                  * The GPE index is within this block, get the node. Leave the node
905                  * NULL for the FADT-defined GPEs
906                  */
907                 if ((gpe_block->node)->type == ACPI_TYPE_DEVICE) {
908                         info->gpe_device = gpe_block->node;
909                 }
910
911                 info->status = AE_OK;
912                 return (AE_CTRL_END);
913         }
914
915         return (AE_OK);
916 }
917
918 /******************************************************************************
919  *
920  * FUNCTION:    acpi_disable_all_gpes
921  *
922  * PARAMETERS:  None
923  *
924  * RETURN:      Status
925  *
926  * DESCRIPTION: Disable and clear all GPEs in all GPE blocks
927  *
928  ******************************************************************************/
929
930 acpi_status acpi_disable_all_gpes(void)
931 {
932         acpi_status status;
933
934         ACPI_FUNCTION_TRACE(acpi_disable_all_gpes);
935
936         status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
937         if (ACPI_FAILURE(status)) {
938                 return_ACPI_STATUS(status);
939         }
940
941         status = acpi_hw_disable_all_gpes();
942         (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
943
944         return_ACPI_STATUS(status);
945 }
946
947 /******************************************************************************
948  *
949  * FUNCTION:    acpi_enable_all_runtime_gpes
950  *
951  * PARAMETERS:  None
952  *
953  * RETURN:      Status
954  *
955  * DESCRIPTION: Enable all "runtime" GPEs, in all GPE blocks
956  *
957  ******************************************************************************/
958
959 acpi_status acpi_enable_all_runtime_gpes(void)
960 {
961         acpi_status status;
962
963         ACPI_FUNCTION_TRACE(acpi_enable_all_runtime_gpes);
964
965         status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
966         if (ACPI_FAILURE(status)) {
967                 return_ACPI_STATUS(status);
968         }
969
970         status = acpi_hw_enable_all_runtime_gpes();
971         (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
972
973         return_ACPI_STATUS(status);
974 }