Print this page
update to acpica-unix2-20140114
update to acpica-unix2-20130927
acpica-unix2-20130823
PANKOVs restructure
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/intel/io/acpica/events/evgpe.c
+++ new/usr/src/common/acpica/components/events/evgpe.c
1 1 /******************************************************************************
2 2 *
3 3 * Module Name: evgpe - General Purpose Event handling and dispatch
4 4 *
5 5 *****************************************************************************/
6 6
7 7 /*
8 - * Copyright (C) 2000 - 2011, Intel Corp.
8 + * Copyright (C) 2000 - 2014, Intel Corp.
9 9 * All rights reserved.
10 10 *
11 11 * Redistribution and use in source and binary forms, with or without
12 12 * modification, are permitted provided that the following conditions
13 13 * are met:
14 14 * 1. Redistributions of source code must retain the above copyright
15 15 * notice, this list of conditions, and the following disclaimer,
16 16 * without modification.
17 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 18 * substantially similar to the "NO WARRANTY" disclaimer below
19 19 * ("Disclaimer") and any redistribution must be conditioned upon
20 20 * including a substantially similar Disclaimer requirement for further
21 21 * binary redistribution.
22 22 * 3. Neither the names of the above-listed copyright holders nor the names
23 23 * of any contributors may be used to endorse or promote products derived
24 24 * from this software without specific prior written permission.
25 25 *
26 26 * Alternatively, this software may be distributed under the terms of the
27 27 * GNU General Public License ("GPL") version 2 as published by the Free
28 28 * Software Foundation.
29 29 *
30 30 * NO WARRANTY
31 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 41 * POSSIBILITY OF SUCH DAMAGES.
↓ open down ↓ |
23 lines elided |
↑ open up ↑ |
42 42 */
43 43
44 44 #include "acpi.h"
45 45 #include "accommon.h"
46 46 #include "acevents.h"
47 47 #include "acnamesp.h"
48 48
49 49 #define _COMPONENT ACPI_EVENTS
50 50 ACPI_MODULE_NAME ("evgpe")
51 51
52 +#if (!ACPI_REDUCED_HARDWARE) /* Entire module */
53 +
52 54 /* Local prototypes */
53 55
54 56 static void ACPI_SYSTEM_XFACE
55 57 AcpiEvAsynchExecuteGpeMethod (
56 58 void *Context);
57 59
58 60 static void ACPI_SYSTEM_XFACE
59 61 AcpiEvAsynchEnableGpe (
60 62 void *Context);
61 63
62 64
63 65 /*******************************************************************************
64 66 *
65 67 * FUNCTION: AcpiEvUpdateGpeEnableMask
66 68 *
67 69 * PARAMETERS: GpeEventInfo - GPE to update
68 70 *
69 71 * RETURN: Status
70 72 *
71 73 * DESCRIPTION: Updates GPE register enable mask based upon whether there are
72 74 * runtime references to this GPE
73 75 *
74 76 ******************************************************************************/
75 77
76 78 ACPI_STATUS
77 79 AcpiEvUpdateGpeEnableMask (
78 80 ACPI_GPE_EVENT_INFO *GpeEventInfo)
79 81 {
80 82 ACPI_GPE_REGISTER_INFO *GpeRegisterInfo;
81 83 UINT32 RegisterBit;
82 84
↓ open down ↓ |
21 lines elided |
↑ open up ↑ |
83 85
84 86 ACPI_FUNCTION_TRACE (EvUpdateGpeEnableMask);
85 87
86 88
87 89 GpeRegisterInfo = GpeEventInfo->RegisterInfo;
88 90 if (!GpeRegisterInfo)
89 91 {
90 92 return_ACPI_STATUS (AE_NOT_EXIST);
91 93 }
92 94
93 - RegisterBit = AcpiHwGetGpeRegisterBit (GpeEventInfo, GpeRegisterInfo);
95 + RegisterBit = AcpiHwGetGpeRegisterBit (GpeEventInfo);
94 96
95 97 /* Clear the run bit up front */
96 98
97 99 ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForRun, RegisterBit);
98 100
99 101 /* Set the mask bit only if there are references to this GPE */
100 102
101 103 if (GpeEventInfo->RuntimeCount)
102 104 {
103 105 ACPI_SET_BIT (GpeRegisterInfo->EnableForRun, (UINT8) RegisterBit);
104 106 }
105 107
106 108 return_ACPI_STATUS (AE_OK);
107 109 }
108 110
109 111
110 112 /*******************************************************************************
111 113 *
112 114 * FUNCTION: AcpiEvEnableGpe
113 115 *
114 116 * PARAMETERS: GpeEventInfo - GPE to enable
115 117 *
116 118 * RETURN: Status
117 119 *
118 120 * DESCRIPTION: Clear a GPE of stale events and enable it.
119 121 *
120 122 ******************************************************************************/
121 123
122 124 ACPI_STATUS
123 125 AcpiEvEnableGpe (
124 126 ACPI_GPE_EVENT_INFO *GpeEventInfo)
125 127 {
126 128 ACPI_STATUS Status;
127 129
128 130
129 131 ACPI_FUNCTION_TRACE (EvEnableGpe);
130 132
131 133
132 134 /*
133 135 * We will only allow a GPE to be enabled if it has either an associated
134 136 * method (_Lxx/_Exx) or a handler, or is using the implicit notify
135 137 * feature. Otherwise, the GPE will be immediately disabled by
136 138 * AcpiEvGpeDispatch the first time it fires.
137 139 */
138 140 if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) ==
139 141 ACPI_GPE_DISPATCH_NONE)
140 142 {
141 143 return_ACPI_STATUS (AE_NO_HANDLER);
142 144 }
143 145
144 146 /* Clear the GPE (of stale events) */
145 147
146 148 Status = AcpiHwClearGpe (GpeEventInfo);
147 149 if (ACPI_FAILURE (Status))
148 150 {
149 151 return_ACPI_STATUS (Status);
150 152 }
151 153
152 154 /* Enable the requested GPE */
153 155
154 156 Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_ENABLE);
155 157 return_ACPI_STATUS (Status);
156 158 }
157 159
158 160
159 161 /*******************************************************************************
160 162 *
161 163 * FUNCTION: AcpiEvAddGpeReference
162 164 *
163 165 * PARAMETERS: GpeEventInfo - Add a reference to this GPE
164 166 *
165 167 * RETURN: Status
166 168 *
167 169 * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is
168 170 * hardware-enabled.
169 171 *
170 172 ******************************************************************************/
171 173
172 174 ACPI_STATUS
173 175 AcpiEvAddGpeReference (
174 176 ACPI_GPE_EVENT_INFO *GpeEventInfo)
175 177 {
176 178 ACPI_STATUS Status = AE_OK;
177 179
178 180
179 181 ACPI_FUNCTION_TRACE (EvAddGpeReference);
180 182
181 183
182 184 if (GpeEventInfo->RuntimeCount == ACPI_UINT8_MAX)
183 185 {
184 186 return_ACPI_STATUS (AE_LIMIT);
185 187 }
186 188
187 189 GpeEventInfo->RuntimeCount++;
188 190 if (GpeEventInfo->RuntimeCount == 1)
189 191 {
190 192 /* Enable on first reference */
191 193
192 194 Status = AcpiEvUpdateGpeEnableMask (GpeEventInfo);
193 195 if (ACPI_SUCCESS (Status))
194 196 {
195 197 Status = AcpiEvEnableGpe (GpeEventInfo);
196 198 }
197 199
198 200 if (ACPI_FAILURE (Status))
199 201 {
200 202 GpeEventInfo->RuntimeCount--;
201 203 }
202 204 }
203 205
204 206 return_ACPI_STATUS (Status);
205 207 }
206 208
207 209
208 210 /*******************************************************************************
209 211 *
210 212 * FUNCTION: AcpiEvRemoveGpeReference
211 213 *
212 214 * PARAMETERS: GpeEventInfo - Remove a reference to this GPE
213 215 *
214 216 * RETURN: Status
215 217 *
216 218 * DESCRIPTION: Remove a reference to a GPE. When the last reference is
217 219 * removed, the GPE is hardware-disabled.
218 220 *
219 221 ******************************************************************************/
220 222
221 223 ACPI_STATUS
222 224 AcpiEvRemoveGpeReference (
223 225 ACPI_GPE_EVENT_INFO *GpeEventInfo)
224 226 {
225 227 ACPI_STATUS Status = AE_OK;
226 228
227 229
228 230 ACPI_FUNCTION_TRACE (EvRemoveGpeReference);
229 231
230 232
231 233 if (!GpeEventInfo->RuntimeCount)
232 234 {
233 235 return_ACPI_STATUS (AE_LIMIT);
234 236 }
235 237
236 238 GpeEventInfo->RuntimeCount--;
237 239 if (!GpeEventInfo->RuntimeCount)
238 240 {
239 241 /* Disable on last reference */
240 242
241 243 Status = AcpiEvUpdateGpeEnableMask (GpeEventInfo);
242 244 if (ACPI_SUCCESS (Status))
243 245 {
244 246 Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_DISABLE);
245 247 }
246 248
247 249 if (ACPI_FAILURE (Status))
248 250 {
249 251 GpeEventInfo->RuntimeCount++;
250 252 }
251 253 }
252 254
253 255 return_ACPI_STATUS (Status);
254 256 }
255 257
256 258
257 259 /*******************************************************************************
258 260 *
259 261 * FUNCTION: AcpiEvLowGetGpeInfo
260 262 *
261 263 * PARAMETERS: GpeNumber - Raw GPE number
262 264 * GpeBlock - A GPE info block
263 265 *
264 266 * RETURN: A GPE EventInfo struct. NULL if not a valid GPE (The GpeNumber
265 267 * is not within the specified GPE block)
266 268 *
267 269 * DESCRIPTION: Returns the EventInfo struct associated with this GPE. This is
268 270 * the low-level implementation of EvGetGpeEventInfo.
269 271 *
270 272 ******************************************************************************/
271 273
272 274 ACPI_GPE_EVENT_INFO *
273 275 AcpiEvLowGetGpeInfo (
274 276 UINT32 GpeNumber,
275 277 ACPI_GPE_BLOCK_INFO *GpeBlock)
276 278 {
277 279 UINT32 GpeIndex;
278 280
279 281
280 282 /*
281 283 * Validate that the GpeNumber is within the specified GpeBlock.
282 284 * (Two steps)
283 285 */
284 286 if (!GpeBlock ||
285 287 (GpeNumber < GpeBlock->BlockBaseNumber))
286 288 {
287 289 return (NULL);
288 290 }
289 291
290 292 GpeIndex = GpeNumber - GpeBlock->BlockBaseNumber;
291 293 if (GpeIndex >= GpeBlock->GpeCount)
292 294 {
293 295 return (NULL);
294 296 }
295 297
296 298 return (&GpeBlock->EventInfo[GpeIndex]);
297 299 }
298 300
299 301
300 302 /*******************************************************************************
301 303 *
302 304 * FUNCTION: AcpiEvGetGpeEventInfo
303 305 *
304 306 * PARAMETERS: GpeDevice - Device node. NULL for GPE0/GPE1
305 307 * GpeNumber - Raw GPE number
306 308 *
307 309 * RETURN: A GPE EventInfo struct. NULL if not a valid GPE
308 310 *
309 311 * DESCRIPTION: Returns the EventInfo struct associated with this GPE.
310 312 * Validates the GpeBlock and the GpeNumber
311 313 *
312 314 * Should be called only when the GPE lists are semaphore locked
313 315 * and not subject to change.
314 316 *
315 317 ******************************************************************************/
316 318
317 319 ACPI_GPE_EVENT_INFO *
318 320 AcpiEvGetGpeEventInfo (
319 321 ACPI_HANDLE GpeDevice,
320 322 UINT32 GpeNumber)
321 323 {
322 324 ACPI_OPERAND_OBJECT *ObjDesc;
323 325 ACPI_GPE_EVENT_INFO *GpeInfo;
324 326 UINT32 i;
325 327
326 328
327 329 ACPI_FUNCTION_ENTRY ();
328 330
329 331
330 332 /* A NULL GpeDevice means use the FADT-defined GPE block(s) */
331 333
332 334 if (!GpeDevice)
333 335 {
334 336 /* Examine GPE Block 0 and 1 (These blocks are permanent) */
335 337
336 338 for (i = 0; i < ACPI_MAX_GPE_BLOCKS; i++)
337 339 {
338 340 GpeInfo = AcpiEvLowGetGpeInfo (GpeNumber,
339 341 AcpiGbl_GpeFadtBlocks[i]);
340 342 if (GpeInfo)
341 343 {
342 344 return (GpeInfo);
343 345 }
344 346 }
345 347
346 348 /* The GpeNumber was not in the range of either FADT GPE block */
347 349
348 350 return (NULL);
349 351 }
350 352
351 353 /* A Non-NULL GpeDevice means this is a GPE Block Device */
352 354
353 355 ObjDesc = AcpiNsGetAttachedObject ((ACPI_NAMESPACE_NODE *) GpeDevice);
354 356 if (!ObjDesc ||
355 357 !ObjDesc->Device.GpeBlock)
356 358 {
357 359 return (NULL);
358 360 }
359 361
360 362 return (AcpiEvLowGetGpeInfo (GpeNumber, ObjDesc->Device.GpeBlock));
361 363 }
362 364
363 365
364 366 /*******************************************************************************
365 367 *
366 368 * FUNCTION: AcpiEvGpeDetect
367 369 *
368 370 * PARAMETERS: GpeXruptList - Interrupt block for this interrupt.
369 371 * Can have multiple GPE blocks attached.
370 372 *
371 373 * RETURN: INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED
372 374 *
373 375 * DESCRIPTION: Detect if any GP events have occurred. This function is
374 376 * executed at interrupt level.
375 377 *
376 378 ******************************************************************************/
377 379
378 380 UINT32
379 381 AcpiEvGpeDetect (
380 382 ACPI_GPE_XRUPT_INFO *GpeXruptList)
381 383 {
382 384 ACPI_STATUS Status;
383 385 ACPI_GPE_BLOCK_INFO *GpeBlock;
384 386 ACPI_GPE_REGISTER_INFO *GpeRegisterInfo;
385 387 UINT32 IntStatus = ACPI_INTERRUPT_NOT_HANDLED;
386 388 UINT8 EnabledStatusByte;
387 389 UINT32 StatusReg;
388 390 UINT32 EnableReg;
389 391 ACPI_CPU_FLAGS Flags;
390 392 UINT32 i;
391 393 UINT32 j;
392 394
393 395
394 396 ACPI_FUNCTION_NAME (EvGpeDetect);
395 397
396 398 /* Check for the case where there are no GPEs */
397 399
398 400 if (!GpeXruptList)
399 401 {
400 402 return (IntStatus);
401 403 }
402 404
403 405 /*
404 406 * We need to obtain the GPE lock for both the data structs and registers
405 407 * Note: Not necessary to obtain the hardware lock, since the GPE
406 408 * registers are owned by the GpeLock.
407 409 */
408 410 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
409 411
410 412 /* Examine all GPE blocks attached to this interrupt level */
411 413
412 414 GpeBlock = GpeXruptList->GpeBlockListHead;
413 415 while (GpeBlock)
414 416 {
415 417 /*
416 418 * Read all of the 8-bit GPE status and enable registers in this GPE
417 419 * block, saving all of them. Find all currently active GP events.
418 420 */
419 421 for (i = 0; i < GpeBlock->RegisterCount; i++)
420 422 {
421 423 /* Get the next status/enable pair */
↓ open down ↓ |
318 lines elided |
↑ open up ↑ |
422 424
423 425 GpeRegisterInfo = &GpeBlock->RegisterInfo[i];
424 426
425 427 /*
426 428 * Optimization: If there are no GPEs enabled within this
427 429 * register, we can safely ignore the entire register.
428 430 */
429 431 if (!(GpeRegisterInfo->EnableForRun |
430 432 GpeRegisterInfo->EnableForWake))
431 433 {
434 + ACPI_DEBUG_PRINT ((ACPI_DB_INTERRUPTS,
435 + "Ignore disabled registers for GPE%02X-GPE%02X: "
436 + "RunEnable=%02X, WakeEnable=%02X\n",
437 + GpeRegisterInfo->BaseGpeNumber,
438 + GpeRegisterInfo->BaseGpeNumber + (ACPI_GPE_REGISTER_WIDTH - 1),
439 + GpeRegisterInfo->EnableForRun,
440 + GpeRegisterInfo->EnableForWake));
432 441 continue;
433 442 }
434 443
435 444 /* Read the Status Register */
436 445
437 446 Status = AcpiHwRead (&StatusReg, &GpeRegisterInfo->StatusAddress);
438 447 if (ACPI_FAILURE (Status))
439 448 {
440 449 goto UnlockAndExit;
441 450 }
442 451
443 452 /* Read the Enable Register */
444 453
445 454 Status = AcpiHwRead (&EnableReg, &GpeRegisterInfo->EnableAddress);
446 455 if (ACPI_FAILURE (Status))
447 456 {
448 457 goto UnlockAndExit;
449 458 }
450 459
451 460 ACPI_DEBUG_PRINT ((ACPI_DB_INTERRUPTS,
452 - "Read GPE Register at GPE%02X: Status=%02X, Enable=%02X\n",
453 - GpeRegisterInfo->BaseGpeNumber, StatusReg, EnableReg));
461 + "Read registers for GPE%02X-GPE%02X: Status=%02X, Enable=%02X, "
462 + "RunEnable=%02X, WakeEnable=%02X\n",
463 + GpeRegisterInfo->BaseGpeNumber,
464 + GpeRegisterInfo->BaseGpeNumber + (ACPI_GPE_REGISTER_WIDTH - 1),
465 + StatusReg, EnableReg,
466 + GpeRegisterInfo->EnableForRun,
467 + GpeRegisterInfo->EnableForWake));
454 468
455 469 /* Check if there is anything active at all in this register */
456 470
457 471 EnabledStatusByte = (UINT8) (StatusReg & EnableReg);
458 472 if (!EnabledStatusByte)
459 473 {
460 474 /* No active GPEs in this register, move on */
461 475
462 476 continue;
463 477 }
464 478
465 479 /* Now look at the individual GPEs in this byte register */
466 480
467 481 for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++)
468 482 {
469 483 /* Examine one GPE bit */
470 484
471 485 if (EnabledStatusByte & (1 << j))
472 486 {
473 487 /*
474 488 * Found an active GPE. Dispatch the event to a handler
475 489 * or method.
476 490 */
477 491 IntStatus |= AcpiEvGpeDispatch (GpeBlock->Node,
478 492 &GpeBlock->EventInfo[((ACPI_SIZE) i *
479 493 ACPI_GPE_REGISTER_WIDTH) + j],
480 494 j + GpeRegisterInfo->BaseGpeNumber);
481 495 }
482 496 }
483 497 }
484 498
485 499 GpeBlock = GpeBlock->Next;
486 500 }
487 501
488 502 UnlockAndExit:
489 503
490 504 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
491 505 return (IntStatus);
492 506 }
493 507
494 508
495 509 /*******************************************************************************
496 510 *
497 511 * FUNCTION: AcpiEvAsynchExecuteGpeMethod
498 512 *
499 513 * PARAMETERS: Context (GpeEventInfo) - Info for this GPE
500 514 *
501 515 * RETURN: None
502 516 *
503 517 * DESCRIPTION: Perform the actual execution of a GPE control method. This
504 518 * function is called from an invocation of AcpiOsExecute and
505 519 * therefore does NOT execute at interrupt level - so that
506 520 * the control method itself is not executed in the context of
507 521 * an interrupt handler.
508 522 *
↓ open down ↓ |
45 lines elided |
↑ open up ↑ |
509 523 ******************************************************************************/
510 524
511 525 static void ACPI_SYSTEM_XFACE
512 526 AcpiEvAsynchExecuteGpeMethod (
513 527 void *Context)
514 528 {
515 529 ACPI_GPE_EVENT_INFO *GpeEventInfo = Context;
516 530 ACPI_STATUS Status;
517 531 ACPI_GPE_EVENT_INFO *LocalGpeEventInfo;
518 532 ACPI_EVALUATE_INFO *Info;
533 + ACPI_GPE_NOTIFY_INFO *Notify;
519 534
520 535
521 536 ACPI_FUNCTION_TRACE (EvAsynchExecuteGpeMethod);
522 537
523 538
524 539 /* Allocate a local GPE block */
525 540
526 541 LocalGpeEventInfo = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_GPE_EVENT_INFO));
527 542 if (!LocalGpeEventInfo)
528 543 {
529 544 ACPI_EXCEPTION ((AE_INFO, AE_NO_MEMORY,
530 545 "while handling a GPE"));
531 546 return_VOID;
532 547 }
533 548
534 549 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
535 550 if (ACPI_FAILURE (Status))
536 551 {
552 + ACPI_FREE (LocalGpeEventInfo);
537 553 return_VOID;
538 554 }
539 555
540 556 /* Must revalidate the GpeNumber/GpeBlock */
541 557
542 558 if (!AcpiEvValidGpeEvent (GpeEventInfo))
543 559 {
544 560 Status = AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
561 + ACPI_FREE (LocalGpeEventInfo);
545 562 return_VOID;
546 563 }
547 564
548 565 /*
549 566 * Take a snapshot of the GPE info for this level - we copy the info to
550 567 * prevent a race condition with RemoveHandler/RemoveBlock.
551 568 */
552 569 ACPI_MEMCPY (LocalGpeEventInfo, GpeEventInfo,
553 570 sizeof (ACPI_GPE_EVENT_INFO));
554 571
555 572 Status = AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
556 573 if (ACPI_FAILURE (Status))
557 574 {
575 + ACPI_FREE (LocalGpeEventInfo);
558 576 return_VOID;
559 577 }
560 578
561 579 /* Do the correct dispatch - normal method or implicit notify */
562 580
563 581 switch (LocalGpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK)
564 582 {
565 583 case ACPI_GPE_DISPATCH_NOTIFY:
566 -
567 584 /*
568 585 * Implicit notify.
569 586 * Dispatch a DEVICE_WAKE notify to the appropriate handler.
570 587 * NOTE: the request is queued for execution after this method
571 588 * completes. The notify handlers are NOT invoked synchronously
572 589 * from this thread -- because handlers may in turn run other
573 590 * control methods.
591 + *
592 + * June 2012: Expand implicit notify mechanism to support
593 + * notifies on multiple device objects.
574 594 */
575 - Status = AcpiEvQueueNotifyRequest (
576 - LocalGpeEventInfo->Dispatch.DeviceNode,
577 - ACPI_NOTIFY_DEVICE_WAKE);
595 + Notify = LocalGpeEventInfo->Dispatch.NotifyList;
596 + while (ACPI_SUCCESS (Status) && Notify)
597 + {
598 + Status = AcpiEvQueueNotifyRequest (Notify->DeviceNode,
599 + ACPI_NOTIFY_DEVICE_WAKE);
600 +
601 + Notify = Notify->Next;
602 + }
578 603 break;
579 604
580 605 case ACPI_GPE_DISPATCH_METHOD:
581 606
582 607 /* Allocate the evaluation information block */
583 608
584 609 Info = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO));
585 610 if (!Info)
586 611 {
587 612 Status = AE_NO_MEMORY;
588 613 }
589 614 else
590 615 {
591 616 /*
592 617 * Invoke the GPE Method (_Lxx, _Exx) i.e., evaluate the
593 618 * _Lxx/_Exx control method that corresponds to this GPE
594 619 */
595 620 Info->PrefixNode = LocalGpeEventInfo->Dispatch.MethodNode;
596 621 Info->Flags = ACPI_IGNORE_RETURN_VALUE;
597 622
↓ open down ↓ |
10 lines elided |
↑ open up ↑ |
598 623 Status = AcpiNsEvaluate (Info);
599 624 ACPI_FREE (Info);
600 625 }
601 626
602 627 if (ACPI_FAILURE (Status))
603 628 {
604 629 ACPI_EXCEPTION ((AE_INFO, Status,
605 630 "while evaluating GPE method [%4.4s]",
606 631 AcpiUtGetNodeName (LocalGpeEventInfo->Dispatch.MethodNode)));
607 632 }
608 -
609 633 break;
610 634
611 635 default:
636 +
612 637 return_VOID; /* Should never happen */
613 638 }
614 639
615 640 /* Defer enabling of GPE until all notify handlers are done */
616 641
617 642 Status = AcpiOsExecute (OSL_NOTIFY_HANDLER,
618 643 AcpiEvAsynchEnableGpe, LocalGpeEventInfo);
619 644 if (ACPI_FAILURE (Status))
620 645 {
621 646 ACPI_FREE (LocalGpeEventInfo);
622 647 }
623 648 return_VOID;
624 649 }
625 650
626 651
627 652 /*******************************************************************************
628 653 *
629 654 * FUNCTION: AcpiEvAsynchEnableGpe
630 655 *
631 656 * PARAMETERS: Context (GpeEventInfo) - Info for this GPE
632 657 * Callback from AcpiOsExecute
633 658 *
634 659 * RETURN: None
635 660 *
636 661 * DESCRIPTION: Asynchronous clear/enable for GPE. This allows the GPE to
637 662 * complete (i.e., finish execution of Notify)
638 663 *
639 664 ******************************************************************************/
640 665
641 666 static void ACPI_SYSTEM_XFACE
642 667 AcpiEvAsynchEnableGpe (
643 668 void *Context)
644 669 {
645 670 ACPI_GPE_EVENT_INFO *GpeEventInfo = Context;
646 671
647 672
648 673 (void) AcpiEvFinishGpe (GpeEventInfo);
649 674
650 675 ACPI_FREE (GpeEventInfo);
651 676 return;
652 677 }
653 678
654 679
655 680 /*******************************************************************************
656 681 *
657 682 * FUNCTION: AcpiEvFinishGpe
658 683 *
659 684 * PARAMETERS: GpeEventInfo - Info for this GPE
660 685 *
661 686 * RETURN: Status
662 687 *
663 688 * DESCRIPTION: Clear/Enable a GPE. Common code that is used after execution
664 689 * of a GPE method or a synchronous or asynchronous GPE handler.
665 690 *
666 691 ******************************************************************************/
667 692
668 693 ACPI_STATUS
669 694 AcpiEvFinishGpe (
670 695 ACPI_GPE_EVENT_INFO *GpeEventInfo)
671 696 {
672 697 ACPI_STATUS Status;
673 698
674 699
675 700 if ((GpeEventInfo->Flags & ACPI_GPE_XRUPT_TYPE_MASK) ==
676 701 ACPI_GPE_LEVEL_TRIGGERED)
677 702 {
678 703 /*
679 704 * GPE is level-triggered, we clear the GPE status bit after
680 705 * handling the event.
681 706 */
682 707 Status = AcpiHwClearGpe (GpeEventInfo);
683 708 if (ACPI_FAILURE (Status))
684 709 {
685 710 return (Status);
686 711 }
687 712 }
688 713
689 714 /*
690 715 * Enable this GPE, conditionally. This means that the GPE will
691 716 * only be physically enabled if the EnableForRun bit is set
692 717 * in the EventInfo.
693 718 */
694 719 (void) AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_CONDITIONAL_ENABLE);
695 720 return (AE_OK);
696 721 }
697 722
698 723
699 724 /*******************************************************************************
700 725 *
701 726 * FUNCTION: AcpiEvGpeDispatch
702 727 *
703 728 * PARAMETERS: GpeDevice - Device node. NULL for GPE0/GPE1
704 729 * GpeEventInfo - Info for this GPE
705 730 * GpeNumber - Number relative to the parent GPE block
706 731 *
707 732 * RETURN: INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED
708 733 *
709 734 * DESCRIPTION: Dispatch a General Purpose Event to either a function (e.g. EC)
710 735 * or method (e.g. _Lxx/_Exx) handler.
711 736 *
712 737 * This function executes at interrupt level.
713 738 *
714 739 ******************************************************************************/
715 740
716 741 UINT32
717 742 AcpiEvGpeDispatch (
718 743 ACPI_NAMESPACE_NODE *GpeDevice,
719 744 ACPI_GPE_EVENT_INFO *GpeEventInfo,
720 745 UINT32 GpeNumber)
721 746 {
722 747 ACPI_STATUS Status;
723 748 UINT32 ReturnValue;
724 749
725 750
726 751 ACPI_FUNCTION_TRACE (EvGpeDispatch);
727 752
728 753
729 754 /* Invoke global event handler if present */
730 755
731 756 AcpiGpeCount++;
732 757 if (AcpiGbl_GlobalEventHandler)
733 758 {
734 759 AcpiGbl_GlobalEventHandler (ACPI_EVENT_TYPE_GPE, GpeDevice,
735 760 GpeNumber, AcpiGbl_GlobalEventHandlerContext);
736 761 }
737 762
738 763 /*
739 764 * If edge-triggered, clear the GPE status bit now. Note that
740 765 * level-triggered events are cleared after the GPE is serviced.
741 766 */
742 767 if ((GpeEventInfo->Flags & ACPI_GPE_XRUPT_TYPE_MASK) ==
743 768 ACPI_GPE_EDGE_TRIGGERED)
744 769 {
745 770 Status = AcpiHwClearGpe (GpeEventInfo);
746 771 if (ACPI_FAILURE (Status))
747 772 {
748 773 ACPI_EXCEPTION ((AE_INFO, Status,
749 774 "Unable to clear GPE%02X", GpeNumber));
750 775 return_UINT32 (ACPI_INTERRUPT_NOT_HANDLED);
751 776 }
752 777 }
753 778
754 779 /*
755 780 * Always disable the GPE so that it does not keep firing before
756 781 * any asynchronous activity completes (either from the execution
757 782 * of a GPE method or an asynchronous GPE handler.)
758 783 *
759 784 * If there is no handler or method to run, just disable the
760 785 * GPE and leave it disabled permanently to prevent further such
761 786 * pointless events from firing.
762 787 */
763 788 Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_DISABLE);
764 789 if (ACPI_FAILURE (Status))
765 790 {
766 791 ACPI_EXCEPTION ((AE_INFO, Status,
767 792 "Unable to disable GPE%02X", GpeNumber));
768 793 return_UINT32 (ACPI_INTERRUPT_NOT_HANDLED);
769 794 }
770 795
771 796 /*
772 797 * Dispatch the GPE to either an installed handler or the control
773 798 * method associated with this GPE (_Lxx or _Exx). If a handler
774 799 * exists, we invoke it and do not attempt to run the method.
775 800 * If there is neither a handler nor a method, leave the GPE
776 801 * disabled.
777 802 */
778 803 switch (GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK)
779 804 {
780 805 case ACPI_GPE_DISPATCH_HANDLER:
781 806
782 807 /* Invoke the installed handler (at interrupt level) */
783 808
784 809 ReturnValue = GpeEventInfo->Dispatch.Handler->Address (
785 810 GpeDevice, GpeNumber,
786 811 GpeEventInfo->Dispatch.Handler->Context);
787 812
↓ open down ↓ |
166 lines elided |
↑ open up ↑ |
788 813 /* If requested, clear (if level-triggered) and reenable the GPE */
789 814
790 815 if (ReturnValue & ACPI_REENABLE_GPE)
791 816 {
792 817 (void) AcpiEvFinishGpe (GpeEventInfo);
793 818 }
794 819 break;
795 820
796 821 case ACPI_GPE_DISPATCH_METHOD:
797 822 case ACPI_GPE_DISPATCH_NOTIFY:
798 -
799 823 /*
800 824 * Execute the method associated with the GPE
801 825 * NOTE: Level-triggered GPEs are cleared after the method completes.
802 826 */
803 827 Status = AcpiOsExecute (OSL_GPE_HANDLER,
804 828 AcpiEvAsynchExecuteGpeMethod, GpeEventInfo);
805 829 if (ACPI_FAILURE (Status))
806 830 {
807 831 ACPI_EXCEPTION ((AE_INFO, Status,
808 832 "Unable to queue handler for GPE%02X - event disabled",
809 833 GpeNumber));
810 834 }
811 835 break;
812 836
813 837 default:
814 -
815 838 /*
816 839 * No handler or method to run!
817 840 * 03/2010: This case should no longer be possible. We will not allow
818 841 * a GPE to be enabled if it has no handler or method.
819 842 */
820 843 ACPI_ERROR ((AE_INFO,
821 844 "No handler or method for GPE%02X, disabling event",
822 845 GpeNumber));
823 846 break;
824 847 }
825 848
826 849 return_UINT32 (ACPI_INTERRUPT_HANDLED);
827 850 }
828 851
852 +#endif /* !ACPI_REDUCED_HARDWARE */
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX