Subversion Repositories Kolibri OS

Rev

Rev 1498 | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1498 Rev 2216
Line 6... Line 6...
6
 
6
 
7
/******************************************************************************
7
/******************************************************************************
8
 *
8
 *
9
 * 1. Copyright Notice
9
 * 1. Copyright Notice
10
 *
10
 *
11
 * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp.
11
 * Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp.
12
 * All rights reserved.
12
 * All rights reserved.
13
 *
13
 *
14
 * 2. License
14
 * 2. License
15
 *
15
 *
Line 132... Line 132...
132
    void                    *Context);
132
    void                    *Context);
Line 133... Line 133...
133
 
133
 
134
 
134
 
135
/*******************************************************************************
135
/*******************************************************************************
136
 *
136
 *
137
 * FUNCTION:    AcpiEvUpdateGpeEnableMasks
137
 * FUNCTION:    AcpiEvUpdateGpeEnableMask
138
 *
138
 *
139
 * PARAMETERS:  GpeEventInfo            - GPE to update
139
 * PARAMETERS:  GpeEventInfo            - GPE to update
140
 *
140
 *
141
 * RETURN:      Status
141
 * RETURN:      Status
142
 *
142
 *
143
 * DESCRIPTION: Updates GPE register enable masks based upon whether there are
143
 * DESCRIPTION: Updates GPE register enable mask based upon whether there are
144
 *              references (either wake or run) to this GPE
144
 *              runtime references to this GPE
Line 145... Line 145...
145
 *
145
 *
146
 ******************************************************************************/
146
 ******************************************************************************/
147
 
147
 
148
ACPI_STATUS
148
ACPI_STATUS
149
AcpiEvUpdateGpeEnableMasks (
149
AcpiEvUpdateGpeEnableMask (
150
    ACPI_GPE_EVENT_INFO     *GpeEventInfo)
150
    ACPI_GPE_EVENT_INFO     *GpeEventInfo)
Line 151... Line 151...
151
{
151
{
Line 152... Line 152...
152
    ACPI_GPE_REGISTER_INFO  *GpeRegisterInfo;
152
    ACPI_GPE_REGISTER_INFO  *GpeRegisterInfo;
153
    UINT8                   RegisterBit;
153
    UINT32                  RegisterBit;
154
 
154
 
155
 
155
 
156
    ACPI_FUNCTION_TRACE (EvUpdateGpeEnableMasks);
156
    ACPI_FUNCTION_TRACE (EvUpdateGpeEnableMask);
Line 157... Line -...
157
 
-
 
158
 
157
 
Line 159... Line 158...
159
    GpeRegisterInfo = GpeEventInfo->RegisterInfo;
158
 
Line 160... Line -...
160
    if (!GpeRegisterInfo)
-
 
161
    {
159
    GpeRegisterInfo = GpeEventInfo->RegisterInfo;
Line 162... Line 160...
162
        return_ACPI_STATUS (AE_NOT_EXIST);
160
    if (!GpeRegisterInfo)
Line 163... Line 161...
163
    }
161
    {
164
 
162
        return_ACPI_STATUS (AE_NOT_EXIST);
165
    RegisterBit = (UINT8)
163
    }
166
        (1 << (GpeEventInfo->GpeNumber - GpeRegisterInfo->BaseGpeNumber));
-
 
167
 
-
 
168
    /* Clear the wake/run bits up front */
-
 
169
 
-
 
170
    ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForWake, RegisterBit);
-
 
171
    ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForRun, RegisterBit);
164
 
Line 172... Line 165...
172
 
165
    RegisterBit = AcpiHwGetGpeRegisterBit (GpeEventInfo, GpeRegisterInfo);
173
    /* Set the mask bits only if there are references to this GPE */
166
 
Line 192... Line 185...
192
 *
185
 *
193
 * PARAMETERS:  GpeEventInfo            - GPE to enable
186
 * PARAMETERS:  GpeEventInfo            - GPE to enable
194
 *
187
 *
195
 * RETURN:      Status
188
 * RETURN:      Status
196
 *
189
 *
