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