Warning, cross-references for /kernel/drivers/acpica/evgpeblk.c need to be fixed.
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
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
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116 #include "acpi.h"
0117 #include "accommon.h"
0118 #include "acevents.h"
0119 #include "acnamesp.h"
0120
0121 #define _COMPONENT ACPI_EVENTS
0122 ACPI_MODULE_NAME ("evgpeblk")
0123
0124
0125
0126 static ACPI_STATUS
0127 AcpiEvSaveMethodInfo (
0128 ACPI_HANDLE ObjHandle,
0129 UINT32 Level,
0130 void *ObjDesc,
0131 void **ReturnValue);
0132
0133 static ACPI_STATUS
0134 AcpiEvMatchPrwAndGpe (
0135 ACPI_HANDLE ObjHandle,
0136 UINT32 Level,
0137 void *Info,
0138 void **ReturnValue);
0139
0140 static ACPI_GPE_XRUPT_INFO *
0141 AcpiEvGetGpeXruptBlock (
0142 UINT32 InterruptNumber);
0143
0144 static ACPI_STATUS
0145 AcpiEvDeleteGpeXrupt (
0146 ACPI_GPE_XRUPT_INFO *GpeXrupt);
0147
0148 static ACPI_STATUS
0149 AcpiEvInstallGpeBlock (
0150 ACPI_GPE_BLOCK_INFO *GpeBlock,
0151 UINT32 InterruptNumber);
0152
0153 static ACPI_STATUS
0154 AcpiEvCreateGpeInfoBlocks (
0155 ACPI_GPE_BLOCK_INFO *GpeBlock);
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172 BOOLEAN
0173 AcpiEvValidGpeEvent (
0174 ACPI_GPE_EVENT_INFO *GpeEventInfo)
0175 {
0176 ACPI_GPE_XRUPT_INFO *GpeXruptBlock;
0177 ACPI_GPE_BLOCK_INFO *GpeBlock;
0178
0179
0180 ACPI_FUNCTION_ENTRY ();
0181
0182
0183
0184
0185
0186
0187 GpeXruptBlock = AcpiGbl_GpeXruptListHead;
0188 while (GpeXruptBlock)
0189 {
0190 GpeBlock = GpeXruptBlock->GpeBlockListHead;
0191
0192
0193
0194 while (GpeBlock)
0195 {
0196 if ((&GpeBlock->EventInfo[0] <= GpeEventInfo) &&
0197 (&GpeBlock->EventInfo[((ACPI_SIZE)
0198 GpeBlock->RegisterCount) * 8] > GpeEventInfo))
0199 {
0200 return (TRUE);
0201 }
0202
0203 GpeBlock = GpeBlock->Next;
0204 }
0205
0206 GpeXruptBlock = GpeXruptBlock->Next;
0207 }
0208
0209 return (FALSE);
0210 }
0211
0212
0213
0214
0215
0216
0217
0218
0219
0220
0221
0222
0223
0224
0225
0226 ACPI_STATUS
0227 AcpiEvWalkGpeList (
0228 ACPI_GPE_CALLBACK GpeWalkCallback,
0229 void *Context)
0230 {
0231 ACPI_GPE_BLOCK_INFO *GpeBlock;
0232 ACPI_GPE_XRUPT_INFO *GpeXruptInfo;
0233 ACPI_STATUS Status = AE_OK;
0234 ACPI_CPU_FLAGS Flags;
0235
0236
0237 ACPI_FUNCTION_TRACE (EvWalkGpeList);
0238
0239
0240 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
0241
0242
0243
0244 GpeXruptInfo = AcpiGbl_GpeXruptListHead;
0245 while (GpeXruptInfo)
0246 {
0247
0248
0249 GpeBlock = GpeXruptInfo->GpeBlockListHead;
0250 while (GpeBlock)
0251 {
0252
0253
0254 Status = GpeWalkCallback (GpeXruptInfo, GpeBlock, Context);
0255 if (ACPI_FAILURE (Status))
0256 {
0257 if (Status == AE_CTRL_END)
0258 {
0259 Status = AE_OK;
0260 }
0261 goto UnlockAndExit;
0262 }
0263
0264 GpeBlock = GpeBlock->Next;
0265 }
0266
0267 GpeXruptInfo = GpeXruptInfo->Next;
0268 }
0269
0270 UnlockAndExit:
0271 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
0272 return_ACPI_STATUS (Status);
0273 }
0274
0275
0276
0277
0278
0279
0280
0281
0282
0283
0284
0285
0286
0287
0288
0289
0290 ACPI_STATUS
0291 AcpiEvDeleteGpeHandlers (
0292 ACPI_GPE_XRUPT_INFO *GpeXruptInfo,
0293 ACPI_GPE_BLOCK_INFO *GpeBlock,
0294 void *Context)
0295 {
0296 ACPI_GPE_EVENT_INFO *GpeEventInfo;
0297 UINT32 i;
0298 UINT32 j;
0299
0300
0301 ACPI_FUNCTION_TRACE (EvDeleteGpeHandlers);
0302
0303
0304
0305
0306 for (i = 0; i < GpeBlock->RegisterCount; i++)
0307 {
0308
0309
0310 for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++)
0311 {
0312 GpeEventInfo = &GpeBlock->EventInfo[((ACPI_SIZE) i *
0313 ACPI_GPE_REGISTER_WIDTH) + j];
0314
0315 if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) ==
0316 ACPI_GPE_DISPATCH_HANDLER)
0317 {
0318 ACPI_FREE (GpeEventInfo->Dispatch.Handler);
0319 GpeEventInfo->Dispatch.Handler = NULL;
0320 GpeEventInfo->Flags &= ~ACPI_GPE_DISPATCH_MASK;
0321 }
0322 }
0323 }
0324
0325 return_ACPI_STATUS (AE_OK);
0326 }
0327
0328
0329
0330
0331
0332
0333
0334
0335
0336
0337
0338
0339
0340
0341
0342
0343
0344
0345
0346
0347
0348
0349
0350
0351 static ACPI_STATUS
0352 AcpiEvSaveMethodInfo (
0353 ACPI_HANDLE ObjHandle,
0354 UINT32 Level,
0355 void *ObjDesc,
0356 void **ReturnValue)
0357 {
0358 ACPI_GPE_BLOCK_INFO *GpeBlock = (void *) ObjDesc;
0359 ACPI_GPE_EVENT_INFO *GpeEventInfo;
0360 UINT32 GpeNumber;
0361 char Name[ACPI_NAME_SIZE + 1];
0362 UINT8 Type;
0363 ACPI_STATUS Status;
0364
0365
0366 ACPI_FUNCTION_TRACE (EvSaveMethodInfo);
0367
0368
0369
0370
0371
0372
0373
0374 ACPI_MOVE_32_TO_32 (
0375 Name, &((ACPI_NAMESPACE_NODE *) ObjHandle)->Name.Integer);
0376 Name[ACPI_NAME_SIZE] = 0;
0377
0378
0379
0380
0381
0382
0383
0384
0385 switch (Name[1])
0386 {
0387 case 'L':
0388 Type = ACPI_GPE_LEVEL_TRIGGERED;
0389 break;
0390
0391 case 'E':
0392 Type = ACPI_GPE_EDGE_TRIGGERED;
0393 break;
0394
0395 default:
0396
0397
0398 ACPI_DEBUG_PRINT ((ACPI_DB_LOAD,
0399 "Ignoring unknown GPE method type: %s "
0400 "(name not of form _Lxx or _Exx)",
0401 Name));
0402 return_ACPI_STATUS (AE_OK);
0403 }
0404
0405
0406
0407 GpeNumber = ACPI_STRTOUL (&Name[2], NULL, 16);
0408 if (GpeNumber == ACPI_UINT32_MAX)
0409 {
0410
0411
0412 ACPI_DEBUG_PRINT ((ACPI_DB_LOAD,
0413 "Could not extract GPE number from name: %s "
0414 "(name is not of form _Lxx or _Exx)",
0415 Name));
0416 return_ACPI_STATUS (AE_OK);
0417 }
0418
0419
0420
0421 if ((GpeNumber < GpeBlock->BlockBaseNumber) ||
0422 (GpeNumber >= (GpeBlock->BlockBaseNumber +
0423 (GpeBlock->RegisterCount * 8))))
0424 {
0425
0426
0427
0428
0429
0430 return_ACPI_STATUS (AE_OK);
0431 }
0432
0433
0434
0435
0436
0437
0438 GpeEventInfo = &GpeBlock->EventInfo[GpeNumber - GpeBlock->BlockBaseNumber];
0439
0440 GpeEventInfo->Flags = (UINT8)
0441 (Type | ACPI_GPE_DISPATCH_METHOD | ACPI_GPE_TYPE_RUNTIME);
0442
0443 GpeEventInfo->Dispatch.MethodNode = (ACPI_NAMESPACE_NODE *) ObjHandle;
0444
0445
0446
0447 Status = AcpiEvEnableGpe (GpeEventInfo, FALSE);
0448
0449 ACPI_DEBUG_PRINT ((ACPI_DB_LOAD,
0450 "Registered GPE method %s as GPE number 0x%.2X\n",
0451 Name, GpeNumber));
0452 return_ACPI_STATUS (Status);
0453 }
0454
0455
0456
0457
0458
0459
0460
0461
0462
0463
0464
0465
0466
0467
0468
0469
0470
0471 static ACPI_STATUS
0472 AcpiEvMatchPrwAndGpe (
0473 ACPI_HANDLE ObjHandle,
0474 UINT32 Level,
0475 void *Info,
0476 void **ReturnValue)
0477 {
0478 ACPI_GPE_WALK_INFO *GpeInfo = (void *) Info;
0479 ACPI_NAMESPACE_NODE *GpeDevice;
0480 ACPI_GPE_BLOCK_INFO *GpeBlock;
0481 ACPI_NAMESPACE_NODE *TargetGpeDevice;
0482 ACPI_GPE_EVENT_INFO *GpeEventInfo;
0483 ACPI_OPERAND_OBJECT *PkgDesc;
0484 ACPI_OPERAND_OBJECT *ObjDesc;
0485 UINT32 GpeNumber;
0486 ACPI_STATUS Status;
0487
0488
0489 ACPI_FUNCTION_TRACE (EvMatchPrwAndGpe);
0490
0491
0492
0493
0494 Status = AcpiUtEvaluateObject (ObjHandle, METHOD_NAME__PRW,
0495 ACPI_BTYPE_PACKAGE, &PkgDesc);
0496 if (ACPI_FAILURE (Status))
0497 {
0498
0499
0500 return_ACPI_STATUS (AE_OK);
0501 }
0502
0503
0504
0505 if (PkgDesc->Package.Count < 2)
0506 {
0507 goto Cleanup;
0508 }
0509
0510
0511
0512 GpeDevice = GpeInfo->GpeDevice;
0513 GpeBlock = GpeInfo->GpeBlock;
0514
0515
0516
0517
0518
0519 ObjDesc = PkgDesc->Package.Elements[0];
0520
0521 if (ObjDesc->Common.Type == ACPI_TYPE_INTEGER)
0522 {
0523
0524
0525 TargetGpeDevice = AcpiGbl_FadtGpeDevice;
0526
0527
0528
0529 GpeNumber = (UINT32) ObjDesc->Integer.Value;
0530 }
0531 else if (ObjDesc->Common.Type == ACPI_TYPE_PACKAGE)
0532 {
0533
0534
0535 if ((ObjDesc->Package.Count < 2) ||
0536 ((ObjDesc->Package.Elements[0])->Common.Type !=
0537 ACPI_TYPE_LOCAL_REFERENCE) ||
0538 ((ObjDesc->Package.Elements[1])->Common.Type !=
0539 ACPI_TYPE_INTEGER))
0540 {
0541 goto Cleanup;
0542 }
0543
0544
0545
0546 TargetGpeDevice = ObjDesc->Package.Elements[0]->Reference.Node;
0547 GpeNumber = (UINT32) ObjDesc->Package.Elements[1]->Integer.Value;
0548 }
0549 else
0550 {
0551
0552
0553 goto Cleanup;
0554 }
0555
0556
0557
0558
0559
0560
0561
0562
0563
0564 if ((GpeDevice == TargetGpeDevice) &&
0565 (GpeNumber >= GpeBlock->BlockBaseNumber) &&
0566 (GpeNumber < GpeBlock->BlockBaseNumber +
0567 (GpeBlock->RegisterCount * 8)))
0568 {
0569 GpeEventInfo = &GpeBlock->EventInfo[GpeNumber -
0570 GpeBlock->BlockBaseNumber];
0571
0572
0573
0574 GpeEventInfo->Flags &= ~(ACPI_GPE_WAKE_ENABLED | ACPI_GPE_RUN_ENABLED);
0575
0576 Status = AcpiEvSetGpeType (GpeEventInfo, ACPI_GPE_TYPE_WAKE);
0577 if (ACPI_FAILURE (Status))
0578 {
0579 goto Cleanup;
0580 }
0581
0582 Status = AcpiEvUpdateGpeEnableMasks (GpeEventInfo, ACPI_GPE_DISABLE);
0583 }
0584
0585 Cleanup:
0586 AcpiUtRemoveReference (PkgDesc);
0587 return_ACPI_STATUS (AE_OK);
0588 }
0589
0590
0591
0592
0593
0594
0595
0596
0597
0598
0599
0600
0601
0602
0603
0604
0605
0606 static ACPI_GPE_XRUPT_INFO *
0607 AcpiEvGetGpeXruptBlock (
0608 UINT32 InterruptNumber)
0609 {
0610 ACPI_GPE_XRUPT_INFO *NextGpeXrupt;
0611 ACPI_GPE_XRUPT_INFO *GpeXrupt;
0612 ACPI_STATUS Status;
0613 ACPI_CPU_FLAGS Flags;
0614
0615
0616 ACPI_FUNCTION_TRACE (EvGetGpeXruptBlock);
0617
0618
0619
0620
0621 NextGpeXrupt = AcpiGbl_GpeXruptListHead;
0622 while (NextGpeXrupt)
0623 {
0624 if (NextGpeXrupt->InterruptNumber == InterruptNumber)
0625 {
0626 return_PTR (NextGpeXrupt);
0627 }
0628
0629 NextGpeXrupt = NextGpeXrupt->Next;
0630 }
0631
0632
0633
0634 GpeXrupt = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_GPE_XRUPT_INFO));
0635 if (!GpeXrupt)
0636 {
0637 return_PTR (NULL);
0638 }
0639
0640 GpeXrupt->InterruptNumber = InterruptNumber;
0641
0642
0643
0644 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
0645 if (AcpiGbl_GpeXruptListHead)
0646 {
0647 NextGpeXrupt = AcpiGbl_GpeXruptListHead;
0648 while (NextGpeXrupt->Next)
0649 {
0650 NextGpeXrupt = NextGpeXrupt->Next;
0651 }
0652
0653 NextGpeXrupt->Next = GpeXrupt;
0654 GpeXrupt->Previous = NextGpeXrupt;
0655 }
0656 else
0657 {
0658 AcpiGbl_GpeXruptListHead = GpeXrupt;
0659 }
0660 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
0661
0662
0663
0664 if (InterruptNumber != AcpiGbl_FADT.SciInterrupt)
0665 {
0666 Status = AcpiOsInstallInterruptHandler (InterruptNumber,
0667 AcpiEvGpeXruptHandler, GpeXrupt);
0668 if (ACPI_FAILURE (Status))
0669 {
0670 ACPI_ERROR ((AE_INFO,
0671 "Could not install GPE interrupt handler at level 0x%X",
0672 InterruptNumber));
0673 return_PTR (NULL);
0674 }
0675 }
0676
0677 return_PTR (GpeXrupt);
0678 }
0679
0680
0681
0682
0683
0684
0685
0686
0687
0688
0689
0690
0691
0692
0693
0694 static ACPI_STATUS
0695 AcpiEvDeleteGpeXrupt (
0696 ACPI_GPE_XRUPT_INFO *GpeXrupt)
0697 {
0698 ACPI_STATUS Status;
0699 ACPI_CPU_FLAGS Flags;
0700
0701
0702 ACPI_FUNCTION_TRACE (EvDeleteGpeXrupt);
0703
0704
0705
0706
0707 if (GpeXrupt->InterruptNumber == AcpiGbl_FADT.SciInterrupt)
0708 {
0709 GpeXrupt->GpeBlockListHead = NULL;
0710 return_ACPI_STATUS (AE_OK);
0711 }
0712
0713
0714
0715 Status = AcpiOsRemoveInterruptHandler (
0716 GpeXrupt->InterruptNumber, AcpiEvGpeXruptHandler);
0717 if (ACPI_FAILURE (Status))
0718 {
0719 return_ACPI_STATUS (Status);
0720 }
0721
0722
0723
0724 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
0725 if (GpeXrupt->Previous)
0726 {
0727 GpeXrupt->Previous->Next = GpeXrupt->Next;
0728 }
0729 else
0730 {
0731
0732
0733 AcpiGbl_GpeXruptListHead = GpeXrupt->Next;
0734 }
0735
0736 if (GpeXrupt->Next)
0737 {
0738 GpeXrupt->Next->Previous = GpeXrupt->Previous;
0739 }
0740 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
0741
0742
0743
0744 ACPI_FREE (GpeXrupt);
0745 return_ACPI_STATUS (AE_OK);
0746 }
0747
0748
0749
0750
0751
0752
0753
0754
0755
0756
0757
0758
0759
0760
0761
0762
0763 static ACPI_STATUS
0764 AcpiEvInstallGpeBlock (
0765 ACPI_GPE_BLOCK_INFO *GpeBlock,
0766 UINT32 InterruptNumber)
0767 {
0768 ACPI_GPE_BLOCK_INFO *NextGpeBlock;
0769 ACPI_GPE_XRUPT_INFO *GpeXruptBlock;
0770 ACPI_STATUS Status;
0771 ACPI_CPU_FLAGS Flags;
0772
0773
0774 ACPI_FUNCTION_TRACE (EvInstallGpeBlock);
0775
0776
0777 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
0778 if (ACPI_FAILURE (Status))
0779 {
0780 return_ACPI_STATUS (Status);
0781 }
0782
0783 GpeXruptBlock = AcpiEvGetGpeXruptBlock (InterruptNumber);
0784 if (!GpeXruptBlock)
0785 {
0786 Status = AE_NO_MEMORY;
0787 goto UnlockAndExit;
0788 }
0789
0790
0791
0792 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
0793 if (GpeXruptBlock->GpeBlockListHead)
0794 {
0795 NextGpeBlock = GpeXruptBlock->GpeBlockListHead;
0796 while (NextGpeBlock->Next)
0797 {
0798 NextGpeBlock = NextGpeBlock->Next;
0799 }
0800
0801 NextGpeBlock->Next = GpeBlock;
0802 GpeBlock->Previous = NextGpeBlock;
0803 }
0804 else
0805 {
0806 GpeXruptBlock->GpeBlockListHead = GpeBlock;
0807 }
0808
0809 GpeBlock->XruptBlock = GpeXruptBlock;
0810 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
0811
0812
0813 UnlockAndExit:
0814 Status = AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
0815 return_ACPI_STATUS (Status);
0816 }
0817
0818
0819
0820
0821
0822
0823
0824
0825
0826
0827
0828
0829
0830
0831 ACPI_STATUS
0832 AcpiEvDeleteGpeBlock (
0833 ACPI_GPE_BLOCK_INFO *GpeBlock)
0834 {
0835 ACPI_STATUS Status;
0836 ACPI_CPU_FLAGS Flags;
0837
0838
0839 ACPI_FUNCTION_TRACE (EvInstallGpeBlock);
0840
0841
0842 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
0843 if (ACPI_FAILURE (Status))
0844 {
0845 return_ACPI_STATUS (Status);
0846 }
0847
0848
0849
0850 Status = AcpiHwDisableGpeBlock (GpeBlock->XruptBlock, GpeBlock, NULL);
0851
0852 if (!GpeBlock->Previous && !GpeBlock->Next)
0853 {
0854
0855
0856 Status = AcpiEvDeleteGpeXrupt (GpeBlock->XruptBlock);
0857 if (ACPI_FAILURE (Status))
0858 {
0859 goto UnlockAndExit;
0860 }
0861 }
0862 else
0863 {
0864
0865
0866 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
0867 if (GpeBlock->Previous)
0868 {
0869 GpeBlock->Previous->Next = GpeBlock->Next;
0870 }
0871 else
0872 {
0873 GpeBlock->XruptBlock->GpeBlockListHead = GpeBlock->Next;
0874 }
0875
0876 if (GpeBlock->Next)
0877 {
0878 GpeBlock->Next->Previous = GpeBlock->Previous;
0879 }
0880 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
0881 }
0882
0883 AcpiCurrentGpeCount -= GpeBlock->RegisterCount * ACPI_GPE_REGISTER_WIDTH;
0884
0885
0886
0887 ACPI_FREE (GpeBlock->RegisterInfo);
0888 ACPI_FREE (GpeBlock->EventInfo);
0889 ACPI_FREE (GpeBlock);
0890
0891 UnlockAndExit:
0892 Status = AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
0893 return_ACPI_STATUS (Status);
0894 }
0895
0896
0897
0898
0899
0900
0901
0902
0903
0904
0905
0906
0907
0908
0909 static ACPI_STATUS
0910 AcpiEvCreateGpeInfoBlocks (
0911 ACPI_GPE_BLOCK_INFO *GpeBlock)
0912 {
0913 ACPI_GPE_REGISTER_INFO *GpeRegisterInfo = NULL;
0914 ACPI_GPE_EVENT_INFO *GpeEventInfo = NULL;
0915 ACPI_GPE_EVENT_INFO *ThisEvent;
0916 ACPI_GPE_REGISTER_INFO *ThisRegister;
0917 UINT32 i;
0918 UINT32 j;
0919 ACPI_STATUS Status;
0920
0921
0922 ACPI_FUNCTION_TRACE (EvCreateGpeInfoBlocks);
0923
0924
0925
0926
0927 GpeRegisterInfo = ACPI_ALLOCATE_ZEROED (
0928 (ACPI_SIZE) GpeBlock->RegisterCount *
0929 sizeof (ACPI_GPE_REGISTER_INFO));
0930 if (!GpeRegisterInfo)
0931 {
0932 ACPI_ERROR ((AE_INFO,
0933 "Could not allocate the GpeRegisterInfo table"));
0934 return_ACPI_STATUS (AE_NO_MEMORY);
0935 }
0936
0937
0938
0939
0940
0941 GpeEventInfo = ACPI_ALLOCATE_ZEROED (
0942 ((ACPI_SIZE) GpeBlock->RegisterCount *
0943 ACPI_GPE_REGISTER_WIDTH) *
0944 sizeof (ACPI_GPE_EVENT_INFO));
0945 if (!GpeEventInfo)
0946 {
0947 ACPI_ERROR ((AE_INFO,
0948 "Could not allocate the GpeEventInfo table"));
0949 Status = AE_NO_MEMORY;
0950 goto ErrorExit;
0951 }
0952
0953
0954
0955 GpeBlock->RegisterInfo = GpeRegisterInfo;
0956 GpeBlock->EventInfo = GpeEventInfo;
0957
0958
0959
0960
0961
0962
0963
0964 ThisRegister = GpeRegisterInfo;
0965 ThisEvent = GpeEventInfo;
0966
0967 for (i = 0; i < GpeBlock->RegisterCount; i++)
0968 {
0969
0970
0971 ThisRegister->BaseGpeNumber = (UINT8) (GpeBlock->BlockBaseNumber +
0972 (i * ACPI_GPE_REGISTER_WIDTH));
0973
0974 ThisRegister->StatusAddress.Address =
0975 GpeBlock->BlockAddress.Address + i;
0976
0977 ThisRegister->EnableAddress.Address =
0978 GpeBlock->BlockAddress.Address + i + GpeBlock->RegisterCount;
0979
0980 ThisRegister->StatusAddress.SpaceId = GpeBlock->BlockAddress.SpaceId;
0981 ThisRegister->EnableAddress.SpaceId = GpeBlock->BlockAddress.SpaceId;
0982 ThisRegister->StatusAddress.BitWidth = ACPI_GPE_REGISTER_WIDTH;
0983 ThisRegister->EnableAddress.BitWidth = ACPI_GPE_REGISTER_WIDTH;
0984 ThisRegister->StatusAddress.BitOffset = 0;
0985 ThisRegister->EnableAddress.BitOffset = 0;
0986
0987
0988
0989 for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++)
0990 {
0991 ThisEvent->GpeNumber = (UINT8) (ThisRegister->BaseGpeNumber + j);
0992 ThisEvent->RegisterInfo = ThisRegister;
0993 ThisEvent++;
0994 }
0995
0996
0997
0998 Status = AcpiHwWrite (0x00, &ThisRegister->EnableAddress);
0999 if (ACPI_FAILURE (Status))
1000 {
1001 goto ErrorExit;
1002 }
1003
1004
1005
1006 Status = AcpiHwWrite (0xFF, &ThisRegister->StatusAddress);
1007 if (ACPI_FAILURE (Status))
1008 {
1009 goto ErrorExit;
1010 }
1011
1012 ThisRegister++;
1013 }
1014
1015 return_ACPI_STATUS (AE_OK);
1016
1017
1018 ErrorExit:
1019 if (GpeRegisterInfo)
1020 {
1021 ACPI_FREE (GpeRegisterInfo);
1022 }
1023 if (GpeEventInfo)
1024 {
1025 ACPI_FREE (GpeEventInfo);
1026 }
1027
1028 return_ACPI_STATUS (Status);
1029 }
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051 ACPI_STATUS
1052 AcpiEvCreateGpeBlock (
1053 ACPI_NAMESPACE_NODE *GpeDevice,
1054 ACPI_GENERIC_ADDRESS *GpeBlockAddress,
1055 UINT32 RegisterCount,
1056 UINT8 GpeBlockBaseNumber,
1057 UINT32 InterruptNumber,
1058 ACPI_GPE_BLOCK_INFO **ReturnGpeBlock)
1059 {
1060 ACPI_STATUS Status;
1061 ACPI_GPE_BLOCK_INFO *GpeBlock;
1062
1063
1064 ACPI_FUNCTION_TRACE (EvCreateGpeBlock);
1065
1066
1067 if (!RegisterCount)
1068 {
1069 return_ACPI_STATUS (AE_OK);
1070 }
1071
1072
1073
1074 GpeBlock = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_GPE_BLOCK_INFO));
1075 if (!GpeBlock)
1076 {
1077 return_ACPI_STATUS (AE_NO_MEMORY);
1078 }
1079
1080
1081
1082 GpeBlock->Node = GpeDevice;
1083 GpeBlock->RegisterCount = RegisterCount;
1084 GpeBlock->BlockBaseNumber = GpeBlockBaseNumber;
1085
1086 ACPI_MEMCPY (&GpeBlock->BlockAddress, GpeBlockAddress,
1087 sizeof (ACPI_GENERIC_ADDRESS));
1088
1089
1090
1091
1092
1093 Status = AcpiEvCreateGpeInfoBlocks (GpeBlock);
1094 if (ACPI_FAILURE (Status))
1095 {
1096 ACPI_FREE (GpeBlock);
1097 return_ACPI_STATUS (Status);
1098 }
1099
1100
1101
1102 Status = AcpiEvInstallGpeBlock (GpeBlock, InterruptNumber);
1103 if (ACPI_FAILURE (Status))
1104 {
1105 ACPI_FREE (GpeBlock);
1106 return_ACPI_STATUS (Status);
1107 }
1108
1109
1110
1111 Status = AcpiNsWalkNamespace (ACPI_TYPE_METHOD, GpeDevice,
1112 ACPI_UINT32_MAX, ACPI_NS_WALK_NO_UNLOCK,
1113 AcpiEvSaveMethodInfo, GpeBlock, NULL);
1114
1115
1116
1117 if (ReturnGpeBlock)
1118 {
1119 (*ReturnGpeBlock) = GpeBlock;
1120 }
1121
1122 ACPI_DEBUG_PRINT ((ACPI_DB_INIT,
1123 "GPE %02X to %02X [%4.4s] %u regs on int 0x%X\n",
1124 (UINT32) GpeBlock->BlockBaseNumber,
1125 (UINT32) (GpeBlock->BlockBaseNumber +
1126 ((GpeBlock->RegisterCount * ACPI_GPE_REGISTER_WIDTH) -1)),
1127 GpeDevice->Name.Ascii,
1128 GpeBlock->RegisterCount,
1129 InterruptNumber));
1130
1131
1132
1133 AcpiCurrentGpeCount += RegisterCount * ACPI_GPE_REGISTER_WIDTH;
1134 return_ACPI_STATUS (AE_OK);
1135 }
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154 ACPI_STATUS
1155 AcpiEvInitializeGpeBlock (
1156 ACPI_NAMESPACE_NODE *GpeDevice,
1157 ACPI_GPE_BLOCK_INFO *GpeBlock)
1158 {
1159 ACPI_STATUS Status;
1160 ACPI_GPE_EVENT_INFO *GpeEventInfo;
1161 ACPI_GPE_WALK_INFO GpeInfo;
1162 UINT32 WakeGpeCount;
1163 UINT32 GpeEnabledCount;
1164 UINT32 i;
1165 UINT32 j;
1166
1167
1168 ACPI_FUNCTION_TRACE (EvInitializeGpeBlock);
1169
1170
1171
1172
1173 if (!GpeBlock)
1174 {
1175 return_ACPI_STATUS (AE_OK);
1176 }
1177
1178
1179
1180
1181
1182 if (AcpiGbl_LeaveWakeGpesDisabled)
1183 {
1184
1185
1186
1187
1188
1189
1190 GpeInfo.GpeBlock = GpeBlock;
1191 GpeInfo.GpeDevice = GpeDevice;
1192
1193 Status = AcpiNsWalkNamespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
1194 ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK,
1195 AcpiEvMatchPrwAndGpe, &GpeInfo, NULL);
1196 }
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206 WakeGpeCount = 0;
1207 GpeEnabledCount = 0;
1208
1209 for (i = 0; i < GpeBlock->RegisterCount; i++)
1210 {
1211 for (j = 0; j < 8; j++)
1212 {
1213
1214
1215 GpeEventInfo = &GpeBlock->EventInfo[((ACPI_SIZE) i *
1216 ACPI_GPE_REGISTER_WIDTH) + j];
1217
1218 if (((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) ==
1219 ACPI_GPE_DISPATCH_METHOD) &&
1220 (GpeEventInfo->Flags & ACPI_GPE_TYPE_RUNTIME))
1221 {
1222 GpeEnabledCount++;
1223 }
1224
1225 if (GpeEventInfo->Flags & ACPI_GPE_TYPE_WAKE)
1226 {
1227 WakeGpeCount++;
1228 }
1229 }
1230 }
1231
1232 ACPI_DEBUG_PRINT ((ACPI_DB_INIT,
1233 "Found %u Wake, Enabled %u Runtime GPEs in this block\n",
1234 WakeGpeCount, GpeEnabledCount));
1235
1236
1237
1238 Status = AcpiHwEnableRuntimeGpeBlock (NULL, GpeBlock, NULL);
1239 if (ACPI_FAILURE (Status))
1240 {
1241 ACPI_ERROR ((AE_INFO, "Could not enable GPEs in GpeBlock %p",
1242 GpeBlock));
1243 }
1244
1245 return_ACPI_STATUS (Status);
1246 }
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261 ACPI_STATUS
1262 AcpiEvGpeInitialize (
1263 void)
1264 {
1265 UINT32 RegisterCount0 = 0;
1266 UINT32 RegisterCount1 = 0;
1267 UINT32 GpeNumberMax = 0;
1268 ACPI_STATUS Status;
1269
1270
1271 ACPI_FUNCTION_TRACE (EvGpeInitialize);
1272
1273
1274 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
1275 if (ACPI_FAILURE (Status))
1276 {
1277 return_ACPI_STATUS (Status);
1278 }
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305 if (AcpiGbl_FADT.Gpe0BlockLength &&
1306 AcpiGbl_FADT.XGpe0Block.Address)
1307 {
1308
1309
1310 RegisterCount0 = (UINT16) (AcpiGbl_FADT.Gpe0BlockLength / 2);
1311
1312 GpeNumberMax = (RegisterCount0 * ACPI_GPE_REGISTER_WIDTH) - 1;
1313
1314
1315
1316 Status = AcpiEvCreateGpeBlock (AcpiGbl_FadtGpeDevice,
1317 &AcpiGbl_FADT.XGpe0Block, RegisterCount0, 0,
1318 AcpiGbl_FADT.SciInterrupt, &AcpiGbl_GpeFadtBlocks[0]);
1319
1320 if (ACPI_FAILURE (Status))
1321 {
1322 ACPI_EXCEPTION ((AE_INFO, Status,
1323 "Could not create GPE Block 0"));
1324 }
1325 }
1326
1327 if (AcpiGbl_FADT.Gpe1BlockLength &&
1328 AcpiGbl_FADT.XGpe1Block.Address)
1329 {
1330
1331
1332 RegisterCount1 = (UINT16) (AcpiGbl_FADT.Gpe1BlockLength / 2);
1333
1334
1335
1336 if ((RegisterCount0) &&
1337 (GpeNumberMax >= AcpiGbl_FADT.Gpe1Base))
1338 {
1339 ACPI_ERROR ((AE_INFO,
1340 "GPE0 block (GPE 0 to %d) overlaps the GPE1 block "
1341 "(GPE %d to %d) - Ignoring GPE1",
1342 GpeNumberMax, AcpiGbl_FADT.Gpe1Base,
1343 AcpiGbl_FADT.Gpe1Base +
1344 ((RegisterCount1 * ACPI_GPE_REGISTER_WIDTH) - 1)));
1345
1346
1347
1348 RegisterCount1 = 0;
1349 }
1350 else
1351 {
1352
1353
1354 Status = AcpiEvCreateGpeBlock (AcpiGbl_FadtGpeDevice,
1355 &AcpiGbl_FADT.XGpe1Block, RegisterCount1,
1356 AcpiGbl_FADT.Gpe1Base,
1357 AcpiGbl_FADT.SciInterrupt, &AcpiGbl_GpeFadtBlocks[1]);
1358
1359 if (ACPI_FAILURE (Status))
1360 {
1361 ACPI_EXCEPTION ((AE_INFO, Status,
1362 "Could not create GPE Block 1"));
1363 }
1364
1365
1366
1367
1368
1369 GpeNumberMax = AcpiGbl_FADT.Gpe1Base +
1370 ((RegisterCount1 * ACPI_GPE_REGISTER_WIDTH) - 1);
1371 }
1372 }
1373
1374
1375
1376 if ((RegisterCount0 + RegisterCount1) == 0)
1377 {
1378
1379
1380 ACPI_DEBUG_PRINT ((ACPI_DB_INIT,
1381 "There are no GPE blocks defined in the FADT\n"));
1382 Status = AE_OK;
1383 goto Cleanup;
1384 }
1385
1386
1387
1388 if (GpeNumberMax > ACPI_GPE_MAX)
1389 {
1390 ACPI_ERROR ((AE_INFO,
1391 "Maximum GPE number from FADT is too large: 0x%X",
1392 GpeNumberMax));
1393 Status = AE_BAD_VALUE;
1394 goto Cleanup;
1395 }
1396
1397 Cleanup:
1398 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
1399 return_ACPI_STATUS (AE_OK);
1400 }
1401
1402