197
 * DESCRIPTION: Hardware-enable a GPE. Always enables the GPE, regardless
190
 * DESCRIPTION: Clear a GPE of stale events and enable it.
198
 *              of type or number of references.
-
 
199
 *
-
 
200
 * Note: The GPE lock should be already acquired when this function is called.
-
 
201
 *
191
 *
202
 ******************************************************************************/
192
 ******************************************************************************/
Line 203... Line 193...
203
 
193
 
204
ACPI_STATUS
194
ACPI_STATUS
Line 210... Line 200...
210
 
200
 
Line 211... Line 201...
211
    ACPI_FUNCTION_TRACE (EvEnableGpe);
201
    ACPI_FUNCTION_TRACE (EvEnableGpe);
212
 
202
 
213
 
203
 
214
    /*
204
    /*
215
     * We will only allow a GPE to be enabled if it has either an
205
     * We will only allow a GPE to be enabled if it has either an associated
216
     * associated method (_Lxx/_Exx) or a handler. Otherwise, the
206
     * method (_Lxx/_Exx) or a handler, or is using the implicit notify
217
     * GPE will be immediately disabled by AcpiEvGpeDispatch the
207
     * feature. Otherwise, the GPE will be immediately disabled by
-
 
208
     * AcpiEvGpeDispatch the first time it fires.
218
     * first time it fires.
209
     */
219
     */
210
    if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) ==
220
    if (!(GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK))
211
        ACPI_GPE_DISPATCH_NONE)
Line 221... Line -...
221
    {
-
 
222
        return_ACPI_STATUS (AE_NO_HANDLER);
-
 
223
    }
-
 
224
 
-
 
225
    /* Ensure the HW enable masks are current */
-
 
226
 
-
 
227
    Status = AcpiEvUpdateGpeEnableMasks (GpeEventInfo);
-
 
228
    if (ACPI_FAILURE (Status))
-
 
229
    {
212
    {
Line 230... Line 213...
230
        return_ACPI_STATUS (Status);
213
        return_ACPI_STATUS (AE_NO_HANDLER);
231
    }
214
    }
232
 
215
 
233
    /* Clear the GPE (of stale events) */
216
    /* Clear the GPE (of stale events) */
234
 
217
 
Line 235... Line 218...
235
    Status = AcpiHwClearGpe (GpeEventInfo);
218
    Status = AcpiHwClearGpe (GpeEventInfo);
Line 236... Line 219...
236
    if (ACPI_FAILURE (Status))
219
    if (ACPI_FAILURE (Status))
237
    {
220
    {
238
        return_ACPI_STATUS (Status);
221
        return_ACPI_STATUS (Status);
Line 239... Line 222...
239
    }
222
    }
240
 
223
 
241
    /* Enable the requested GPE */
224
    /* Enable the requested GPE */
242
 
225
 
243
    Status = AcpiHwWriteGpeEnableReg (GpeEventInfo);
226
    Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_ENABLE);
244
    return_ACPI_STATUS (Status);
227
    return_ACPI_STATUS (Status);
245
}
228
}
246
 
229
 
247
 
230
 
248
/*******************************************************************************
231
/*******************************************************************************
249
 *
-
 
250
 * FUNCTION:    AcpiEvDisableGpe
-
 
251
 *
232
 *
252
 * PARAMETERS:  GpeEventInfo            - GPE to disable
233
 * FUNCTION:    AcpiEvAddGpeReference
Line 253... Line 234...
253
 *
234
 *
254
 * RETURN:      Status
235
 * PARAMETERS:  GpeEventInfo            - Add a reference to this GPE
255
 *
236
 *
256
 * DESCRIPTION: Hardware-disable a GPE. Always disables the requested GPE,
237
 * RETURN:      Status
257
 *              regardless of the type or number of references.
238
 *
Line 258... Line 239...
258
 *
239
 * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is
Line -... Line 240...
-
 
240
 *              hardware-enabled.
259
 * Note: The GPE lock should be already acquired when this function is called.
241
 *
260
 *
242
 ******************************************************************************/
-
 
243
 
-
 
