1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44#include <acpi/acpi.h>
45#include "accommon.h"
46#include "acevents.h"
47#include "acnamesp.h"
48
49#define _COMPONENT ACPI_EVENTS
50ACPI_MODULE_NAME("evxfgpe")
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74acpi_status acpi_update_all_gpes(void)
75{
76 acpi_status status;
77
78 ACPI_FUNCTION_TRACE(acpi_update_all_gpes);
79
80 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
81 if (ACPI_FAILURE(status)) {
82 return_ACPI_STATUS(status);
83 }
84
85 if (acpi_gbl_all_gpes_initialized) {
86 goto unlock_and_exit;
87 }
88
89 status = acpi_ev_walk_gpe_list(acpi_ev_initialize_gpe_block, NULL);
90 if (ACPI_SUCCESS(status)) {
91 acpi_gbl_all_gpes_initialized = TRUE;
92 }
93
94unlock_and_exit:
95 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
96
97 return_ACPI_STATUS(status);
98}
99
100ACPI_EXPORT_SYMBOL(acpi_update_all_gpes)
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number)
117{
118 acpi_status status = AE_BAD_PARAMETER;
119 struct acpi_gpe_event_info *gpe_event_info;
120 acpi_cpu_flags flags;
121
122 ACPI_FUNCTION_TRACE(acpi_enable_gpe);
123
124 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
125
126
127
128 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
129 if (gpe_event_info) {
130 status = acpi_ev_add_gpe_reference(gpe_event_info);
131 }
132
133 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
134 return_ACPI_STATUS(status);
135}
136ACPI_EXPORT_SYMBOL(acpi_enable_gpe)
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number)
154{
155 acpi_status status = AE_BAD_PARAMETER;
156 struct acpi_gpe_event_info *gpe_event_info;
157 acpi_cpu_flags flags;
158
159 ACPI_FUNCTION_TRACE(acpi_disable_gpe);
160
161 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
162
163
164
165 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
166 if (gpe_event_info) {
167 status = acpi_ev_remove_gpe_reference(gpe_event_info) ;
168 }
169
170 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
171 return_ACPI_STATUS(status);
172}
173ACPI_EXPORT_SYMBOL(acpi_disable_gpe)
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194acpi_status
195acpi_setup_gpe_for_wake(acpi_handle wake_device,
196 acpi_handle gpe_device, u32 gpe_number)
197{
198 acpi_status status = AE_BAD_PARAMETER;
199 struct acpi_gpe_event_info *gpe_event_info;
200 struct acpi_namespace_node *device_node;
201 struct acpi_gpe_notify_object *notify_object;
202 acpi_cpu_flags flags;
203 u8 gpe_dispatch_mask;
204
205 ACPI_FUNCTION_TRACE(acpi_setup_gpe_for_wake);
206
207
208
209 if (!wake_device) {
210
211
212
213
214 return_ACPI_STATUS(AE_BAD_PARAMETER);
215 }
216
217 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
218
219
220
221 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
222 if (!gpe_event_info) {
223 goto unlock_and_exit;
224 }
225
226 if (wake_device == ACPI_ROOT_OBJECT) {
227 goto out;
228 }
229
230
231
232
233
234
235
236 gpe_dispatch_mask = gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK;
237 if (gpe_dispatch_mask != ACPI_GPE_DISPATCH_NONE
238 && gpe_dispatch_mask != ACPI_GPE_DISPATCH_NOTIFY) {
239 goto out;
240 }
241
242
243
244 device_node = ACPI_CAST_PTR(struct acpi_namespace_node, wake_device);
245 if (device_node->type != ACPI_TYPE_DEVICE) {
246 goto unlock_and_exit;
247 }
248
249 if (gpe_dispatch_mask == ACPI_GPE_DISPATCH_NONE) {
250 gpe_event_info->flags = (ACPI_GPE_DISPATCH_NOTIFY |
251 ACPI_GPE_LEVEL_TRIGGERED);
252 gpe_event_info->dispatch.device.node = device_node;
253 gpe_event_info->dispatch.device.next = NULL;
254 } else {
255
256
257 notify_object = ACPI_ALLOCATE_ZEROED(sizeof(*notify_object));
258 if (!notify_object) {
259 status = AE_NO_MEMORY;
260 goto unlock_and_exit;
261 }
262
263 notify_object->node = device_node;
264 notify_object->next = gpe_event_info->dispatch.device.next;
265 gpe_event_info->dispatch.device.next = notify_object;
266 }
267
268 out:
269 gpe_event_info->flags |= ACPI_GPE_CAN_WAKE;
270 status = AE_OK;
271
272 unlock_and_exit:
273 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
274 return_ACPI_STATUS(status);
275}
276ACPI_EXPORT_SYMBOL(acpi_setup_gpe_for_wake)
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293acpi_status acpi_set_gpe_wake_mask(acpi_handle gpe_device, u32 gpe_number, u8 action)
294{
295 acpi_status status = AE_OK;
296 struct acpi_gpe_event_info *gpe_event_info;
297 struct acpi_gpe_register_info *gpe_register_info;
298 acpi_cpu_flags flags;
299 u32 register_bit;
300
301 ACPI_FUNCTION_TRACE(acpi_set_gpe_wake_mask);
302
303 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
304
305
306
307
308
309 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
310 if (!gpe_event_info) {
311 status = AE_BAD_PARAMETER;
312 goto unlock_and_exit;
313 }
314
315 if (!(gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) {
316 status = AE_TYPE;
317 goto unlock_and_exit;
318 }
319
320 gpe_register_info = gpe_event_info->register_info;
321 if (!gpe_register_info) {
322 status = AE_NOT_EXIST;
323 goto unlock_and_exit;
324 }
325
326 register_bit =
327 acpi_hw_get_gpe_register_bit(gpe_event_info, gpe_register_info);
328
329
330
331 switch (action) {
332 case ACPI_GPE_ENABLE:
333 ACPI_SET_BIT(gpe_register_info->enable_for_wake,
334 (u8)register_bit);
335 break;
336
337 case ACPI_GPE_DISABLE:
338 ACPI_CLEAR_BIT(gpe_register_info->enable_for_wake,
339 (u8)register_bit);
340 break;
341
342 default:
343 ACPI_ERROR((AE_INFO, "%u, Invalid action", action));
344 status = AE_BAD_PARAMETER;
345 break;
346 }
347
348unlock_and_exit:
349 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
350 return_ACPI_STATUS(status);
351}
352
353ACPI_EXPORT_SYMBOL(acpi_set_gpe_wake_mask)
354
355
356
357
358
359
360
361
362
363
364
365
366
367acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number)
368{
369 acpi_status status = AE_OK;
370 struct acpi_gpe_event_info *gpe_event_info;
371 acpi_cpu_flags flags;
372
373 ACPI_FUNCTION_TRACE(acpi_clear_gpe);
374
375 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
376
377
378
379 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
380 if (!gpe_event_info) {
381 status = AE_BAD_PARAMETER;
382 goto unlock_and_exit;
383 }
384
385 status = acpi_hw_clear_gpe(gpe_event_info);
386
387 unlock_and_exit:
388 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
389 return_ACPI_STATUS(status);
390}
391
392ACPI_EXPORT_SYMBOL(acpi_clear_gpe)
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408acpi_status
409acpi_get_gpe_status(acpi_handle gpe_device,
410 u32 gpe_number, acpi_event_status *event_status)
411{
412 acpi_status status = AE_OK;
413 struct acpi_gpe_event_info *gpe_event_info;
414 acpi_cpu_flags flags;
415
416 ACPI_FUNCTION_TRACE(acpi_get_gpe_status);
417
418 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
419
420
421
422 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
423 if (!gpe_event_info) {
424 status = AE_BAD_PARAMETER;
425 goto unlock_and_exit;
426 }
427
428
429
430 status = acpi_hw_get_gpe_status(gpe_event_info, event_status);
431
432 if (gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK)
433 *event_status |= ACPI_EVENT_FLAG_HANDLE;
434
435 unlock_and_exit:
436 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
437 return_ACPI_STATUS(status);
438}
439
440ACPI_EXPORT_SYMBOL(acpi_get_gpe_status)
441
442
443
444
445
446
447
448
449
450
451
452
453
454acpi_status acpi_disable_all_gpes(void)
455{
456 acpi_status status;
457
458 ACPI_FUNCTION_TRACE(acpi_disable_all_gpes);
459
460 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
461 if (ACPI_FAILURE(status)) {
462 return_ACPI_STATUS(status);
463 }
464
465 status = acpi_hw_disable_all_gpes();
466 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
467
468 return_ACPI_STATUS(status);
469}
470
471ACPI_EXPORT_SYMBOL(acpi_disable_all_gpes)
472
473
474
475
476
477
478
479
480
481
482
483
484
485acpi_status acpi_enable_all_runtime_gpes(void)
486{
487 acpi_status status;
488
489 ACPI_FUNCTION_TRACE(acpi_enable_all_runtime_gpes);
490
491 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
492 if (ACPI_FAILURE(status)) {
493 return_ACPI_STATUS(status);
494 }
495
496 status = acpi_hw_enable_all_runtime_gpes();
497 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
498
499 return_ACPI_STATUS(status);
500}
501
502ACPI_EXPORT_SYMBOL(acpi_enable_all_runtime_gpes)
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519acpi_status
520acpi_install_gpe_block(acpi_handle gpe_device,
521 struct acpi_generic_address *gpe_block_address,
522 u32 register_count, u32 interrupt_number)
523{
524 acpi_status status;
525 union acpi_operand_object *obj_desc;
526 struct acpi_namespace_node *node;
527 struct acpi_gpe_block_info *gpe_block;
528
529 ACPI_FUNCTION_TRACE(acpi_install_gpe_block);
530
531 if ((!gpe_device) || (!gpe_block_address) || (!register_count)) {
532 return_ACPI_STATUS(AE_BAD_PARAMETER);
533 }
534
535 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
536 if (ACPI_FAILURE(status)) {
537 return (status);
538 }
539
540 node = acpi_ns_validate_handle(gpe_device);
541 if (!node) {
542 status = AE_BAD_PARAMETER;
543 goto unlock_and_exit;
544 }
545
546
547
548
549
550 status =
551 acpi_ev_create_gpe_block(node, gpe_block_address, register_count, 0,
552 interrupt_number, &gpe_block);
553 if (ACPI_FAILURE(status)) {
554 goto unlock_and_exit;
555 }
556
557
558
559 obj_desc = acpi_ns_get_attached_object(node);
560 if (!obj_desc) {
561
562
563
564
565
566 obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_DEVICE);
567 if (!obj_desc) {
568 status = AE_NO_MEMORY;
569 goto unlock_and_exit;
570 }
571
572 status =
573 acpi_ns_attach_object(node, obj_desc, ACPI_TYPE_DEVICE);
574
575
576
577 acpi_ut_remove_reference(obj_desc);
578
579 if (ACPI_FAILURE(status)) {
580 goto unlock_and_exit;
581 }
582 }
583
584
585
586 obj_desc->device.gpe_block = gpe_block;
587
588 unlock_and_exit:
589 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
590 return_ACPI_STATUS(status);
591}
592
593ACPI_EXPORT_SYMBOL(acpi_install_gpe_block)
594
595
596
597
598
599
600
601
602
603
604
605
606acpi_status acpi_remove_gpe_block(acpi_handle gpe_device)
607{
608 union acpi_operand_object *obj_desc;
609 acpi_status status;
610 struct acpi_namespace_node *node;
611
612 ACPI_FUNCTION_TRACE(acpi_remove_gpe_block);
613
614 if (!gpe_device) {
615 return_ACPI_STATUS(AE_BAD_PARAMETER);
616 }
617
618 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
619 if (ACPI_FAILURE(status)) {
620 return (status);
621 }
622
623 node = acpi_ns_validate_handle(gpe_device);
624 if (!node) {
625 status = AE_BAD_PARAMETER;
626 goto unlock_and_exit;
627 }
628
629
630
631 obj_desc = acpi_ns_get_attached_object(node);
632 if (!obj_desc || !obj_desc->device.gpe_block) {
633 return_ACPI_STATUS(AE_NULL_OBJECT);
634 }
635
636
637
638 status = acpi_ev_delete_gpe_block(obj_desc->device.gpe_block);
639 if (ACPI_SUCCESS(status)) {
640 obj_desc->device.gpe_block = NULL;
641 }
642
643 unlock_and_exit:
644 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
645 return_ACPI_STATUS(status);
646}
647
648ACPI_EXPORT_SYMBOL(acpi_remove_gpe_block)
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664acpi_status
665acpi_get_gpe_device(u32 index, acpi_handle *gpe_device)
666{
667 struct acpi_gpe_device_info info;
668 acpi_status status;
669
670 ACPI_FUNCTION_TRACE(acpi_get_gpe_device);
671
672 if (!gpe_device) {
673 return_ACPI_STATUS(AE_BAD_PARAMETER);
674 }
675
676 if (index >= acpi_current_gpe_count) {
677 return_ACPI_STATUS(AE_NOT_EXIST);
678 }
679
680
681
682 info.index = index;
683 info.status = AE_NOT_EXIST;
684 info.gpe_device = NULL;
685 info.next_block_base_index = 0;
686
687 status = acpi_ev_walk_gpe_list(acpi_ev_get_gpe_device, &info);
688 if (ACPI_FAILURE(status)) {
689 return_ACPI_STATUS(status);
690 }
691
692 *gpe_device = ACPI_CAST_PTR(acpi_handle, info.gpe_device);
693 return_ACPI_STATUS(info.status);
694}
695
696ACPI_EXPORT_SYMBOL(acpi_get_gpe_device)
697