evgpeblk.c (114239) | evgpeblk.c (117521) |
---|---|
1/****************************************************************************** 2 * 3 * Module Name: evgpeblk - GPE block creation and initialization. | 1/****************************************************************************** 2 * 3 * Module Name: evgpeblk - GPE block creation and initialization. |
4 * $Revision: 4 $ | 4 * $Revision: 23 $ |
5 * 6 *****************************************************************************/ 7 8/****************************************************************************** 9 * 10 * 1. Copyright Notice 11 * 12 * Some or all of this work - Copyright (c) 1999 - 2003, Intel Corp. --- 101 unchanged lines hidden (view full) --- 114 * 115 *****************************************************************************/ 116 117#include "acpi.h" 118#include "acevents.h" 119#include "acnamesp.h" 120 121#define _COMPONENT ACPI_EVENTS | 5 * 6 *****************************************************************************/ 7 8/****************************************************************************** 9 * 10 * 1. Copyright Notice 11 * 12 * Some or all of this work - Copyright (c) 1999 - 2003, Intel Corp. --- 101 unchanged lines hidden (view full) --- 114 * 115 *****************************************************************************/ 116 117#include "acpi.h" 118#include "acevents.h" 119#include "acnamesp.h" 120 121#define _COMPONENT ACPI_EVENTS |
122 ACPI_MODULE_NAME ("evgpe") | 122 ACPI_MODULE_NAME ("evgpeblk") |
123 124 125/******************************************************************************* 126 * | 123 124 125/******************************************************************************* 126 * |
127 * FUNCTION: AcpiEvValidGpeEvent 128 * 129 * PARAMETERS: GpeEventInfo - Info for this GPE 130 * 131 * RETURN: TRUE if the GpeEvent is valid 132 * 133 * DESCRIPTION: Validate a GPE event. DO NOT CALL FROM INTERRUPT LEVEL. 134 * Should be called only when the GPE lists are semaphore locked 135 * and not subject to change. 136 * 137 ******************************************************************************/ 138 139BOOLEAN 140AcpiEvValidGpeEvent ( 141 ACPI_GPE_EVENT_INFO *GpeEventInfo) 142{ 143 ACPI_GPE_XRUPT_INFO *GpeXruptBlock; 144 ACPI_GPE_BLOCK_INFO *GpeBlock; 145 146 147 ACPI_FUNCTION_ENTRY (); 148 149 150 /* No need for spin lock since we are not changing any list elements */ 151 152 /* Walk the GPE interrupt levels */ 153 154 GpeXruptBlock = AcpiGbl_GpeXruptListHead; 155 while (GpeXruptBlock) 156 { 157 GpeBlock = GpeXruptBlock->GpeBlockListHead; 158 159 /* Walk the GPE blocks on this interrupt level */ 160 161 while (GpeBlock) 162 { 163 if ((&GpeBlock->EventInfo[0] <= GpeEventInfo) && 164 (&GpeBlock->EventInfo[((ACPI_SIZE) GpeBlock->RegisterCount) * 8] > GpeEventInfo)) 165 { 166 return (TRUE); 167 } 168 169 GpeBlock = GpeBlock->Next; 170 } 171 172 GpeXruptBlock = GpeXruptBlock->Next; 173 } 174 175 return (FALSE); 176} 177 178 179/******************************************************************************* 180 * 181 * FUNCTION: AcpiEvWalkGpeList 182 * 183 * PARAMETERS: GpeWalkCallback - Routine called for each GPE block 184 * 185 * RETURN: Status 186 * 187 * DESCRIPTION: Walk the GPE lists. 188 * FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED 189 * 190 ******************************************************************************/ 191 192ACPI_STATUS 193AcpiEvWalkGpeList ( 194 ACPI_GPE_CALLBACK GpeWalkCallback) 195{ 196 ACPI_GPE_BLOCK_INFO *GpeBlock; 197 ACPI_GPE_XRUPT_INFO *GpeXruptInfo; 198 ACPI_STATUS Status = AE_OK; 199 200 201 ACPI_FUNCTION_TRACE ("EvWalkGpeList"); 202 203 204 AcpiOsAcquireLock (AcpiGbl_GpeLock, ACPI_ISR); 205 206 /* Walk the interrupt level descriptor list */ 207 208 GpeXruptInfo = AcpiGbl_GpeXruptListHead; 209 while (GpeXruptInfo) 210 { 211 /* Walk all Gpe Blocks attached to this interrupt level */ 212 213 GpeBlock = GpeXruptInfo->GpeBlockListHead; 214 while (GpeBlock) 215 { 216 /* One callback per GPE block */ 217 218 Status = GpeWalkCallback (GpeXruptInfo, GpeBlock); 219 if (ACPI_FAILURE (Status)) 220 { 221 goto UnlockAndExit; 222 } 223 224 GpeBlock = GpeBlock->Next; 225 } 226 227 GpeXruptInfo = GpeXruptInfo->Next; 228 } 229 230UnlockAndExit: 231 AcpiOsReleaseLock (AcpiGbl_GpeLock, ACPI_ISR); 232 return_ACPI_STATUS (Status); 233} 234 235 236/******************************************************************************* 237 * |
|
127 * FUNCTION: AcpiEvSaveMethodInfo 128 * 129 * PARAMETERS: Callback from WalkNamespace 130 * | 238 * FUNCTION: AcpiEvSaveMethodInfo 239 * 240 * PARAMETERS: Callback from WalkNamespace 241 * |
131 * RETURN: None | 242 * RETURN: Status |
132 * 133 * DESCRIPTION: Called from AcpiWalkNamespace. Expects each object to be a 134 * control method under the _GPE portion of the namespace. 135 * Extract the name and GPE type from the object, saving this 136 * information for quick lookup during GPE dispatch 137 * 138 * The name of each GPE control method is of the form: 139 * "_Lnn" or "_Enn" | 243 * 244 * DESCRIPTION: Called from AcpiWalkNamespace. Expects each object to be a 245 * control method under the _GPE portion of the namespace. 246 * Extract the name and GPE type from the object, saving this 247 * information for quick lookup during GPE dispatch 248 * 249 * The name of each GPE control method is of the form: 250 * "_Lnn" or "_Enn" |
140 * Where: 141 * L - means that the GPE is level triggered 142 * E - means that the GPE is edge triggered 143 * nn - is the GPE number [in HEX] | 251 * Where: 252 * L - means that the GPE is level triggered 253 * E - means that the GPE is edge triggered 254 * nn - is the GPE number [in HEX] |
144 * 145 ******************************************************************************/ 146 147static ACPI_STATUS 148AcpiEvSaveMethodInfo ( 149 ACPI_HANDLE ObjHandle, 150 UINT32 Level, 151 void *ObjDesc, 152 void **ReturnValue) 153{ 154 ACPI_GPE_BLOCK_INFO *GpeBlock = (void *) ObjDesc; 155 ACPI_GPE_EVENT_INFO *GpeEventInfo; 156 UINT32 GpeNumber; 157 char Name[ACPI_NAME_SIZE + 1]; 158 UINT8 Type; 159 ACPI_STATUS Status; 160 161 | 255 * 256 ******************************************************************************/ 257 258static ACPI_STATUS 259AcpiEvSaveMethodInfo ( 260 ACPI_HANDLE ObjHandle, 261 UINT32 Level, 262 void *ObjDesc, 263 void **ReturnValue) 264{ 265 ACPI_GPE_BLOCK_INFO *GpeBlock = (void *) ObjDesc; 266 ACPI_GPE_EVENT_INFO *GpeEventInfo; 267 UINT32 GpeNumber; 268 char Name[ACPI_NAME_SIZE + 1]; 269 UINT8 Type; 270 ACPI_STATUS Status; 271 272 |
162 ACPI_FUNCTION_NAME ("EvSaveMethodInfo"); | 273 ACPI_FUNCTION_TRACE ("EvSaveMethodInfo"); |
163 164 165 /* Extract the name from the object and convert to a string */ 166 | 274 275 276 /* Extract the name from the object and convert to a string */ 277 |
167 ACPI_MOVE_UNALIGNED32_TO_32 (Name, 168 &((ACPI_NAMESPACE_NODE *) ObjHandle)->Name.Integer); | 278 ACPI_MOVE_32_TO_32 (Name, 279 &((ACPI_NAMESPACE_NODE *) ObjHandle)->Name.Integer); |
169 Name[ACPI_NAME_SIZE] = 0; 170 171 /* | 280 Name[ACPI_NAME_SIZE] = 0; 281 282 /* |
172 * Edge/Level determination is based on the 2nd character of the method name | 283 * Edge/Level determination is based on the 2nd character 284 * of the method name |
173 */ 174 switch (Name[1]) 175 { 176 case 'L': 177 Type = ACPI_EVENT_LEVEL_TRIGGERED; 178 break; 179 180 case 'E': 181 Type = ACPI_EVENT_EDGE_TRIGGERED; 182 break; 183 184 default: 185 /* Unknown method type, just ignore it! */ 186 187 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, 188 "Unknown GPE method type: %s (name not of form _Lnn or _Enn)\n", 189 Name)); | 285 */ 286 switch (Name[1]) 287 { 288 case 'L': 289 Type = ACPI_EVENT_LEVEL_TRIGGERED; 290 break; 291 292 case 'E': 293 Type = ACPI_EVENT_EDGE_TRIGGERED; 294 break; 295 296 default: 297 /* Unknown method type, just ignore it! */ 298 299 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, 300 "Unknown GPE method type: %s (name not of form _Lnn or _Enn)\n", 301 Name)); |
190 return (AE_OK); | 302 return_ACPI_STATUS (AE_OK); |
191 } 192 193 /* Convert the last two characters of the name to the GPE Number */ 194 195 GpeNumber = ACPI_STRTOUL (&Name[2], NULL, 16); 196 if (GpeNumber == ACPI_UINT32_MAX) 197 { 198 /* Conversion failed; invalid method, just ignore it */ 199 200 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, 201 "Could not extract GPE number from name: %s (name is not of form _Lnn or _Enn)\n", 202 Name)); | 303 } 304 305 /* Convert the last two characters of the name to the GPE Number */ 306 307 GpeNumber = ACPI_STRTOUL (&Name[2], NULL, 16); 308 if (GpeNumber == ACPI_UINT32_MAX) 309 { 310 /* Conversion failed; invalid method, just ignore it */ 311 312 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, 313 "Could not extract GPE number from name: %s (name is not of form _Lnn or _Enn)\n", 314 Name)); |
203 return (AE_OK); | 315 return_ACPI_STATUS (AE_OK); |
204 } 205 206 /* Ensure that we have a valid GPE number for this GPE block */ 207 208 if ((GpeNumber < GpeBlock->BlockBaseNumber) || | 316 } 317 318 /* Ensure that we have a valid GPE number for this GPE block */ 319 320 if ((GpeNumber < GpeBlock->BlockBaseNumber) || |
209 (GpeNumber - GpeBlock->BlockBaseNumber >= (GpeBlock->RegisterCount * 8))) | 321 (GpeNumber >= (GpeBlock->BlockBaseNumber + (GpeBlock->RegisterCount * 8)))) |
210 { | 322 { |
211 /* Not valid, all we can do here is ignore it */ 212 213 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, 214 "GPE number associated with method %s is not valid\n", Name)); 215 return (AE_OK); | 323 /* 324 * Not valid for this GPE block, just ignore it 325 * However, it may be valid for a different GPE block, since GPE0 and GPE1 326 * methods both appear under \_GPE. 327 */ 328 return_ACPI_STATUS (AE_OK); |
216 } 217 218 /* 219 * Now we can add this information to the GpeEventInfo block 220 * for use during dispatch of this GPE. 221 */ 222 GpeEventInfo = &GpeBlock->EventInfo[GpeNumber - GpeBlock->BlockBaseNumber]; 223 | 329 } 330 331 /* 332 * Now we can add this information to the GpeEventInfo block 333 * for use during dispatch of this GPE. 334 */ 335 GpeEventInfo = &GpeBlock->EventInfo[GpeNumber - GpeBlock->BlockBaseNumber]; 336 |
224 GpeEventInfo->Type = Type; | 337 GpeEventInfo->Flags = Type; |
225 GpeEventInfo->MethodNode = (ACPI_NAMESPACE_NODE *) ObjHandle; 226 | 338 GpeEventInfo->MethodNode = (ACPI_NAMESPACE_NODE *) ObjHandle; 339 |
227 /* 228 * Enable the GPE (SCIs should be disabled at this point) 229 */ | 340 /* Enable the GPE (SCIs should be disabled at this point) */ 341 |
230 Status = AcpiHwEnableGpe (GpeEventInfo); 231 if (ACPI_FAILURE (Status)) 232 { | 342 Status = AcpiHwEnableGpe (GpeEventInfo); 343 if (ACPI_FAILURE (Status)) 344 { |
233 return (Status); | 345 return_ACPI_STATUS (Status); |
234 } 235 | 346 } 347 |
236 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Registered GPE method %s as GPE number %2.2X\n", | 348 ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, 349 "Registered GPE method %s as GPE number 0x%.2X\n", |
237 Name, GpeNumber)); | 350 Name, GpeNumber)); |
238 return (AE_OK); | 351 return_ACPI_STATUS (AE_OK); |
239} 240 241 242/******************************************************************************* 243 * | 352} 353 354 355/******************************************************************************* 356 * |
357 * FUNCTION: AcpiEvGetGpeXruptBlock 358 * 359 * PARAMETERS: InterruptLevel - Interrupt for a GPE block 360 * 361 * RETURN: A GPE interrupt block 362 * 363 * DESCRIPTION: Get or Create a GPE interrupt block. There is one interrupt 364 * block per unique interrupt level used for GPEs. 365 * Should be called only when the GPE lists are semaphore locked 366 * and not subject to change. 367 * 368 ******************************************************************************/ 369 370static ACPI_GPE_XRUPT_INFO * 371AcpiEvGetGpeXruptBlock ( 372 UINT32 InterruptLevel) 373{ 374 ACPI_GPE_XRUPT_INFO *NextGpeXrupt; 375 ACPI_GPE_XRUPT_INFO *GpeXrupt; 376 ACPI_STATUS Status; 377 378 379 ACPI_FUNCTION_TRACE ("EvGetGpeXruptBlock"); 380 381 382 /* No need for spin lock since we are not changing any list elements here */ 383 384 NextGpeXrupt = AcpiGbl_GpeXruptListHead; 385 while (NextGpeXrupt) 386 { 387 if (NextGpeXrupt->InterruptLevel == InterruptLevel) 388 { 389 return_PTR (NextGpeXrupt); 390 } 391 392 NextGpeXrupt = NextGpeXrupt->Next; 393 } 394 395 /* Not found, must allocate a new xrupt descriptor */ 396 397 GpeXrupt = ACPI_MEM_CALLOCATE (sizeof (ACPI_GPE_XRUPT_INFO)); 398 if (!GpeXrupt) 399 { 400 return_PTR (NULL); 401 } 402 403 GpeXrupt->InterruptLevel = InterruptLevel; 404 405 /* Install new interrupt descriptor with spin lock */ 406 407 AcpiOsAcquireLock (AcpiGbl_GpeLock, ACPI_NOT_ISR); 408 if (AcpiGbl_GpeXruptListHead) 409 { 410 NextGpeXrupt = AcpiGbl_GpeXruptListHead; 411 while (NextGpeXrupt->Next) 412 { 413 NextGpeXrupt = NextGpeXrupt->Next; 414 } 415 416 NextGpeXrupt->Next = GpeXrupt; 417 GpeXrupt->Previous = NextGpeXrupt; 418 } 419 else 420 { 421 AcpiGbl_GpeXruptListHead = GpeXrupt; 422 } 423 AcpiOsReleaseLock (AcpiGbl_GpeLock, ACPI_NOT_ISR); 424 425 /* Install new interrupt handler if not SCI_INT */ 426 427 if (InterruptLevel != AcpiGbl_FADT->SciInt) 428 { 429 Status = AcpiOsInstallInterruptHandler (InterruptLevel, 430 AcpiEvGpeXruptHandler, GpeXrupt); 431 if (ACPI_FAILURE (Status)) 432 { 433 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, 434 "Could not install GPE interrupt handler at level 0x%X\n", 435 InterruptLevel)); 436 return_PTR (NULL); 437 } 438 } 439 440 return_PTR (GpeXrupt); 441} 442 443 444/******************************************************************************* 445 * 446 * FUNCTION: AcpiEvDeleteGpeXrupt 447 * 448 * PARAMETERS: GpeXrupt - A GPE interrupt info block 449 * 450 * RETURN: Status 451 * 452 * DESCRIPTION: Remove and free a GpeXrupt block. Remove an associated 453 * interrupt handler if not the SCI interrupt. 454 * 455 ******************************************************************************/ 456 457static ACPI_STATUS 458AcpiEvDeleteGpeXrupt ( 459 ACPI_GPE_XRUPT_INFO *GpeXrupt) 460{ 461 ACPI_STATUS Status; 462 463 464 ACPI_FUNCTION_TRACE ("EvDeleteGpeXrupt"); 465 466 467 /* We never want to remove the SCI interrupt handler */ 468 469 if (GpeXrupt->InterruptLevel == AcpiGbl_FADT->SciInt) 470 { 471 GpeXrupt->GpeBlockListHead = NULL; 472 return_ACPI_STATUS (AE_OK); 473 } 474 475 /* Disable this interrupt */ 476 477 Status = AcpiOsRemoveInterruptHandler (GpeXrupt->InterruptLevel, 478 AcpiEvGpeXruptHandler); 479 if (ACPI_FAILURE (Status)) 480 { 481 return_ACPI_STATUS (Status); 482 } 483 484 /* Unlink the interrupt block with lock */ 485 486 AcpiOsAcquireLock (AcpiGbl_GpeLock, ACPI_NOT_ISR); 487 if (GpeXrupt->Previous) 488 { 489 GpeXrupt->Previous->Next = GpeXrupt->Next; 490 } 491 492 if (GpeXrupt->Next) 493 { 494 GpeXrupt->Next->Previous = GpeXrupt->Previous; 495 } 496 AcpiOsReleaseLock (AcpiGbl_GpeLock, ACPI_NOT_ISR); 497 498 /* Free the block */ 499 500 ACPI_MEM_FREE (GpeXrupt); 501 return_ACPI_STATUS (AE_OK); 502} 503 504 505/******************************************************************************* 506 * |
|
244 * FUNCTION: AcpiEvInstallGpeBlock 245 * | 507 * FUNCTION: AcpiEvInstallGpeBlock 508 * |
246 * PARAMETERS: GpeBlock - New GPE block | 509 * PARAMETERS: GpeBlock - New GPE block 510 * InterruptLevel - Level to be associated with this GPE block |
247 * 248 * RETURN: Status 249 * 250 * DESCRIPTION: Install new GPE block with mutex support 251 * 252 ******************************************************************************/ 253 | 511 * 512 * RETURN: Status 513 * 514 * DESCRIPTION: Install new GPE block with mutex support 515 * 516 ******************************************************************************/ 517 |
254ACPI_STATUS | 518static ACPI_STATUS |
255AcpiEvInstallGpeBlock ( | 519AcpiEvInstallGpeBlock ( |
256 ACPI_GPE_BLOCK_INFO *GpeBlock) | 520 ACPI_GPE_BLOCK_INFO *GpeBlock, 521 UINT32 InterruptLevel) |
257{ 258 ACPI_GPE_BLOCK_INFO *NextGpeBlock; | 522{ 523 ACPI_GPE_BLOCK_INFO *NextGpeBlock; |
524 ACPI_GPE_XRUPT_INFO *GpeXruptBlock; |
|
259 ACPI_STATUS Status; 260 261 | 525 ACPI_STATUS Status; 526 527 |
528 ACPI_FUNCTION_TRACE ("EvInstallGpeBlock"); 529 530 |
|
262 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 263 if (ACPI_FAILURE (Status)) 264 { | 531 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 532 if (ACPI_FAILURE (Status)) 533 { |
265 return (Status); | 534 return_ACPI_STATUS (Status); |
266 } 267 | 535 } 536 |
268 /* Install the new block at the end of the global list */ | 537 GpeXruptBlock = AcpiEvGetGpeXruptBlock (InterruptLevel); 538 if (!GpeXruptBlock) 539 { 540 Status = AE_NO_MEMORY; 541 goto UnlockAndExit; 542 } |
269 | 543 |
270 if (AcpiGbl_GpeBlockListHead) | 544 /* Install the new block at the end of the list for this interrupt with lock */ 545 546 AcpiOsAcquireLock (AcpiGbl_GpeLock, ACPI_NOT_ISR); 547 if (GpeXruptBlock->GpeBlockListHead) |
271 { | 548 { |
272 NextGpeBlock = AcpiGbl_GpeBlockListHead; | 549 NextGpeBlock = GpeXruptBlock->GpeBlockListHead; |
273 while (NextGpeBlock->Next) 274 { 275 NextGpeBlock = NextGpeBlock->Next; 276 } 277 278 NextGpeBlock->Next = GpeBlock; 279 GpeBlock->Previous = NextGpeBlock; 280 } 281 else 282 { | 550 while (NextGpeBlock->Next) 551 { 552 NextGpeBlock = NextGpeBlock->Next; 553 } 554 555 NextGpeBlock->Next = GpeBlock; 556 GpeBlock->Previous = NextGpeBlock; 557 } 558 else 559 { |
283 AcpiGbl_GpeBlockListHead = GpeBlock; | 560 GpeXruptBlock->GpeBlockListHead = GpeBlock; |
284 } 285 | 561 } 562 |
563 GpeBlock->XruptBlock = GpeXruptBlock; 564 AcpiOsReleaseLock (AcpiGbl_GpeLock, ACPI_NOT_ISR); 565 566UnlockAndExit: |
|
286 Status = AcpiUtReleaseMutex (ACPI_MTX_EVENTS); | 567 Status = AcpiUtReleaseMutex (ACPI_MTX_EVENTS); |
287 return (Status); | 568 return_ACPI_STATUS (Status); |
288} 289 290 291/******************************************************************************* 292 * | 569} 570 571 572/******************************************************************************* 573 * |
574 * FUNCTION: AcpiEvDeleteGpeBlock 575 * 576 * PARAMETERS: GpeBlock - Existing GPE block 577 * 578 * RETURN: Status 579 * 580 * DESCRIPTION: Install new GPE block with mutex support 581 * 582 ******************************************************************************/ 583 584ACPI_STATUS 585AcpiEvDeleteGpeBlock ( 586 ACPI_GPE_BLOCK_INFO *GpeBlock) 587{ 588 ACPI_STATUS Status; 589 590 591 ACPI_FUNCTION_TRACE ("EvInstallGpeBlock"); 592 593 594 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 595 if (ACPI_FAILURE (Status)) 596 { 597 return_ACPI_STATUS (Status); 598 } 599 600 /* Disable all GPEs in this block */ 601 602 Status = AcpiHwDisableGpeBlock (GpeBlock->XruptBlock, GpeBlock); 603 604 if (!GpeBlock->Previous && !GpeBlock->Next) 605 { 606 /* This is the last GpeBlock on this interrupt */ 607 608 Status = AcpiEvDeleteGpeXrupt (GpeBlock->XruptBlock); 609 if (ACPI_FAILURE (Status)) 610 { 611 goto UnlockAndExit; 612 } 613 } 614 else 615 { 616 /* Remove the block on this interrupt with lock */ 617 618 AcpiOsAcquireLock (AcpiGbl_GpeLock, ACPI_NOT_ISR); 619 if (GpeBlock->Previous) 620 { 621 GpeBlock->Previous->Next = GpeBlock->Next; 622 } 623 else 624 { 625 GpeBlock->XruptBlock->GpeBlockListHead = GpeBlock->Next; 626 } 627 628 if (GpeBlock->Next) 629 { 630 GpeBlock->Next->Previous = GpeBlock->Previous; 631 } 632 AcpiOsReleaseLock (AcpiGbl_GpeLock, ACPI_NOT_ISR); 633 } 634 635 /* Free the GpeBlock */ 636 637 ACPI_MEM_FREE (GpeBlock->RegisterInfo); 638 ACPI_MEM_FREE (GpeBlock->EventInfo); 639 ACPI_MEM_FREE (GpeBlock); 640 641UnlockAndExit: 642 Status = AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 643 return_ACPI_STATUS (Status); 644} 645 646 647/******************************************************************************* 648 * |
|
293 * FUNCTION: AcpiEvCreateGpeInfoBlocks 294 * 295 * PARAMETERS: GpeBlock - New GPE block 296 * 297 * RETURN: Status 298 * 299 * DESCRIPTION: Create the RegisterInfo and EventInfo blocks for this GPE block 300 * 301 ******************************************************************************/ 302 | 649 * FUNCTION: AcpiEvCreateGpeInfoBlocks 650 * 651 * PARAMETERS: GpeBlock - New GPE block 652 * 653 * RETURN: Status 654 * 655 * DESCRIPTION: Create the RegisterInfo and EventInfo blocks for this GPE block 656 * 657 ******************************************************************************/ 658 |
303ACPI_STATUS | 659static ACPI_STATUS |
304AcpiEvCreateGpeInfoBlocks ( 305 ACPI_GPE_BLOCK_INFO *GpeBlock) 306{ 307 ACPI_GPE_REGISTER_INFO *GpeRegisterInfo = NULL; 308 ACPI_GPE_EVENT_INFO *GpeEventInfo = NULL; 309 ACPI_GPE_EVENT_INFO *ThisEvent; 310 ACPI_GPE_REGISTER_INFO *ThisRegister; 311 ACPI_NATIVE_UINT i; --- 25 unchanged lines hidden (view full) --- 337 sizeof (ACPI_GPE_EVENT_INFO)); 338 if (!GpeEventInfo) 339 { 340 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not allocate the GpeEventInfo table\n")); 341 Status = AE_NO_MEMORY; 342 goto ErrorExit; 343 } 344 | 660AcpiEvCreateGpeInfoBlocks ( 661 ACPI_GPE_BLOCK_INFO *GpeBlock) 662{ 663 ACPI_GPE_REGISTER_INFO *GpeRegisterInfo = NULL; 664 ACPI_GPE_EVENT_INFO *GpeEventInfo = NULL; 665 ACPI_GPE_EVENT_INFO *ThisEvent; 666 ACPI_GPE_REGISTER_INFO *ThisRegister; 667 ACPI_NATIVE_UINT i; --- 25 unchanged lines hidden (view full) --- 693 sizeof (ACPI_GPE_EVENT_INFO)); 694 if (!GpeEventInfo) 695 { 696 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not allocate the GpeEventInfo table\n")); 697 Status = AE_NO_MEMORY; 698 goto ErrorExit; 699 } 700 |
701 /* Save the new Info arrays in the GPE block */ 702 703 GpeBlock->RegisterInfo = GpeRegisterInfo; 704 GpeBlock->EventInfo = GpeEventInfo; 705 |
|
345 /* 346 * Initialize the GPE Register and Event structures. A goal of these 347 * tables is to hide the fact that there are two separate GPE register sets 348 * in a given gpe hardware block, the status registers occupy the first half, | 706 /* 707 * Initialize the GPE Register and Event structures. A goal of these 708 * tables is to hide the fact that there are two separate GPE register sets 709 * in a given gpe hardware block, the status registers occupy the first half, |
349 * and the enable registers occupy the second half. Another goal is to hide 350 * the fact that there may be multiple GPE hardware blocks. | 710 * and the enable registers occupy the second half. |
351 */ 352 ThisRegister = GpeRegisterInfo; 353 ThisEvent = GpeEventInfo; 354 355 for (i = 0; i < GpeBlock->RegisterCount; i++) 356 { 357 /* Init the RegisterInfo for this GPE register (8 GPEs) */ 358 --- 26 unchanged lines hidden (view full) --- 385 } 386 387 /* 388 * Clear the status/enable registers. Note that status registers 389 * are cleared by writing a '1', while enable registers are cleared 390 * by writing a '0'. 391 */ 392 Status = AcpiHwLowLevelWrite (ACPI_GPE_REGISTER_WIDTH, 0x00, | 711 */ 712 ThisRegister = GpeRegisterInfo; 713 ThisEvent = GpeEventInfo; 714 715 for (i = 0; i < GpeBlock->RegisterCount; i++) 716 { 717 /* Init the RegisterInfo for this GPE register (8 GPEs) */ 718 --- 26 unchanged lines hidden (view full) --- 745 } 746 747 /* 748 * Clear the status/enable registers. Note that status registers 749 * are cleared by writing a '1', while enable registers are cleared 750 * by writing a '0'. 751 */ 752 Status = AcpiHwLowLevelWrite (ACPI_GPE_REGISTER_WIDTH, 0x00, |
393 &ThisRegister->EnableAddress, 0); | 753 &ThisRegister->EnableAddress); |
394 if (ACPI_FAILURE (Status)) 395 { 396 goto ErrorExit; 397 } 398 399 Status = AcpiHwLowLevelWrite (ACPI_GPE_REGISTER_WIDTH, 0xFF, | 754 if (ACPI_FAILURE (Status)) 755 { 756 goto ErrorExit; 757 } 758 759 Status = AcpiHwLowLevelWrite (ACPI_GPE_REGISTER_WIDTH, 0xFF, |
400 &ThisRegister->StatusAddress, 0); | 760 &ThisRegister->StatusAddress); |
401 if (ACPI_FAILURE (Status)) 402 { 403 goto ErrorExit; 404 } 405 406 ThisRegister++; 407 } 408 | 761 if (ACPI_FAILURE (Status)) 762 { 763 goto ErrorExit; 764 } 765 766 ThisRegister++; 767 } 768 |
409 GpeBlock->RegisterInfo = GpeRegisterInfo; 410 GpeBlock->EventInfo = GpeEventInfo; 411 | |
412 return_ACPI_STATUS (AE_OK); 413 414 415ErrorExit: | 769 return_ACPI_STATUS (AE_OK); 770 771 772ErrorExit: |
416 | |
417 if (GpeRegisterInfo) 418 { 419 ACPI_MEM_FREE (GpeRegisterInfo); 420 } 421 if (GpeEventInfo) 422 { 423 ACPI_MEM_FREE (GpeEventInfo); 424 } 425 | 773 if (GpeRegisterInfo) 774 { 775 ACPI_MEM_FREE (GpeRegisterInfo); 776 } 777 if (GpeEventInfo) 778 { 779 ACPI_MEM_FREE (GpeEventInfo); 780 } 781 |
426 return_ACPI_STATUS (AE_OK); | 782 return_ACPI_STATUS (Status); |
427} 428 429 430/******************************************************************************* 431 * 432 * FUNCTION: AcpiEvCreateGpeBlock 433 * | 783} 784 785 786/******************************************************************************* 787 * 788 * FUNCTION: AcpiEvCreateGpeBlock 789 * |
434 * PARAMETERS: TBD | 790 * PARAMETERS: GpeDevice - Handle to the parent GPE block 791 * GpeBlockAddress - Address and SpaceID 792 * RegisterCount - Number of GPE register pairs in the block 793 * GpeBlockBaseNumber - Starting GPE number for the block 794 * InterruptLevel - H/W interrupt for the block 795 * ReturnGpeBlock - Where the new block descriptor is returned |
435 * 436 * RETURN: Status 437 * 438 * DESCRIPTION: Create and Install a block of GPE registers 439 * 440 ******************************************************************************/ 441 442ACPI_STATUS 443AcpiEvCreateGpeBlock ( | 796 * 797 * RETURN: Status 798 * 799 * DESCRIPTION: Create and Install a block of GPE registers 800 * 801 ******************************************************************************/ 802 803ACPI_STATUS 804AcpiEvCreateGpeBlock ( |
444 char *Pathname, | 805 ACPI_NAMESPACE_NODE *GpeDevice, |
445 ACPI_GENERIC_ADDRESS *GpeBlockAddress, 446 UINT32 RegisterCount, 447 UINT8 GpeBlockBaseNumber, | 806 ACPI_GENERIC_ADDRESS *GpeBlockAddress, 807 UINT32 RegisterCount, 808 UINT8 GpeBlockBaseNumber, |
448 UINT32 InterruptLevel) | 809 UINT32 InterruptLevel, 810 ACPI_GPE_BLOCK_INFO **ReturnGpeBlock) |
449{ 450 ACPI_GPE_BLOCK_INFO *GpeBlock; 451 ACPI_STATUS Status; | 811{ 812 ACPI_GPE_BLOCK_INFO *GpeBlock; 813 ACPI_STATUS Status; |
452 ACPI_HANDLE ObjHandle; | |
453 454 455 ACPI_FUNCTION_TRACE ("EvCreateGpeBlock"); 456 457 458 if (!RegisterCount) 459 { 460 return_ACPI_STATUS (AE_OK); 461 } 462 | 814 815 816 ACPI_FUNCTION_TRACE ("EvCreateGpeBlock"); 817 818 819 if (!RegisterCount) 820 { 821 return_ACPI_STATUS (AE_OK); 822 } 823 |
463 /* Get a handle to the parent object for this GPE block */ 464 465 Status = AcpiGetHandle (NULL, Pathname, &ObjHandle); 466 if (ACPI_FAILURE (Status)) 467 { 468 return_ACPI_STATUS (Status); 469 } 470 | |
471 /* Allocate a new GPE block */ 472 473 GpeBlock = ACPI_MEM_CALLOCATE (sizeof (ACPI_GPE_BLOCK_INFO)); 474 if (!GpeBlock) 475 { 476 return_ACPI_STATUS (AE_NO_MEMORY); 477 } 478 --- 9 unchanged lines hidden (view full) --- 488 Status = AcpiEvCreateGpeInfoBlocks (GpeBlock); 489 if (ACPI_FAILURE (Status)) 490 { 491 ACPI_MEM_FREE (GpeBlock); 492 return_ACPI_STATUS (Status); 493 } 494 495 /* Install the new block in the global list(s) */ | 824 /* Allocate a new GPE block */ 825 826 GpeBlock = ACPI_MEM_CALLOCATE (sizeof (ACPI_GPE_BLOCK_INFO)); 827 if (!GpeBlock) 828 { 829 return_ACPI_STATUS (AE_NO_MEMORY); 830 } 831 --- 9 unchanged lines hidden (view full) --- 841 Status = AcpiEvCreateGpeInfoBlocks (GpeBlock); 842 if (ACPI_FAILURE (Status)) 843 { 844 ACPI_MEM_FREE (GpeBlock); 845 return_ACPI_STATUS (Status); 846 } 847 848 /* Install the new block in the global list(s) */ |
496 /* TBD: Install block in the interrupt handler list */ | |
497 | 849 |
498 Status = AcpiEvInstallGpeBlock (GpeBlock); | 850 Status = AcpiEvInstallGpeBlock (GpeBlock, InterruptLevel); |
499 if (ACPI_FAILURE (Status)) 500 { 501 ACPI_MEM_FREE (GpeBlock); 502 return_ACPI_STATUS (Status); 503 } 504 505 /* Dump info about this GPE block */ 506 | 851 if (ACPI_FAILURE (Status)) 852 { 853 ACPI_MEM_FREE (GpeBlock); 854 return_ACPI_STATUS (Status); 855 } 856 857 /* Dump info about this GPE block */ 858 |
507 ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "GPE Block: %X registers at %8.8X%8.8X\n", | 859 ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "GPE %02d to %02d [%4.4s] %d regs at %8.8X%8.8X on int %d\n", 860 GpeBlock->BlockBaseNumber, 861 (UINT32) (GpeBlock->BlockBaseNumber + 862 ((GpeBlock->RegisterCount * ACPI_GPE_REGISTER_WIDTH) -1)), 863 GpeDevice->Name.Ascii, |
508 GpeBlock->RegisterCount, 509 ACPI_HIDWORD (ACPI_GET_ADDRESS (GpeBlock->BlockAddress.Address)), | 864 GpeBlock->RegisterCount, 865 ACPI_HIDWORD (ACPI_GET_ADDRESS (GpeBlock->BlockAddress.Address)), |
510 ACPI_LODWORD (ACPI_GET_ADDRESS (GpeBlock->BlockAddress.Address)))); | 866 ACPI_LODWORD (ACPI_GET_ADDRESS (GpeBlock->BlockAddress.Address)), 867 InterruptLevel)); |
511 | 868 |
512 ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "GPE Block defined as GPE%d to GPE%d\n", 513 GpeBlock->BlockBaseNumber, 514 (UINT32) (GpeBlock->BlockBaseNumber + 515 ((GpeBlock->RegisterCount * ACPI_GPE_REGISTER_WIDTH) -1)))); 516 | |
517 /* Find all GPE methods (_Lxx, _Exx) for this block */ 518 | 869 /* Find all GPE methods (_Lxx, _Exx) for this block */ 870 |
519 Status = AcpiWalkNamespace (ACPI_TYPE_METHOD, ObjHandle, 520 ACPI_UINT32_MAX, AcpiEvSaveMethodInfo, | 871 Status = AcpiNsWalkNamespace (ACPI_TYPE_METHOD, GpeDevice, 872 ACPI_UINT32_MAX, ACPI_NS_WALK_NO_UNLOCK, AcpiEvSaveMethodInfo, |
521 GpeBlock, NULL); 522 | 873 GpeBlock, NULL); 874 |
875 /* Return the new block */ 876 877 if (ReturnGpeBlock) 878 { 879 (*ReturnGpeBlock) = GpeBlock; 880 } 881 |
|
523 return_ACPI_STATUS (AE_OK); 524} 525 526 527/******************************************************************************* 528 * 529 * FUNCTION: AcpiEvGpeInitialize 530 * --- 6 unchanged lines hidden (view full) --- 537 ******************************************************************************/ 538 539ACPI_STATUS 540AcpiEvGpeInitialize (void) 541{ 542 UINT32 RegisterCount0 = 0; 543 UINT32 RegisterCount1 = 0; 544 UINT32 GpeNumberMax = 0; | 882 return_ACPI_STATUS (AE_OK); 883} 884 885 886/******************************************************************************* 887 * 888 * FUNCTION: AcpiEvGpeInitialize 889 * --- 6 unchanged lines hidden (view full) --- 896 ******************************************************************************/ 897 898ACPI_STATUS 899AcpiEvGpeInitialize (void) 900{ 901 UINT32 RegisterCount0 = 0; 902 UINT32 RegisterCount1 = 0; 903 UINT32 GpeNumberMax = 0; |
904 ACPI_HANDLE GpeDevice; 905 ACPI_STATUS Status; |
|
545 546 547 ACPI_FUNCTION_TRACE ("EvGpeInitialize"); 548 549 | 906 907 908 ACPI_FUNCTION_TRACE ("EvGpeInitialize"); 909 910 |
911 /* Get a handle to the predefined _GPE object */ 912 913 Status = AcpiGetHandle (NULL, "\\_GPE", &GpeDevice); 914 if (ACPI_FAILURE (Status)) 915 { 916 return_ACPI_STATUS (Status); 917 } 918 |
|
550 /* 551 * Initialize the GPE Blocks defined in the FADT 552 * 553 * Why the GPE register block lengths are divided by 2: From the ACPI Spec, 554 * section "General-Purpose Event Registers", we have: 555 * 556 * "Each register block contains two registers of equal length 557 * GPEx_STS and GPEx_EN (where x is 0 or 1). The length of the --- 5 unchanged lines hidden (view full) --- 563 * to be the same size." 564 */ 565 566 /* 567 * Determine the maximum GPE number for this machine. 568 * 569 * Note: both GPE0 and GPE1 are optional, and either can exist without 570 * the other. | 919 /* 920 * Initialize the GPE Blocks defined in the FADT 921 * 922 * Why the GPE register block lengths are divided by 2: From the ACPI Spec, 923 * section "General-Purpose Event Registers", we have: 924 * 925 * "Each register block contains two registers of equal length 926 * GPEx_STS and GPEx_EN (where x is 0 or 1). The length of the --- 5 unchanged lines hidden (view full) --- 932 * to be the same size." 933 */ 934 935 /* 936 * Determine the maximum GPE number for this machine. 937 * 938 * Note: both GPE0 and GPE1 are optional, and either can exist without 939 * the other. |
940 * |
|
571 * If EITHER the register length OR the block address are zero, then that 572 * particular block is not supported. 573 */ 574 if (AcpiGbl_FADT->Gpe0BlkLen && 575 ACPI_GET_ADDRESS (AcpiGbl_FADT->XGpe0Blk.Address)) 576 { 577 /* GPE block 0 exists (has both length and address > 0) */ 578 579 RegisterCount0 = (UINT16) (AcpiGbl_FADT->Gpe0BlkLen / 2); 580 581 GpeNumberMax = (RegisterCount0 * ACPI_GPE_REGISTER_WIDTH) - 1; 582 | 941 * If EITHER the register length OR the block address are zero, then that 942 * particular block is not supported. 943 */ 944 if (AcpiGbl_FADT->Gpe0BlkLen && 945 ACPI_GET_ADDRESS (AcpiGbl_FADT->XGpe0Blk.Address)) 946 { 947 /* GPE block 0 exists (has both length and address > 0) */ 948 949 RegisterCount0 = (UINT16) (AcpiGbl_FADT->Gpe0BlkLen / 2); 950 951 GpeNumberMax = (RegisterCount0 * ACPI_GPE_REGISTER_WIDTH) - 1; 952 |
583 AcpiEvCreateGpeBlock ("\\_GPE", &AcpiGbl_FADT->XGpe0Blk, 584 RegisterCount0, 0, AcpiGbl_FADT->SciInt); | 953 /* Install GPE Block 0 */ 954 955 Status = AcpiEvCreateGpeBlock (GpeDevice, &AcpiGbl_FADT->XGpe0Blk, 956 RegisterCount0, 0, AcpiGbl_FADT->SciInt, &AcpiGbl_GpeFadtBlocks[0]); 957 if (ACPI_FAILURE (Status)) 958 { 959 ACPI_REPORT_ERROR (( 960 "Could not create GPE Block 0, %s\n", 961 AcpiFormatException (Status))); 962 } |
585 } 586 587 if (AcpiGbl_FADT->Gpe1BlkLen && 588 ACPI_GET_ADDRESS (AcpiGbl_FADT->XGpe1Blk.Address)) 589 { 590 /* GPE block 1 exists (has both length and address > 0) */ 591 592 RegisterCount1 = (UINT16) (AcpiGbl_FADT->Gpe1BlkLen / 2); --- 10 unchanged lines hidden (view full) --- 603 ((RegisterCount1 * ACPI_GPE_REGISTER_WIDTH) - 1))); 604 605 /* Ignore GPE1 block by setting the register count to zero */ 606 607 RegisterCount1 = 0; 608 } 609 else 610 { | 963 } 964 965 if (AcpiGbl_FADT->Gpe1BlkLen && 966 ACPI_GET_ADDRESS (AcpiGbl_FADT->XGpe1Blk.Address)) 967 { 968 /* GPE block 1 exists (has both length and address > 0) */ 969 970 RegisterCount1 = (UINT16) (AcpiGbl_FADT->Gpe1BlkLen / 2); --- 10 unchanged lines hidden (view full) --- 981 ((RegisterCount1 * ACPI_GPE_REGISTER_WIDTH) - 1))); 982 983 /* Ignore GPE1 block by setting the register count to zero */ 984 985 RegisterCount1 = 0; 986 } 987 else 988 { |
611 AcpiEvCreateGpeBlock ("\\_GPE", &AcpiGbl_FADT->XGpe1Blk, 612 RegisterCount1, AcpiGbl_FADT->Gpe1Base, AcpiGbl_FADT->SciInt); | 989 /* Install GPE Block 1 */ |
613 | 990 |
991 Status = AcpiEvCreateGpeBlock (GpeDevice, &AcpiGbl_FADT->XGpe1Blk, 992 RegisterCount1, AcpiGbl_FADT->Gpe1Base, 993 AcpiGbl_FADT->SciInt, &AcpiGbl_GpeFadtBlocks[1]); 994 if (ACPI_FAILURE (Status)) 995 { 996 ACPI_REPORT_ERROR (( 997 "Could not create GPE Block 1, %s\n", 998 AcpiFormatException (Status))); 999 } 1000 |
|
614 /* | 1001 /* |
615 * GPE0 and GPE1 do not have to be contiguous in the GPE number space, 616 * But, GPE0 always starts at zero. | 1002 * GPE0 and GPE1 do not have to be contiguous in the GPE number 1003 * space. However, GPE0 always starts at GPE number zero. |
617 */ 618 GpeNumberMax = AcpiGbl_FADT->Gpe1Base + 619 ((RegisterCount1 * ACPI_GPE_REGISTER_WIDTH) - 1); 620 } 621 } 622 623 /* Exit if there are no GPE registers */ 624 --- 21 unchanged lines hidden --- | 1004 */ 1005 GpeNumberMax = AcpiGbl_FADT->Gpe1Base + 1006 ((RegisterCount1 * ACPI_GPE_REGISTER_WIDTH) - 1); 1007 } 1008 } 1009 1010 /* Exit if there are no GPE registers */ 1011 --- 21 unchanged lines hidden --- |