244
ACPI_STATUS
261
 ******************************************************************************/
245
AcpiEvAddGpeReference (
262
 
246
    ACPI_GPE_EVENT_INFO     *GpeEventInfo)
263
ACPI_STATUS
247
{
-
 
248
    ACPI_STATUS             Status = AE_OK;
Line 264... Line 249...
264
AcpiEvDisableGpe (
249
 
-
 
250
 
-
 
251
    ACPI_FUNCTION_TRACE (EvAddGpeReference);
-
 
252
 
-
 
253
 
Line 265... Line -...
265
    ACPI_GPE_EVENT_INFO     *GpeEventInfo)
-
 
266
{
254
    if (GpeEventInfo->RuntimeCount == ACPI_UINT8_MAX)
267
    ACPI_STATUS             Status;
255
    {
-
 
256
        return_ACPI_STATUS (AE_LIMIT);
-
 
257
    }
-
 
258
 
-
 
259
    GpeEventInfo->RuntimeCount++;
268
 
260
    if (GpeEventInfo->RuntimeCount == 1)
269
 
261
    {
Line -... Line 262...
-
 
262
        /* Enable on first reference */
-
 
263
 
-
 
264
        Status = AcpiEvUpdateGpeEnableMask (GpeEventInfo);
-
 
265
        if (ACPI_SUCCESS (Status))
270
    ACPI_FUNCTION_TRACE (EvDisableGpe);
266
        {
271
 
267
            Status = AcpiEvEnableGpe (GpeEventInfo);
-
 
268
        }
-
 
269
 
-
 
270
        if (ACPI_FAILURE (Status))
272
 
271
        {
273
    /*
272
            GpeEventInfo->RuntimeCount--;
-
 
273
        }
-
 
274
    }
-
 
275
 
-
 
276
    return_ACPI_STATUS (Status);
-
 
277
}
-
 
278
 
-
 
279
 
274
     * Note: Always disable the GPE, even if we think that that it is already
280
/*******************************************************************************
-
 
281
 *
-
 
282
 * FUNCTION:    AcpiEvRemoveGpeReference
275
     * disabled. It is possible that the AML or some other code has enabled
283
 *
-
 
284
 * PARAMETERS:  GpeEventInfo            - Remove a reference to this GPE
-
 
285
 *
-
 
286
 * RETURN:      Status
-
 
287
 *
-
 
288
 * DESCRIPTION: Remove a reference to a GPE. When the last reference is
-
 
289
 *              removed, the GPE is hardware-disabled.
-
 
290
 *
-
 
291
 ******************************************************************************/
276
     * the GPE behind our back.
292
 
277
     */
293
ACPI_STATUS
-
 
294
AcpiEvRemoveGpeReference (
-
 
295
    ACPI_GPE_EVENT_INFO     *GpeEventInfo)
278
 
296
{
-
 
297
    ACPI_STATUS             Status = AE_OK;
-
 
298
 
-
 
299
 
-
 
300
    ACPI_FUNCTION_TRACE (EvRemoveGpeReference);
-
 
301
 
-
 
302
 
-
 
303
    if (!GpeEventInfo->RuntimeCount)
-
 
304
    {
-
 
305
        return_ACPI_STATUS (AE_LIMIT);
-
 
306
    }
-
 
307
 
279
    /* Ensure the HW enable masks are current */
308
    GpeEventInfo->RuntimeCount--;
280
 
309
    if (!GpeEventInfo->RuntimeCount)
Line 281... Line 310...
281
    Status = AcpiEvUpdateGpeEnableMasks (GpeEventInfo);
310
    {
Line 463... Line 492...
463
        {
492
        {
464
            /* Get the next status/enable pair */
493
            /* Get the next status/enable pair */
Line 465... Line 494...
465
 
494
 
Line -... Line 495...
-
 
495
            GpeRegisterInfo = &GpeBlock->RegisterInfo[i];
-
 
496
 
-
 
497
            /*
-
 
498
             * Optimization: If there are no GPEs enabled within this
-
 
499
             * register, we can safely ignore the entire register.
-
 
500
             */
-
 
501
            if (!(GpeRegisterInfo->EnableForRun |
-
 
502
                  GpeRegisterInfo->EnableForWake))
-
 
503
            {
-
 
504
                continue;
466
            GpeRegisterInfo = &GpeBlock->RegisterInfo[i];
505
            }
Line 467... Line 506...
467
 
506
 
468
            /* Read the Status Register */
507
            /* Read the Status Register */
469
 
508
 
Line 480... Line 519...
480
            {
519
            {
481
                goto UnlockAndExit;
520
                goto UnlockAndExit;
482
            }
521
            }
Line 483... Line 522...
483
 
522
 
484
            ACPI_DEBUG_PRINT ((ACPI_DB_INTERRUPTS,
523
            ACPI_DEBUG_PRINT ((ACPI_DB_INTERRUPTS,
485
                "Read GPE Register at GPE%X: Status=%02X, Enable=%02X\n",
524
                "Read GPE Register at GPE%02X: Status=%02X, Enable=%02X\n",
Line 486... Line 525...
486
                GpeRegisterInfo->BaseGpeNumber, StatusReg, EnableReg));
525
                GpeRegisterInfo->BaseGpeNumber, StatusReg, EnableReg));
Line 487... Line 526...
487
 
526
 
Line 505... Line 544...
505
                {
544
                {
506
                    /*
545
                    /*
507
                     * Found an active GPE. Dispatch the event to a handler
546
                     * Found an active GPE. Dispatch the event to a handler
508
                     * or method.
547
                     * or method.
509
                     */
548
                     */
510
                    IntStatus |= AcpiEvGpeDispatch (
549
                    IntStatus |= AcpiEvGpeDispatch (GpeBlock->Node,
511
                        &GpeBlock->EventInfo[((ACPI_SIZE) i *
550
                        &GpeBlock->EventInfo[((ACPI_SIZE) i *
512
                            ACPI_GPE_REGISTER_WIDTH) + j],
551
                            ACPI_GPE_REGISTER_WIDTH) + j],
513
                        j + GpeRegisterInfo->BaseGpeNumber);
552
                        j + GpeRegisterInfo->BaseGpeNumber);
514
                }
553
                }
515
            }
554
            }
Line 576... Line 615...
576
    {
615
    {
577
        Status = AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
616
        Status = AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
578
        return_VOID;
617
        return_VOID;
579
    }
618
    }
Line 580... Line -...
580
 
-
 
581
    /* Update the GPE register masks for return to enabled state */
-
 
582
 
-
 
583
    (void) AcpiEvUpdateGpeEnableMasks (GpeEventInfo);
-
 
584
 
619
 
585
    /*
620
    /*
586
     * Take a snapshot of the GPE info for this level - we copy the info to
621
     * Take a snapshot of the GPE info for this level - we copy the info to
587
     * prevent a race condition with RemoveHandler/RemoveBlock.
622
     * prevent a race condition with RemoveHandler/RemoveBlock.
588
     */
623
     */
Line 593... Line 628...
593
    if (ACPI_FAILURE (Status))
628
    if (ACPI_FAILURE (Status))
594
    {
629
    {
595
        return_VOID;
630
        return_VOID;
596
    }
631
    }
Line -... Line 632...
-
 
632
 
-
 
633
    /* Do the correct dispatch - normal method or implicit notify */
-
 
634
 
-
 
635
    switch (LocalGpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK)
-
 
636
    {
-
 
637
    case ACPI_GPE_DISPATCH_NOTIFY:
597
 
638
 
-
 
639
        /*
-
 
640
         * Implicit notify.
598
    /*
641
         * Dispatch a DEVICE_WAKE notify to the appropriate handler.
-
 
642
         * NOTE: the request is queued for execution after this method
-
 
643
         * completes. The notify handlers are NOT invoked synchronously
599
     * Must check for control method type dispatch one more time to avoid a
644
         * from this thread -- because handlers may in turn run other
600
     * race with EvGpeInstallHandler
645
         * control methods.
-
 
646
         */
601
     */
647
        Status = AcpiEvQueueNotifyRequest (
-
 
648
                    LocalGpeEventInfo->Dispatch.DeviceNode,
-
 
649
                    ACPI_NOTIFY_DEVICE_WAKE);
-
 
650
        break;
602
    if ((LocalGpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) ==
651
 
603
            ACPI_GPE_DISPATCH_METHOD)
652
    case ACPI_GPE_DISPATCH_METHOD:
604
    {
653
 
Line 605... Line 654...
605
        /* Allocate the evaluation information block */
654
        /* Allocate the evaluation information block */
606
 
655
 
607
        Info = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO));
656
        Info = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO));
608
        if (!Info)
657
        if (!Info)
609
        {
658
        {
610
            Status = AE_NO_MEMORY;
659
            Status = AE_NO_MEMORY;
611
        }
660
        }
612
        else
661
        else
613
        {
662
        {
614
            /*
663
            /*
615
             * Invoke the GPE Method (_Lxx, _Exx) i.e., evaluate the _Lxx/_Exx
664
             * Invoke the GPE Method (_Lxx, _Exx) i.e., evaluate the
616
             * control method that corresponds to this GPE
665
             * _Lxx/_Exx control method that corresponds to this GPE
617
             */
666
             */
Line 618... Line 667...
618
            Info->PrefixNode = LocalGpeEventInfo->Dispatch.MethodNode;
667
            Info->PrefixNode = LocalGpeEventInfo->Dispatch.MethodNode;
Line 626... Line 675...
626
        {
675
        {
627
            ACPI_EXCEPTION ((AE_INFO, Status,
676
            ACPI_EXCEPTION ((AE_INFO, Status,
628
                "while evaluating GPE method [%4.4s]",
677
                "while evaluating GPE method [%4.4s]",
629
                AcpiUtGetNodeName (LocalGpeEventInfo->Dispatch.MethodNode)));
678
                AcpiUtGetNodeName (LocalGpeEventInfo->Dispatch.MethodNode)));
630
        }
679
        }
-
 
680
 
-
 
681
        break;
-
 
682
 
-
 
683
    default:
-
 
684
        return_VOID; /* Should never happen */
631
    }
685
    }
Line 632... Line 686...
632
 
686
 
Line 633... Line 687...
633
    /* Defer enabling of GPE until all notify handlers are done */
687
    /* Defer enabling of GPE until all notify handlers are done */
Line 645... Line 699...
645
/*******************************************************************************
699
/*******************************************************************************
646
 *
700
 *
647
 * FUNCTION:    AcpiEvAsynchEnableGpe
701
 * FUNCTION:    AcpiEvAsynchEnableGpe
648
 *
702
 *
649
 * PARAMETERS:  Context (GpeEventInfo) - Info for this GPE
703
 * PARAMETERS:  Context (GpeEventInfo) - Info for this GPE
-
 
704
 *              Callback from AcpiOsExecute
650
 *
705
 *
651
 * RETURN:      None
706
 * RETURN:      None
652
 *
707
 *
653
 * DESCRIPTION: Asynchronous clear/enable for GPE. This allows the GPE to
708
 * DESCRIPTION: Asynchronous clear/enable for GPE. This allows the GPE to
654
 *              complete (i.e., finish execution of Notify)
709
 *              complete (i.e., finish execution of Notify)
Line 658... Line 713...
658
static void ACPI_SYSTEM_XFACE
713
static void ACPI_SYSTEM_XFACE
659
AcpiEvAsynchEnableGpe (
714
AcpiEvAsynchEnableGpe (
660
    void                    *Context)
715
    void                    *Context)
661
{
716
{
662
    ACPI_GPE_EVENT_INFO     *GpeEventInfo = Context;
717
    ACPI_GPE_EVENT_INFO     *GpeEventInfo = Context;
-
 
718
 
-
 
719
 
-
 
720
    (void) AcpiEvFinishGpe (GpeEventInfo);
-
 
721
 
-
 
722
    ACPI_FREE (GpeEventInfo);
-
 
723
    return;
-
 
724
}
-
 
725
 
-
 
726
 
-
 
727
/*******************************************************************************
-
 
728
 *
-
 
729
 * FUNCTION:    AcpiEvFinishGpe
-
 
730
 *
-
 
731
 * PARAMETERS:  GpeEventInfo        - Info for this GPE
-
 
732
 *
-
 
733
 * RETURN:      Status
-
 
734
 *
-
 
735
 * DESCRIPTION: Clear/Enable a GPE. Common code that is used after execution
-
 
736
 *              of a GPE method or a synchronous or asynchronous GPE handler.
-
 
737
 *
-
 
738
 ******************************************************************************/
-
 
739
 
-
 
740
ACPI_STATUS
-
 
741
AcpiEvFinishGpe (
-
 
742
    ACPI_GPE_EVENT_INFO     *GpeEventInfo)
-
 
743
{
663
    ACPI_STATUS             Status;
744
    ACPI_STATUS             Status;
Line 664... Line 745...
664
 
745
 
665
 
746
 
666
    if ((GpeEventInfo->Flags & ACPI_GPE_XRUPT_TYPE_MASK) ==
747
    if ((GpeEventInfo->Flags & ACPI_GPE_XRUPT_TYPE_MASK) ==
667
            ACPI_GPE_LEVEL_TRIGGERED)
748
            ACPI_GPE_LEVEL_TRIGGERED)
668
    {
749
    {
669
        /*
750
        /*
670
         * GPE is level-triggered, we clear the GPE status bit after handling
751
         * GPE is level-triggered, we clear the GPE status bit after
671
         * the event.
752
         * handling the event.
672
         */
753
         */
673
        Status = AcpiHwClearGpe (GpeEventInfo);
754
        Status = AcpiHwClearGpe (GpeEventInfo);
674
        if (ACPI_FAILURE (Status))
755
        if (ACPI_FAILURE (Status))
675
        {
756
        {
676
            goto Exit;
757
            return (Status);
Line -... Line 758...
-
 
758
        }
677
        }
759
    }
678
    }
-
 
679
 
760
 
680
    /* Enable this GPE */
-
 
-
 
761
    /*
681
 
762
     * Enable this GPE, conditionally. This means that the GPE will
682
    (void) AcpiHwWriteGpeEnableReg (GpeEventInfo);
763
     * only be physically enabled if the EnableForRun bit is set
683
 
764
     * in the EventInfo.
684
Exit:
765
     */
Line 685... Line 766...
685
    ACPI_FREE (GpeEventInfo);
766
    (void) AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_CONDITIONAL_ENABLE);
686
    return;
767
    return (AE_OK);
687
}
768
}
688
 
769
 
-
 
770
 
689
 
771
/*******************************************************************************
690
/*******************************************************************************
772
 *
691
 *
773
 * FUNCTION:    AcpiEvGpeDispatch
692
 * FUNCTION:    AcpiEvGpeDispatch
774
 *
693
 *
775
 * PARAMETERS:  GpeDevice           - Device node. NULL for GPE0/GPE1
694
 * PARAMETERS:  GpeEventInfo    - Info for this GPE
776
 *              GpeEventInfo        - Info for this GPE
Line 703... Line 785...
703
 *
785
 *
704
 ******************************************************************************/
786
 ******************************************************************************/
Line 705... Line 787...
705
 
787
 
706
UINT32
788
UINT32
-
 
789
AcpiEvGpeDispatch (
707
AcpiEvGpeDispatch (
790
    ACPI_NAMESPACE_NODE     *GpeDevice,
708
    ACPI_GPE_EVENT_INFO     *GpeEventInfo,
791
    ACPI_GPE_EVENT_INFO     *GpeEventInfo,
709
    UINT32                  GpeNumber)
792
    UINT32                  GpeNumber)
710
{
793
{
-
 
794
    ACPI_STATUS             Status;
Line 711... Line 795...
711
    ACPI_STATUS             Status;
795
    UINT32                  ReturnValue;
Line -... Line 796...
-
 
796
 
-
 
797
 
712
 
798
    ACPI_FUNCTION_TRACE (EvGpeDispatch);
-
 
799
 
-
 
800
 
-
 
801
    /* Invoke global event handler if present */
-
 
802
 
-
 
803
    AcpiGpeCount++;
Line 713... Line 804...
713
 
804
    if (AcpiGbl_GlobalEventHandler)
714
    ACPI_FUNCTION_TRACE (EvGpeDispatch);
805
    {
715
 
806
        AcpiGbl_GlobalEventHandler (ACPI_EVENT_TYPE_GPE, GpeDevice,
716
 
807
             GpeNumber, AcpiGbl_GlobalEventHandlerContext);
Line 725... Line 816...
725
    {
816
    {
726
        Status = AcpiHwClearGpe (GpeEventInfo);
817
        Status = AcpiHwClearGpe (GpeEventInfo);
727
        if (ACPI_FAILURE (Status))
818
        if (ACPI_FAILURE (Status))
728
        {
819
        {
729
            ACPI_EXCEPTION ((AE_INFO, Status,
820
            ACPI_EXCEPTION ((AE_INFO, Status,
730
                "Unable to clear GPE[0x%2X]", GpeNumber));
821
                "Unable to clear GPE%02X", GpeNumber));
731
            return_UINT32 (ACPI_INTERRUPT_NOT_HANDLED);
822
            return_UINT32 (ACPI_INTERRUPT_NOT_HANDLED);
732
        }
823
        }
733
    }
824
    }
Line 734... Line 825...
734
 
825
 
735
    /*
826
    /*
736
     * Dispatch the GPE to either an installed handler, or the control method
827
     * Always disable the GPE so that it does not keep firing before
-
 
828
     * any asynchronous activity completes (either from the execution
-
 
829
     * of a GPE method or an asynchronous GPE handler.)
737
     * associated with this GPE (_Lxx or _Exx). If a handler exists, we invoke
830
     *
738
     * it and do not attempt to run the method. If there is neither a handler
831
     * If there is no handler or method to run, just disable the
739
     * nor a method, we disable this GPE to prevent further such pointless
832
     * GPE and leave it disabled permanently to prevent further such
740
     * events from firing.
833
     * pointless events from firing.
741
     */
834
     */
-
 
835
    Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_DISABLE);
742
    switch (GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK)
836
    if (ACPI_FAILURE (Status))
-
 
837
    {
-
 
838
        ACPI_EXCEPTION ((AE_INFO, Status,
743
    {
839
            "Unable to disable GPE%02X", GpeNumber));
-
 
840
        return_UINT32 (ACPI_INTERRUPT_NOT_HANDLED);
Line 744... Line 841...
744
    case ACPI_GPE_DISPATCH_HANDLER:
841
    }
745
 
842
 
-
 
843
    /*
746
        /*
844
     * Dispatch the GPE to either an installed handler or the control
747
         * Invoke the installed handler (at interrupt level)
845
     * method associated with this GPE (_Lxx or _Exx). If a handler
-
 
846
     * exists, we invoke it and do not attempt to run the method.
748
         * Ignore return status for now.
847
     * If there is neither a handler nor a method, leave the GPE
-
 
848
     * disabled.
-
 
849
     */
-
 
850
    switch (GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK)
-
 
851
    {
-
 
852
    case ACPI_GPE_DISPATCH_HANDLER:
-
 
853
 
749
         * TBD: leave GPE disabled on error?
854
        /* Invoke the installed handler (at interrupt level) */
-
 
855
 
750
         */
856
        ReturnValue = GpeEventInfo->Dispatch.Handler->Address (
Line 751... Line 857...
751
        (void) GpeEventInfo->Dispatch.Handler->Address (
857
            GpeDevice, GpeNumber,
Line 752... Line 858...
752
                        GpeEventInfo->Dispatch.Handler->Context);
858
            GpeEventInfo->Dispatch.Handler->Context);
753
 
-
 
754
        /* It is now safe to clear level-triggered events. */
859
 
755
 
860
        /* If requested, clear (if level-triggered) and reenable the GPE */
756
        if ((GpeEventInfo->Flags & ACPI_GPE_XRUPT_TYPE_MASK) ==
-
 
757
                ACPI_GPE_LEVEL_TRIGGERED)
-
 
758
        {
-
 
759
            Status = AcpiHwClearGpe (GpeEventInfo);
-
 
760
            if (ACPI_FAILURE (Status))
-
 
761
            {
-
 
762
                ACPI_EXCEPTION ((AE_INFO, Status,
861
 
763
                    "Unable to clear GPE[0x%2X]", GpeNumber));
862
        if (ReturnValue & ACPI_REENABLE_GPE)
Line 764... Line 863...
764
                return_UINT32 (ACPI_INTERRUPT_NOT_HANDLED);
863
        {
765
            }
-
 
766
        }
-
 
767
        break;
-
 
768
 
-
 
769
    case ACPI_GPE_DISPATCH_METHOD:
-
 
770
 
-
 
771
        /*
864
            (void) AcpiEvFinishGpe (GpeEventInfo);
772
         * Disable the GPE, so it doesn't keep firing before the method has a
-
 
773
         * chance to run (it runs asynchronously with interrupts enabled).
-
 
774
         */
-
 
775
        Status = AcpiEvDisableGpe (GpeEventInfo);
-
 
776
        if (ACPI_FAILURE (Status))
-
 
Line 777... Line 865...
777
        {
865
        }
778
            ACPI_EXCEPTION ((AE_INFO, Status,
866
        break;
779
                "Unable to disable GPE[0x%2X]", GpeNumber));
867
 
780
            return_UINT32 (ACPI_INTERRUPT_NOT_HANDLED);
868
    case ACPI_GPE_DISPATCH_METHOD:
781
        }
869
    case ACPI_GPE_DISPATCH_NOTIFY:
782
 
870
 
783
        /*
871
        /*
784
         * Execute the method associated with the GPE
872
         * Execute the method associated with the GPE
785
         * NOTE: Level-triggered GPEs are cleared after the method completes.
873
         * NOTE: Level-triggered GPEs are cleared after the method completes.
786
         */
874
         */
787
        Status = AcpiOsExecute (OSL_GPE_HANDLER,
875
        Status = AcpiOsExecute (OSL_GPE_HANDLER,
788
                    AcpiEvAsynchExecuteGpeMethod, GpeEventInfo);
876
                    AcpiEvAsynchExecuteGpeMethod, GpeEventInfo);
789
        if (ACPI_FAILURE (Status))
877
        if (ACPI_FAILURE (Status))
Line 790... Line 878...
790
        {
878
        {
Line 800... Line 888...
800
         * No handler or method to run!
888
         * No handler or method to run!
801
         * 03/2010: This case should no longer be possible. We will not allow
889
         * 03/2010: This case should no longer be possible. We will not allow
802
         * a GPE to be enabled if it has no handler or method.
890
         * a GPE to be enabled if it has no handler or method.
803
         */
891
         */
804
        ACPI_ERROR ((AE_INFO,
892
        ACPI_ERROR ((AE_INFO,
805
            "No handler or method for GPE[0x%2X], disabling event",
893
            "No handler or method for GPE%02X, disabling event",
806
            GpeNumber));
894
            GpeNumber));
807
 
-
 
808
        /*
-
 
809
         * Disable the GPE. The GPE will remain disabled a handler
-
 
810
         * is installed or ACPICA is restarted.
-
 
811
         */
-
 
812
        Status = AcpiEvDisableGpe (GpeEventInfo);
-
 
813
        if (ACPI_FAILURE (Status))
-
 
814
        {
-
 
815
            ACPI_EXCEPTION ((AE_INFO, Status,
-
 
816
                "Unable to disable GPE[0x%2X]", GpeNumber));
-
 
817
            return_UINT32 (ACPI_INTERRUPT_NOT_HANDLED);
-
 
818
        }
-
 
819
        break;
895
        break;
820
    }
896
    }
Line 821... Line 897...
821
 
897
 
822
    return_UINT32 (ACPI_INTERRUPT_HANDLED);
898
    return_UINT32 (ACPI_INTERRUPT_HANDLED);