Deleted Added
full compact
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 ---