0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #define EXPORT_ACPI_INTERFACES
0011
0012 #include <acpi/acpi.h>
0013 #include "accommon.h"
0014 #include "acnamesp.h"
0015 #include "acevents.h"
0016 #include "acinterp.h"
0017
0018 #define _COMPONENT ACPI_EVENTS
0019 ACPI_MODULE_NAME("evxface")
0020 #if (!ACPI_REDUCED_HARDWARE)
0021
0022 static acpi_status
0023 acpi_ev_install_gpe_handler(acpi_handle gpe_device,
0024 u32 gpe_number,
0025 u32 type,
0026 u8 is_raw_handler,
0027 acpi_gpe_handler address, void *context);
0028
0029 #endif
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056 acpi_status
0057 acpi_install_notify_handler(acpi_handle device,
0058 u32 handler_type,
0059 acpi_notify_handler handler, void *context)
0060 {
0061 struct acpi_namespace_node *node =
0062 ACPI_CAST_PTR(struct acpi_namespace_node, device);
0063 union acpi_operand_object *obj_desc;
0064 union acpi_operand_object *handler_obj;
0065 acpi_status status;
0066 u32 i;
0067
0068 ACPI_FUNCTION_TRACE(acpi_install_notify_handler);
0069
0070
0071
0072 if ((!device) || (!handler) || (!handler_type) ||
0073 (handler_type > ACPI_MAX_NOTIFY_HANDLER_TYPE)) {
0074 return_ACPI_STATUS(AE_BAD_PARAMETER);
0075 }
0076
0077 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
0078 if (ACPI_FAILURE(status)) {
0079 return_ACPI_STATUS(status);
0080 }
0081
0082
0083
0084
0085
0086
0087
0088
0089 if (device == ACPI_ROOT_OBJECT) {
0090 for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) {
0091 if (handler_type & (i + 1)) {
0092 if (acpi_gbl_global_notify[i].handler) {
0093 status = AE_ALREADY_EXISTS;
0094 goto unlock_and_exit;
0095 }
0096
0097 acpi_gbl_global_notify[i].handler = handler;
0098 acpi_gbl_global_notify[i].context = context;
0099 }
0100 }
0101
0102 goto unlock_and_exit;
0103 }
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114 if (!acpi_ev_is_notify_object(node)) {
0115 status = AE_TYPE;
0116 goto unlock_and_exit;
0117 }
0118
0119
0120
0121 obj_desc = acpi_ns_get_attached_object(node);
0122 if (!obj_desc) {
0123
0124
0125
0126 obj_desc = acpi_ut_create_internal_object(node->type);
0127 if (!obj_desc) {
0128 status = AE_NO_MEMORY;
0129 goto unlock_and_exit;
0130 }
0131
0132
0133
0134 status = acpi_ns_attach_object(device, obj_desc, node->type);
0135 acpi_ut_remove_reference(obj_desc);
0136 if (ACPI_FAILURE(status)) {
0137 goto unlock_and_exit;
0138 }
0139 }
0140
0141
0142
0143 for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) {
0144 if (handler_type & (i + 1)) {
0145 handler_obj = obj_desc->common_notify.notify_list[i];
0146 while (handler_obj) {
0147 if (handler_obj->notify.handler == handler) {
0148 status = AE_ALREADY_EXISTS;
0149 goto unlock_and_exit;
0150 }
0151
0152 handler_obj = handler_obj->notify.next[i];
0153 }
0154 }
0155 }
0156
0157
0158
0159 handler_obj = acpi_ut_create_internal_object(ACPI_TYPE_LOCAL_NOTIFY);
0160 if (!handler_obj) {
0161 status = AE_NO_MEMORY;
0162 goto unlock_and_exit;
0163 }
0164
0165 handler_obj->notify.node = node;
0166 handler_obj->notify.handler_type = handler_type;
0167 handler_obj->notify.handler = handler;
0168 handler_obj->notify.context = context;
0169
0170
0171
0172 for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) {
0173 if (handler_type & (i + 1)) {
0174 handler_obj->notify.next[i] =
0175 obj_desc->common_notify.notify_list[i];
0176
0177 obj_desc->common_notify.notify_list[i] = handler_obj;
0178 }
0179 }
0180
0181
0182
0183 if (handler_type == ACPI_ALL_NOTIFY) {
0184 acpi_ut_add_reference(handler_obj);
0185 }
0186
0187 unlock_and_exit:
0188 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
0189 return_ACPI_STATUS(status);
0190 }
0191
0192 ACPI_EXPORT_SYMBOL(acpi_install_notify_handler)
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210 acpi_status
0211 acpi_remove_notify_handler(acpi_handle device,
0212 u32 handler_type, acpi_notify_handler handler)
0213 {
0214 struct acpi_namespace_node *node =
0215 ACPI_CAST_PTR(struct acpi_namespace_node, device);
0216 union acpi_operand_object *obj_desc;
0217 union acpi_operand_object *handler_obj;
0218 union acpi_operand_object *previous_handler_obj;
0219 acpi_status status = AE_OK;
0220 u32 i;
0221
0222 ACPI_FUNCTION_TRACE(acpi_remove_notify_handler);
0223
0224
0225
0226 if ((!device) || (!handler) || (!handler_type) ||
0227 (handler_type > ACPI_MAX_NOTIFY_HANDLER_TYPE)) {
0228 return_ACPI_STATUS(AE_BAD_PARAMETER);
0229 }
0230
0231
0232
0233 if (device == ACPI_ROOT_OBJECT) {
0234 for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) {
0235 if (handler_type & (i + 1)) {
0236 status =
0237 acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
0238 if (ACPI_FAILURE(status)) {
0239 return_ACPI_STATUS(status);
0240 }
0241
0242 if (!acpi_gbl_global_notify[i].handler ||
0243 (acpi_gbl_global_notify[i].handler !=
0244 handler)) {
0245 status = AE_NOT_EXIST;
0246 goto unlock_and_exit;
0247 }
0248
0249 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
0250 "Removing global notify handler\n"));
0251
0252 acpi_gbl_global_notify[i].handler = NULL;
0253 acpi_gbl_global_notify[i].context = NULL;
0254
0255 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
0256
0257
0258
0259 acpi_os_wait_events_complete();
0260 }
0261 }
0262
0263 return_ACPI_STATUS(AE_OK);
0264 }
0265
0266
0267
0268 if (!acpi_ev_is_notify_object(node)) {
0269 return_ACPI_STATUS(AE_TYPE);
0270 }
0271
0272
0273
0274 obj_desc = acpi_ns_get_attached_object(node);
0275 if (!obj_desc) {
0276 return_ACPI_STATUS(AE_NOT_EXIST);
0277 }
0278
0279
0280
0281 for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) {
0282 if (handler_type & (i + 1)) {
0283 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
0284 if (ACPI_FAILURE(status)) {
0285 return_ACPI_STATUS(status);
0286 }
0287
0288 handler_obj = obj_desc->common_notify.notify_list[i];
0289 previous_handler_obj = NULL;
0290
0291
0292
0293 while (handler_obj &&
0294 (handler_obj->notify.handler != handler)) {
0295 previous_handler_obj = handler_obj;
0296 handler_obj = handler_obj->notify.next[i];
0297 }
0298
0299 if (!handler_obj) {
0300 status = AE_NOT_EXIST;
0301 goto unlock_and_exit;
0302 }
0303
0304
0305
0306 if (previous_handler_obj) {
0307 previous_handler_obj->notify.next[i] =
0308 handler_obj->notify.next[i];
0309 } else {
0310
0311 obj_desc->common_notify.notify_list[i] =
0312 handler_obj->notify.next[i];
0313 }
0314
0315 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
0316
0317
0318
0319 acpi_os_wait_events_complete();
0320 acpi_ut_remove_reference(handler_obj);
0321 }
0322 }
0323
0324 return_ACPI_STATUS(status);
0325
0326 unlock_and_exit:
0327 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
0328 return_ACPI_STATUS(status);
0329 }
0330
0331 ACPI_EXPORT_SYMBOL(acpi_remove_notify_handler)
0332
0333
0334
0335
0336
0337
0338
0339
0340
0341
0342
0343
0344
0345 #ifdef ACPI_FUTURE_USAGE
0346 acpi_status acpi_install_exception_handler(acpi_exception_handler handler)
0347 {
0348 acpi_status status;
0349
0350 ACPI_FUNCTION_TRACE(acpi_install_exception_handler);
0351
0352 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
0353 if (ACPI_FAILURE(status)) {
0354 return_ACPI_STATUS(status);
0355 }
0356
0357
0358
0359 if (acpi_gbl_exception_handler) {
0360 status = AE_ALREADY_EXISTS;
0361 goto cleanup;
0362 }
0363
0364
0365
0366 acpi_gbl_exception_handler = handler;
0367
0368 cleanup:
0369 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
0370 return_ACPI_STATUS(status);
0371 }
0372
0373 ACPI_EXPORT_SYMBOL(acpi_install_exception_handler)
0374 #endif
0375
0376 #if (!ACPI_REDUCED_HARDWARE)
0377
0378
0379
0380
0381
0382
0383
0384
0385
0386
0387
0388
0389 acpi_status acpi_install_sci_handler(acpi_sci_handler address, void *context)
0390 {
0391 struct acpi_sci_handler_info *new_sci_handler;
0392 struct acpi_sci_handler_info *sci_handler;
0393 acpi_cpu_flags flags;
0394 acpi_status status;
0395
0396 ACPI_FUNCTION_TRACE(acpi_install_sci_handler);
0397
0398 if (!address) {
0399 return_ACPI_STATUS(AE_BAD_PARAMETER);
0400 }
0401
0402
0403
0404 new_sci_handler = ACPI_ALLOCATE(sizeof(struct acpi_sci_handler_info));
0405 if (!new_sci_handler) {
0406 return_ACPI_STATUS(AE_NO_MEMORY);
0407 }
0408
0409 new_sci_handler->address = address;
0410 new_sci_handler->context = context;
0411
0412 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
0413 if (ACPI_FAILURE(status)) {
0414 goto exit;
0415 }
0416
0417
0418
0419 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
0420 sci_handler = acpi_gbl_sci_handler_list;
0421
0422
0423
0424 while (sci_handler) {
0425 if (address == sci_handler->address) {
0426 status = AE_ALREADY_EXISTS;
0427 goto unlock_and_exit;
0428 }
0429
0430 sci_handler = sci_handler->next;
0431 }
0432
0433
0434
0435 new_sci_handler->next = acpi_gbl_sci_handler_list;
0436 acpi_gbl_sci_handler_list = new_sci_handler;
0437
0438 unlock_and_exit:
0439
0440 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
0441 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
0442
0443 exit:
0444 if (ACPI_FAILURE(status)) {
0445 ACPI_FREE(new_sci_handler);
0446 }
0447 return_ACPI_STATUS(status);
0448 }
0449
0450 ACPI_EXPORT_SYMBOL(acpi_install_sci_handler)
0451
0452
0453
0454
0455
0456
0457
0458
0459
0460
0461
0462
0463 acpi_status acpi_remove_sci_handler(acpi_sci_handler address)
0464 {
0465 struct acpi_sci_handler_info *prev_sci_handler;
0466 struct acpi_sci_handler_info *next_sci_handler;
0467 acpi_cpu_flags flags;
0468 acpi_status status;
0469
0470 ACPI_FUNCTION_TRACE(acpi_remove_sci_handler);
0471
0472 if (!address) {
0473 return_ACPI_STATUS(AE_BAD_PARAMETER);
0474 }
0475
0476 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
0477 if (ACPI_FAILURE(status)) {
0478 return_ACPI_STATUS(status);
0479 }
0480
0481
0482
0483 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
0484
0485 prev_sci_handler = NULL;
0486 next_sci_handler = acpi_gbl_sci_handler_list;
0487 while (next_sci_handler) {
0488 if (next_sci_handler->address == address) {
0489
0490
0491
0492 if (prev_sci_handler) {
0493 prev_sci_handler->next = next_sci_handler->next;
0494 } else {
0495 acpi_gbl_sci_handler_list =
0496 next_sci_handler->next;
0497 }
0498
0499 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
0500 ACPI_FREE(next_sci_handler);
0501 goto unlock_and_exit;
0502 }
0503
0504 prev_sci_handler = next_sci_handler;
0505 next_sci_handler = next_sci_handler->next;
0506 }
0507
0508 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
0509 status = AE_NOT_EXIST;
0510
0511 unlock_and_exit:
0512 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
0513 return_ACPI_STATUS(status);
0514 }
0515
0516 ACPI_EXPORT_SYMBOL(acpi_remove_sci_handler)
0517
0518
0519
0520
0521
0522
0523
0524
0525
0526
0527
0528
0529
0530
0531
0532
0533 acpi_status
0534 acpi_install_global_event_handler(acpi_gbl_event_handler handler, void *context)
0535 {
0536 acpi_status status;
0537
0538 ACPI_FUNCTION_TRACE(acpi_install_global_event_handler);
0539
0540
0541
0542 if (!handler) {
0543 return_ACPI_STATUS(AE_BAD_PARAMETER);
0544 }
0545
0546 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
0547 if (ACPI_FAILURE(status)) {
0548 return_ACPI_STATUS(status);
0549 }
0550
0551
0552
0553 if (acpi_gbl_global_event_handler) {
0554 status = AE_ALREADY_EXISTS;
0555 goto cleanup;
0556 }
0557
0558 acpi_gbl_global_event_handler = handler;
0559 acpi_gbl_global_event_handler_context = context;
0560
0561 cleanup:
0562 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
0563 return_ACPI_STATUS(status);
0564 }
0565
0566 ACPI_EXPORT_SYMBOL(acpi_install_global_event_handler)
0567
0568
0569
0570
0571
0572
0573
0574
0575
0576
0577
0578
0579
0580
0581
0582
0583 acpi_status
0584 acpi_install_fixed_event_handler(u32 event,
0585 acpi_event_handler handler, void *context)
0586 {
0587 acpi_status status;
0588
0589 ACPI_FUNCTION_TRACE(acpi_install_fixed_event_handler);
0590
0591
0592
0593 if (event > ACPI_EVENT_MAX) {
0594 return_ACPI_STATUS(AE_BAD_PARAMETER);
0595 }
0596
0597 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
0598 if (ACPI_FAILURE(status)) {
0599 return_ACPI_STATUS(status);
0600 }
0601
0602
0603
0604 if (acpi_gbl_fixed_event_handlers[event].handler) {
0605 status = AE_ALREADY_EXISTS;
0606 goto cleanup;
0607 }
0608
0609
0610
0611 acpi_gbl_fixed_event_handlers[event].handler = handler;
0612 acpi_gbl_fixed_event_handlers[event].context = context;
0613
0614 status = acpi_clear_event(event);
0615 if (ACPI_SUCCESS(status))
0616 status = acpi_enable_event(event, 0);
0617 if (ACPI_FAILURE(status)) {
0618 ACPI_WARNING((AE_INFO,
0619 "Could not enable fixed event - %s (%u)",
0620 acpi_ut_get_event_name(event), event));
0621
0622
0623
0624 acpi_gbl_fixed_event_handlers[event].handler = NULL;
0625 acpi_gbl_fixed_event_handlers[event].context = NULL;
0626 } else {
0627 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
0628 "Enabled fixed event %s (%X), Handler=%p\n",
0629 acpi_ut_get_event_name(event), event,
0630 handler));
0631 }
0632
0633 cleanup:
0634 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
0635 return_ACPI_STATUS(status);
0636 }
0637
0638 ACPI_EXPORT_SYMBOL(acpi_install_fixed_event_handler)
0639
0640
0641
0642
0643
0644
0645
0646
0647
0648
0649
0650
0651
0652 acpi_status
0653 acpi_remove_fixed_event_handler(u32 event, acpi_event_handler handler)
0654 {
0655 acpi_status status = AE_OK;
0656
0657 ACPI_FUNCTION_TRACE(acpi_remove_fixed_event_handler);
0658
0659
0660
0661 if (event > ACPI_EVENT_MAX) {
0662 return_ACPI_STATUS(AE_BAD_PARAMETER);
0663 }
0664
0665 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
0666 if (ACPI_FAILURE(status)) {
0667 return_ACPI_STATUS(status);
0668 }
0669
0670
0671
0672 status = acpi_disable_event(event, 0);
0673
0674
0675
0676 acpi_gbl_fixed_event_handlers[event].handler = NULL;
0677 acpi_gbl_fixed_event_handlers[event].context = NULL;
0678
0679 if (ACPI_FAILURE(status)) {
0680 ACPI_WARNING((AE_INFO,
0681 "Could not disable fixed event - %s (%u)",
0682 acpi_ut_get_event_name(event), event));
0683 } else {
0684 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
0685 "Disabled fixed event - %s (%X)\n",
0686 acpi_ut_get_event_name(event), event));
0687 }
0688
0689 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
0690 return_ACPI_STATUS(status);
0691 }
0692
0693 ACPI_EXPORT_SYMBOL(acpi_remove_fixed_event_handler)
0694
0695
0696
0697
0698
0699
0700
0701
0702
0703
0704
0705
0706
0707
0708
0709
0710
0711
0712
0713
0714
0715 static acpi_status
0716 acpi_ev_install_gpe_handler(acpi_handle gpe_device,
0717 u32 gpe_number,
0718 u32 type,
0719 u8 is_raw_handler,
0720 acpi_gpe_handler address, void *context)
0721 {
0722 struct acpi_gpe_event_info *gpe_event_info;
0723 struct acpi_gpe_handler_info *handler;
0724 acpi_status status;
0725 acpi_cpu_flags flags;
0726
0727 ACPI_FUNCTION_TRACE(ev_install_gpe_handler);
0728
0729
0730
0731 if ((!address) || (type & ~ACPI_GPE_XRUPT_TYPE_MASK)) {
0732 return_ACPI_STATUS(AE_BAD_PARAMETER);
0733 }
0734
0735 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
0736 if (ACPI_FAILURE(status)) {
0737 return_ACPI_STATUS(status);
0738 }
0739
0740
0741
0742 handler = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_gpe_handler_info));
0743 if (!handler) {
0744 status = AE_NO_MEMORY;
0745 goto unlock_and_exit;
0746 }
0747
0748 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
0749
0750
0751
0752 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
0753 if (!gpe_event_info) {
0754 status = AE_BAD_PARAMETER;
0755 goto free_and_exit;
0756 }
0757
0758
0759
0760 if ((ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) ==
0761 ACPI_GPE_DISPATCH_HANDLER) ||
0762 (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) ==
0763 ACPI_GPE_DISPATCH_RAW_HANDLER)) {
0764 status = AE_ALREADY_EXISTS;
0765 goto free_and_exit;
0766 }
0767
0768 handler->address = address;
0769 handler->context = context;
0770 handler->method_node = gpe_event_info->dispatch.method_node;
0771 handler->original_flags = (u8)(gpe_event_info->flags &
0772 (ACPI_GPE_XRUPT_TYPE_MASK |
0773 ACPI_GPE_DISPATCH_MASK));
0774
0775
0776
0777
0778
0779
0780 if (((ACPI_GPE_DISPATCH_TYPE(handler->original_flags) ==
0781 ACPI_GPE_DISPATCH_METHOD) ||
0782 (ACPI_GPE_DISPATCH_TYPE(handler->original_flags) ==
0783 ACPI_GPE_DISPATCH_NOTIFY)) && gpe_event_info->runtime_count) {
0784 handler->originally_enabled = TRUE;
0785 (void)acpi_ev_remove_gpe_reference(gpe_event_info);
0786
0787
0788
0789 if (type !=
0790 (u32)(gpe_event_info->flags & ACPI_GPE_XRUPT_TYPE_MASK)) {
0791 ACPI_WARNING((AE_INFO,
0792 "GPE type mismatch (level/edge)"));
0793 }
0794 }
0795
0796
0797
0798 gpe_event_info->dispatch.handler = handler;
0799
0800
0801
0802 gpe_event_info->flags &=
0803 ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK);
0804 gpe_event_info->flags |=
0805 (u8)(type |
0806 (is_raw_handler ? ACPI_GPE_DISPATCH_RAW_HANDLER :
0807 ACPI_GPE_DISPATCH_HANDLER));
0808
0809 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
0810
0811 unlock_and_exit:
0812 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
0813 return_ACPI_STATUS(status);
0814
0815 free_and_exit:
0816 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
0817 ACPI_FREE(handler);
0818 goto unlock_and_exit;
0819 }
0820
0821
0822
0823
0824
0825
0826
0827
0828
0829
0830
0831
0832
0833
0834
0835
0836
0837
0838
0839 acpi_status
0840 acpi_install_gpe_handler(acpi_handle gpe_device,
0841 u32 gpe_number,
0842 u32 type, acpi_gpe_handler address, void *context)
0843 {
0844 acpi_status status;
0845
0846 ACPI_FUNCTION_TRACE(acpi_install_gpe_handler);
0847
0848 status = acpi_ev_install_gpe_handler(gpe_device, gpe_number, type,
0849 FALSE, address, context);
0850
0851 return_ACPI_STATUS(status);
0852 }
0853
0854 ACPI_EXPORT_SYMBOL(acpi_install_gpe_handler)
0855
0856
0857
0858
0859
0860
0861
0862
0863
0864
0865
0866
0867
0868
0869
0870
0871
0872
0873 acpi_status
0874 acpi_install_gpe_raw_handler(acpi_handle gpe_device,
0875 u32 gpe_number,
0876 u32 type, acpi_gpe_handler address, void *context)
0877 {
0878 acpi_status status;
0879
0880 ACPI_FUNCTION_TRACE(acpi_install_gpe_raw_handler);
0881
0882 status = acpi_ev_install_gpe_handler(gpe_device, gpe_number, type,
0883 TRUE, address, context);
0884
0885 return_ACPI_STATUS(status);
0886 }
0887
0888 ACPI_EXPORT_SYMBOL(acpi_install_gpe_raw_handler)
0889
0890
0891
0892
0893
0894
0895
0896
0897
0898
0899
0900
0901
0902
0903
0904 acpi_status
0905 acpi_remove_gpe_handler(acpi_handle gpe_device,
0906 u32 gpe_number, acpi_gpe_handler address)
0907 {
0908 struct acpi_gpe_event_info *gpe_event_info;
0909 struct acpi_gpe_handler_info *handler;
0910 acpi_status status;
0911 acpi_cpu_flags flags;
0912
0913 ACPI_FUNCTION_TRACE(acpi_remove_gpe_handler);
0914
0915
0916
0917 if (!address) {
0918 return_ACPI_STATUS(AE_BAD_PARAMETER);
0919 }
0920
0921 status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
0922 if (ACPI_FAILURE(status)) {
0923 return_ACPI_STATUS(status);
0924 }
0925
0926 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
0927
0928
0929
0930 gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
0931 if (!gpe_event_info) {
0932 status = AE_BAD_PARAMETER;
0933 goto unlock_and_exit;
0934 }
0935
0936
0937
0938 if ((ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) !=
0939 ACPI_GPE_DISPATCH_HANDLER) &&
0940 (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) !=
0941 ACPI_GPE_DISPATCH_RAW_HANDLER)) {
0942 status = AE_NOT_EXIST;
0943 goto unlock_and_exit;
0944 }
0945
0946
0947
0948 if (gpe_event_info->dispatch.handler->address != address) {
0949 status = AE_BAD_PARAMETER;
0950 goto unlock_and_exit;
0951 }
0952
0953
0954
0955 handler = gpe_event_info->dispatch.handler;
0956 gpe_event_info->dispatch.handler = NULL;
0957
0958
0959
0960 gpe_event_info->dispatch.method_node = handler->method_node;
0961 gpe_event_info->flags &=
0962 ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK);
0963 gpe_event_info->flags |= handler->original_flags;
0964
0965
0966
0967
0968
0969
0970 if (((ACPI_GPE_DISPATCH_TYPE(handler->original_flags) ==
0971 ACPI_GPE_DISPATCH_METHOD) ||
0972 (ACPI_GPE_DISPATCH_TYPE(handler->original_flags) ==
0973 ACPI_GPE_DISPATCH_NOTIFY)) && handler->originally_enabled) {
0974 (void)acpi_ev_add_gpe_reference(gpe_event_info, FALSE);
0975 if (ACPI_GPE_IS_POLLING_NEEDED(gpe_event_info)) {
0976
0977
0978
0979 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
0980 (void)acpi_ev_detect_gpe(gpe_device, gpe_event_info,
0981 gpe_number);
0982 flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
0983 }
0984 }
0985
0986 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
0987 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
0988
0989
0990
0991 acpi_os_wait_events_complete();
0992
0993
0994
0995 ACPI_FREE(handler);
0996 return_ACPI_STATUS(status);
0997
0998 unlock_and_exit:
0999 acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
1000
1001 (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
1002 return_ACPI_STATUS(status);
1003 }
1004
1005 ACPI_EXPORT_SYMBOL(acpi_remove_gpe_handler)
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026 acpi_status acpi_acquire_global_lock(u16 timeout, u32 *handle)
1027 {
1028 acpi_status status;
1029
1030 if (!handle) {
1031 return (AE_BAD_PARAMETER);
1032 }
1033
1034
1035
1036 acpi_ex_enter_interpreter();
1037
1038 status = acpi_ex_acquire_mutex_object(timeout,
1039 acpi_gbl_global_lock_mutex,
1040 acpi_os_get_thread_id());
1041
1042 if (ACPI_SUCCESS(status)) {
1043
1044
1045
1046 *handle = acpi_gbl_global_lock_handle;
1047 }
1048
1049 acpi_ex_exit_interpreter();
1050 return (status);
1051 }
1052
1053 ACPI_EXPORT_SYMBOL(acpi_acquire_global_lock)
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066 acpi_status acpi_release_global_lock(u32 handle)
1067 {
1068 acpi_status status;
1069
1070 if (!handle || (handle != acpi_gbl_global_lock_handle)) {
1071 return (AE_NOT_ACQUIRED);
1072 }
1073
1074 status = acpi_ex_release_mutex_object(acpi_gbl_global_lock_mutex);
1075 return (status);
1076 }
1077
1078 ACPI_EXPORT_SYMBOL(acpi_release_global_lock)
1079 #endif