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 <linux/module.h>
45
46#include <acpi/acpi.h>
47#include <acpi/acnamesp.h>
48#include <acpi/acevents.h>
49#include <acpi/acinterp.h>
50
51#define _COMPONENT ACPI_EVENTS
52 ACPI_MODULE_NAME ("evxface")
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67#ifdef ACPI_FUTURE_USAGE
68acpi_status
69acpi_install_exception_handler (
70 acpi_exception_handler handler)
71{
72 acpi_status status;
73
74
75 ACPI_FUNCTION_TRACE ("acpi_install_exception_handler");
76
77
78 status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
79 if (ACPI_FAILURE (status)) {
80 return_ACPI_STATUS (status);
81 }
82
83
84
85 if (acpi_gbl_exception_handler) {
86 status = AE_ALREADY_EXISTS;
87 goto cleanup;
88 }
89
90
91
92 acpi_gbl_exception_handler = handler;
93
94cleanup:
95 (void) acpi_ut_release_mutex (ACPI_MTX_EVENTS);
96 return_ACPI_STATUS (status);
97}
98#endif
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117acpi_status
118acpi_install_fixed_event_handler (
119 u32 event,
120 acpi_event_handler handler,
121 void *context)
122{
123 acpi_status status;
124
125
126 ACPI_FUNCTION_TRACE ("acpi_install_fixed_event_handler");
127
128
129
130
131 if (event > ACPI_EVENT_MAX) {
132 return_ACPI_STATUS (AE_BAD_PARAMETER);
133 }
134
135 status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
136 if (ACPI_FAILURE (status)) {
137 return_ACPI_STATUS (status);
138 }
139
140
141
142 if (NULL != acpi_gbl_fixed_event_handlers[event].handler) {
143 status = AE_ALREADY_EXISTS;
144 goto cleanup;
145 }
146
147
148
149 acpi_gbl_fixed_event_handlers[event].handler = handler;
150 acpi_gbl_fixed_event_handlers[event].context = context;
151
152 status = acpi_enable_event (event, 0);
153 if (ACPI_FAILURE (status)) {
154 ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Could not enable fixed event.\n"));
155
156
157
158 acpi_gbl_fixed_event_handlers[event].handler = NULL;
159 acpi_gbl_fixed_event_handlers[event].context = NULL;
160 }
161 else {
162 ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
163 "Enabled fixed event %X, Handler=%p\n", event, handler));
164 }
165
166
167cleanup:
168 (void) acpi_ut_release_mutex (ACPI_MTX_EVENTS);
169 return_ACPI_STATUS (status);
170}
171EXPORT_SYMBOL(acpi_install_fixed_event_handler);
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187acpi_status
188acpi_remove_fixed_event_handler (
189 u32 event,
190 acpi_event_handler handler)
191{
192 acpi_status status = AE_OK;
193
194
195 ACPI_FUNCTION_TRACE ("acpi_remove_fixed_event_handler");
196
197
198
199
200 if (event > ACPI_EVENT_MAX) {
201 return_ACPI_STATUS (AE_BAD_PARAMETER);
202 }
203
204 status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
205 if (ACPI_FAILURE (status)) {
206 return_ACPI_STATUS (status);
207 }
208
209
210
211 status = acpi_disable_event (event, 0);
212
213
214
215 acpi_gbl_fixed_event_handlers[event].handler = NULL;
216 acpi_gbl_fixed_event_handlers[event].context = NULL;
217
218 if (ACPI_FAILURE (status)) {
219 ACPI_DEBUG_PRINT ((ACPI_DB_WARN,
220 "Could not write to fixed event enable register.\n"));
221 }
222 else {
223 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Disabled fixed event %X.\n", event));
224 }
225
226 (void) acpi_ut_release_mutex (ACPI_MTX_EVENTS);
227 return_ACPI_STATUS (status);
228}
229EXPORT_SYMBOL(acpi_remove_fixed_event_handler);
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250acpi_status
251acpi_install_notify_handler (
252 acpi_handle device,
253 u32 handler_type,
254 acpi_notify_handler handler,
255 void *context)
256{
257 union acpi_operand_object *obj_desc;
258 union acpi_operand_object *notify_obj;
259 struct acpi_namespace_node *node;
260 acpi_status status;
261
262
263 ACPI_FUNCTION_TRACE ("acpi_install_notify_handler");
264
265
266
267
268 if ((!device) ||
269 (!handler) ||
270 (handler_type > ACPI_MAX_NOTIFY_HANDLER_TYPE)) {
271 return_ACPI_STATUS (AE_BAD_PARAMETER);
272 }
273
274 status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
275 if (ACPI_FAILURE (status)) {
276 return_ACPI_STATUS (status);
277 }
278
279
280
281 node = acpi_ns_map_handle_to_node (device);
282 if (!node) {
283 status = AE_BAD_PARAMETER;
284 goto unlock_and_exit;
285 }
286
287
288
289
290
291
292
293 if (device == ACPI_ROOT_OBJECT) {
294
295
296 if (((handler_type & ACPI_SYSTEM_NOTIFY) &&
297 acpi_gbl_system_notify.handler) ||
298 ((handler_type & ACPI_DEVICE_NOTIFY) &&
299 acpi_gbl_device_notify.handler)) {
300 status = AE_ALREADY_EXISTS;
301 goto unlock_and_exit;
302 }
303
304 if (handler_type & ACPI_SYSTEM_NOTIFY) {
305 acpi_gbl_system_notify.node = node;
306 acpi_gbl_system_notify.handler = handler;
307 acpi_gbl_system_notify.context = context;
308 }
309
310 if (handler_type & ACPI_DEVICE_NOTIFY) {
311 acpi_gbl_device_notify.node = node;
312 acpi_gbl_device_notify.handler = handler;
313 acpi_gbl_device_notify.context = context;
314 }
315
316
317 }
318
319
320
321
322
323
324 else {
325
326
327 if (!acpi_ev_is_notify_object (node)) {
328 status = AE_TYPE;
329 goto unlock_and_exit;
330 }
331
332
333
334 obj_desc = acpi_ns_get_attached_object (node);
335 if (obj_desc) {
336
337
338 if (((handler_type & ACPI_SYSTEM_NOTIFY) &&
339 obj_desc->common_notify.system_notify) ||
340 ((handler_type & ACPI_DEVICE_NOTIFY) &&
341 obj_desc->common_notify.device_notify)) {
342 status = AE_ALREADY_EXISTS;
343 goto unlock_and_exit;
344 }
345 }
346 else {
347
348
349 obj_desc = acpi_ut_create_internal_object (node->type);
350 if (!obj_desc) {
351 status = AE_NO_MEMORY;
352 goto unlock_and_exit;
353 }
354
355
356
357 status = acpi_ns_attach_object (device, obj_desc, node->type);
358
359
360
361 acpi_ut_remove_reference (obj_desc);
362 if (ACPI_FAILURE (status)) {
363 goto unlock_and_exit;
364 }
365 }
366
367
368
369 notify_obj = acpi_ut_create_internal_object (ACPI_TYPE_LOCAL_NOTIFY);
370 if (!notify_obj) {
371 status = AE_NO_MEMORY;
372 goto unlock_and_exit;
373 }
374
375 notify_obj->notify.node = node;
376 notify_obj->notify.handler = handler;
377 notify_obj->notify.context = context;
378
379 if (handler_type & ACPI_SYSTEM_NOTIFY) {
380 obj_desc->common_notify.system_notify = notify_obj;
381 }
382
383 if (handler_type & ACPI_DEVICE_NOTIFY) {
384 obj_desc->common_notify.device_notify = notify_obj;
385 }
386
387 if (handler_type == ACPI_ALL_NOTIFY) {
388
389
390 acpi_ut_add_reference (notify_obj);
391 }
392 }
393
394
395unlock_and_exit:
396 (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
397 return_ACPI_STATUS (status);
398}
399EXPORT_SYMBOL(acpi_install_notify_handler);
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419acpi_status
420acpi_remove_notify_handler (
421 acpi_handle device,
422 u32 handler_type,
423 acpi_notify_handler handler)
424{
425 union acpi_operand_object *notify_obj;
426 union acpi_operand_object *obj_desc;
427 struct acpi_namespace_node *node;
428 acpi_status status;
429
430
431 ACPI_FUNCTION_TRACE ("acpi_remove_notify_handler");
432
433
434
435
436 if ((!device) ||
437 (!handler) ||
438 (handler_type > ACPI_MAX_NOTIFY_HANDLER_TYPE)) {
439 return_ACPI_STATUS (AE_BAD_PARAMETER);
440 }
441
442 status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
443 if (ACPI_FAILURE (status)) {
444 return_ACPI_STATUS (status);
445 }
446
447
448
449 node = acpi_ns_map_handle_to_node (device);
450 if (!node) {
451 status = AE_BAD_PARAMETER;
452 goto unlock_and_exit;
453 }
454
455
456
457 if (device == ACPI_ROOT_OBJECT) {
458 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Removing notify handler for ROOT object.\n"));
459
460 if (((handler_type & ACPI_SYSTEM_NOTIFY) &&
461 !acpi_gbl_system_notify.handler) ||
462 ((handler_type & ACPI_DEVICE_NOTIFY) &&
463 !acpi_gbl_device_notify.handler)) {
464 status = AE_NOT_EXIST;
465 goto unlock_and_exit;
466 }
467
468
469
470 (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
471 acpi_os_wait_events_complete(NULL);
472 status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
473 if (ACPI_FAILURE (status)) {
474 return_ACPI_STATUS (status);
475 }
476
477 if (handler_type & ACPI_SYSTEM_NOTIFY) {
478 acpi_gbl_system_notify.node = NULL;
479 acpi_gbl_system_notify.handler = NULL;
480 acpi_gbl_system_notify.context = NULL;
481 }
482
483 if (handler_type & ACPI_DEVICE_NOTIFY) {
484 acpi_gbl_device_notify.node = NULL;
485 acpi_gbl_device_notify.handler = NULL;
486 acpi_gbl_device_notify.context = NULL;
487 }
488 }
489
490
491
492 else {
493
494
495 if (!acpi_ev_is_notify_object (node)) {
496 status = AE_TYPE;
497 goto unlock_and_exit;
498 }
499
500
501
502 obj_desc = acpi_ns_get_attached_object (node);
503 if (!obj_desc) {
504 status = AE_NOT_EXIST;
505 goto unlock_and_exit;
506 }
507
508
509
510 if (handler_type & ACPI_SYSTEM_NOTIFY) {
511 notify_obj = obj_desc->common_notify.system_notify;
512 if ((!notify_obj) ||
513 (notify_obj->notify.handler != handler)) {
514 status = AE_BAD_PARAMETER;
515 goto unlock_and_exit;
516 }
517
518
519 (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
520 acpi_os_wait_events_complete(NULL);
521 status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
522 if (ACPI_FAILURE (status)) {
523 return_ACPI_STATUS (status);
524 }
525
526
527 obj_desc->common_notify.system_notify = NULL;
528 acpi_ut_remove_reference (notify_obj);
529 }
530
531 if (handler_type & ACPI_DEVICE_NOTIFY) {
532 notify_obj = obj_desc->common_notify.device_notify;
533 if ((!notify_obj) ||
534 (notify_obj->notify.handler != handler)) {
535 status = AE_BAD_PARAMETER;
536 goto unlock_and_exit;
537 }
538
539
540 (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
541 acpi_os_wait_events_complete(NULL);
542 status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
543 if (ACPI_FAILURE (status)) {
544 return_ACPI_STATUS (status);
545 }
546
547
548 obj_desc->common_notify.device_notify = NULL;
549 acpi_ut_remove_reference (notify_obj);
550 }
551 }
552
553
554unlock_and_exit:
555 (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
556 return_ACPI_STATUS (status);
557}
558EXPORT_SYMBOL(acpi_remove_notify_handler);
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578acpi_status
579acpi_install_gpe_handler (
580 acpi_handle gpe_device,
581 u32 gpe_number,
582 u32 type,
583 acpi_event_handler address,
584 void *context)
585{
586 struct acpi_gpe_event_info *gpe_event_info;
587 struct acpi_handler_info *handler;
588 acpi_status status;
589
590
591 ACPI_FUNCTION_TRACE ("acpi_install_gpe_handler");
592
593
594
595
596 if ((!address) || (type > ACPI_GPE_XRUPT_TYPE_MASK)) {
597 return_ACPI_STATUS (AE_BAD_PARAMETER);
598 }
599
600 status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
601 if (ACPI_FAILURE (status)) {
602 return_ACPI_STATUS (status);
603 }
604
605
606
607 gpe_event_info = acpi_ev_get_gpe_event_info (gpe_device, gpe_number);
608 if (!gpe_event_info) {
609 status = AE_BAD_PARAMETER;
610 goto unlock_and_exit;
611 }
612
613
614
615 if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) == ACPI_GPE_DISPATCH_HANDLER) {
616 status = AE_ALREADY_EXISTS;
617 goto unlock_and_exit;
618 }
619
620
621
622 handler = ACPI_MEM_CALLOCATE (sizeof (struct acpi_handler_info));
623 if (!handler) {
624 status = AE_NO_MEMORY;
625 goto unlock_and_exit;
626 }
627
628 handler->address = address;
629 handler->context = context;
630 handler->method_node = gpe_event_info->dispatch.method_node;
631
632
633
634 status = acpi_ev_disable_gpe (gpe_event_info);
635 if (ACPI_FAILURE (status)) {
636 goto unlock_and_exit;
637 }
638
639
640
641 acpi_os_acquire_lock (acpi_gbl_gpe_lock, ACPI_NOT_ISR);
642 gpe_event_info->dispatch.handler = handler;
643
644
645
646 gpe_event_info->flags &= ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK);
647 gpe_event_info->flags |= (u8) (type | ACPI_GPE_DISPATCH_HANDLER);
648
649 acpi_os_release_lock (acpi_gbl_gpe_lock, ACPI_NOT_ISR);
650
651
652unlock_and_exit:
653 (void) acpi_ut_release_mutex (ACPI_MTX_EVENTS);
654 return_ACPI_STATUS (status);
655}
656EXPORT_SYMBOL(acpi_install_gpe_handler);
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673acpi_status
674acpi_remove_gpe_handler (
675 acpi_handle gpe_device,
676 u32 gpe_number,
677 acpi_event_handler address)
678{
679 struct acpi_gpe_event_info *gpe_event_info;
680 struct acpi_handler_info *handler;
681 acpi_status status;
682
683
684 ACPI_FUNCTION_TRACE ("acpi_remove_gpe_handler");
685
686
687
688
689 if (!address) {
690 return_ACPI_STATUS (AE_BAD_PARAMETER);
691 }
692
693 status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
694 if (ACPI_FAILURE (status)) {
695 return_ACPI_STATUS (status);
696 }
697
698
699
700 gpe_event_info = acpi_ev_get_gpe_event_info (gpe_device, gpe_number);
701 if (!gpe_event_info) {
702 status = AE_BAD_PARAMETER;
703 goto unlock_and_exit;
704 }
705
706
707
708 if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) != ACPI_GPE_DISPATCH_HANDLER) {
709 status = AE_NOT_EXIST;
710 goto unlock_and_exit;
711 }
712
713
714
715 if (gpe_event_info->dispatch.handler->address != address) {
716 status = AE_BAD_PARAMETER;
717 goto unlock_and_exit;
718 }
719
720
721
722 status = acpi_ev_disable_gpe (gpe_event_info);
723 if (ACPI_FAILURE (status)) {
724 goto unlock_and_exit;
725 }
726
727
728
729 (void) acpi_ut_release_mutex (ACPI_MTX_EVENTS);
730 acpi_os_wait_events_complete(NULL);
731 status = acpi_ut_acquire_mutex (ACPI_MTX_EVENTS);
732 if (ACPI_FAILURE (status)) {
733 return_ACPI_STATUS (status);
734 }
735
736
737
738 acpi_os_acquire_lock (acpi_gbl_gpe_lock, ACPI_NOT_ISR);
739 handler = gpe_event_info->dispatch.handler;
740
741
742
743 gpe_event_info->dispatch.method_node = handler->method_node;
744 gpe_event_info->flags &= ~ACPI_GPE_DISPATCH_MASK;
745 if (handler->method_node) {
746 gpe_event_info->flags |= ACPI_GPE_DISPATCH_METHOD;
747 }
748 acpi_os_release_lock (acpi_gbl_gpe_lock, ACPI_NOT_ISR);
749
750
751
752 ACPI_MEM_FREE (handler);
753
754
755unlock_and_exit:
756 (void) acpi_ut_release_mutex (ACPI_MTX_EVENTS);
757 return_ACPI_STATUS (status);
758}
759EXPORT_SYMBOL(acpi_remove_gpe_handler);
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775acpi_status
776acpi_acquire_global_lock (
777 u16 timeout,
778 u32 *handle)
779{
780 acpi_status status;
781
782
783 if (!handle) {
784 return (AE_BAD_PARAMETER);
785 }
786
787 status = acpi_ex_enter_interpreter ();
788 if (ACPI_FAILURE (status)) {
789 return (status);
790 }
791
792 status = acpi_ev_acquire_global_lock (timeout);
793 acpi_ex_exit_interpreter ();
794
795 if (ACPI_SUCCESS (status)) {
796 acpi_gbl_global_lock_handle++;
797 *handle = acpi_gbl_global_lock_handle;
798 }
799
800 return (status);
801}
802EXPORT_SYMBOL(acpi_acquire_global_lock);
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817acpi_status
818acpi_release_global_lock (
819 u32 handle)
820{
821 acpi_status status;
822
823
824 if (handle != acpi_gbl_global_lock_handle) {
825 return (AE_NOT_ACQUIRED);
826 }
827
828 status = acpi_ev_release_global_lock ();
829 return (status);
830}
831EXPORT_SYMBOL(acpi_release_global_lock);
832
833