hwgpe.c revision 167802
1
2/******************************************************************************
3 *
4 * Module Name: hwgpe - Low level GPE enable/disable/clear functions
5 *              $Revision: 1.75 $
6 *
7 *****************************************************************************/
8
9/******************************************************************************
10 *
11 * 1. Copyright Notice
12 *
13 * Some or all of this work - Copyright (c) 1999 - 2007, Intel Corp.
14 * All rights reserved.
15 *
16 * 2. License
17 *
18 * 2.1. This is your license from Intel Corp. under its intellectual property
19 * rights.  You may have additional license terms from the party that provided
20 * you this software, covering your right to use that party's intellectual
21 * property rights.
22 *
23 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
24 * copy of the source code appearing in this file ("Covered Code") an
25 * irrevocable, perpetual, worldwide license under Intel's copyrights in the
26 * base code distributed originally by Intel ("Original Intel Code") to copy,
27 * make derivatives, distribute, use and display any portion of the Covered
28 * Code in any form, with the right to sublicense such rights; and
29 *
30 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
31 * license (with the right to sublicense), under only those claims of Intel
32 * patents that are infringed by the Original Intel Code, to make, use, sell,
33 * offer to sell, and import the Covered Code and derivative works thereof
34 * solely to the minimum extent necessary to exercise the above copyright
35 * license, and in no event shall the patent license extend to any additions
36 * to or modifications of the Original Intel Code.  No other license or right
37 * is granted directly or by implication, estoppel or otherwise;
38 *
39 * The above copyright and patent license is granted only if the following
40 * conditions are met:
41 *
42 * 3. Conditions
43 *
44 * 3.1. Redistribution of Source with Rights to Further Distribute Source.
45 * Redistribution of source code of any substantial portion of the Covered
46 * Code or modification with rights to further distribute source must include
47 * the above Copyright Notice, the above License, this list of Conditions,
48 * and the following Disclaimer and Export Compliance provision.  In addition,
49 * Licensee must cause all Covered Code to which Licensee contributes to
50 * contain a file documenting the changes Licensee made to create that Covered
51 * Code and the date of any change.  Licensee must include in that file the
52 * documentation of any changes made by any predecessor Licensee.  Licensee
53 * must include a prominent statement that the modification is derived,
54 * directly or indirectly, from Original Intel Code.
55 *
56 * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
57 * Redistribution of source code of any substantial portion of the Covered
58 * Code or modification without rights to further distribute source must
59 * include the following Disclaimer and Export Compliance provision in the
60 * documentation and/or other materials provided with distribution.  In
61 * addition, Licensee may not authorize further sublicense of source of any
62 * portion of the Covered Code, and must include terms to the effect that the
63 * license from Licensee to its licensee is limited to the intellectual
64 * property embodied in the software Licensee provides to its licensee, and
65 * not to intellectual property embodied in modifications its licensee may
66 * make.
67 *
68 * 3.3. Redistribution of Executable. Redistribution in executable form of any
69 * substantial portion of the Covered Code or modification must reproduce the
70 * above Copyright Notice, and the following Disclaimer and Export Compliance
71 * provision in the documentation and/or other materials provided with the
72 * distribution.
73 *
74 * 3.4. Intel retains all right, title, and interest in and to the Original
75 * Intel Code.
76 *
77 * 3.5. Neither the name Intel nor any other trademark owned or controlled by
78 * Intel shall be used in advertising or otherwise to promote the sale, use or
79 * other dealings in products derived from or relating to the Covered Code
80 * without prior written authorization from Intel.
81 *
82 * 4. Disclaimer and Export Compliance
83 *
84 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
85 * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
86 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
87 * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
88 * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
89 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
90 * PARTICULAR PURPOSE.
91 *
92 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
93 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
94 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
95 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
96 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
97 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
98 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
99 * LIMITED REMEDY.
100 *
101 * 4.3. Licensee shall not export, either directly or indirectly, any of this
102 * software or system incorporating such software without first obtaining any
103 * required license or other approval from the U. S. Department of Commerce or
104 * any other agency or department of the United States Government.  In the
105 * event Licensee exports any such software from the United States or
106 * re-exports any such software from a foreign destination, Licensee shall
107 * ensure that the distribution and export/re-export of the software is in
108 * compliance with all laws, regulations, orders, or other restrictions of the
109 * U.S. Export Administration Regulations. Licensee agrees that neither it nor
110 * any of its subsidiaries will export/re-export any technical data, process,
111 * software, or service, directly or indirectly, to any country for which the
112 * United States government or any agency thereof requires an export license,
113 * other governmental approval, or letter of assurance, without first obtaining
114 * such license, approval or letter.
115 *
116 *****************************************************************************/
117
118#include <contrib/dev/acpica/acpi.h>
119#include <contrib/dev/acpica/acevents.h>
120
121#define _COMPONENT          ACPI_HARDWARE
122        ACPI_MODULE_NAME    ("hwgpe")
123
124/* Local prototypes */
125
126static ACPI_STATUS
127AcpiHwEnableWakeupGpeBlock (
128    ACPI_GPE_XRUPT_INFO     *GpeXruptInfo,
129    ACPI_GPE_BLOCK_INFO     *GpeBlock);
130
131
132/******************************************************************************
133 *
134 * FUNCTION:    AcpiHwWriteGpeEnableReg
135 *
136 * PARAMETERS:  GpeEventInfo        - Info block for the GPE to be enabled
137 *
138 * RETURN:      Status
139 *
140 * DESCRIPTION: Write a GPE enable register.  Note: The bit for this GPE must
141 *              already be cleared or set in the parent register
142 *              EnableForRun mask.
143 *
144 ******************************************************************************/
145
146ACPI_STATUS
147AcpiHwWriteGpeEnableReg (
148    ACPI_GPE_EVENT_INFO     *GpeEventInfo)
149{
150    ACPI_GPE_REGISTER_INFO  *GpeRegisterInfo;
151    ACPI_STATUS             Status;
152
153
154    ACPI_FUNCTION_ENTRY ();
155
156
157    /* Get the info block for the entire GPE register */
158
159    GpeRegisterInfo = GpeEventInfo->RegisterInfo;
160    if (!GpeRegisterInfo)
161    {
162        return (AE_NOT_EXIST);
163    }
164
165    /* Write the entire GPE (runtime) enable register */
166
167    Status = AcpiHwLowLevelWrite (8, GpeRegisterInfo->EnableForRun,
168                    &GpeRegisterInfo->EnableAddress);
169
170    return (Status);
171}
172
173
174/******************************************************************************
175 *
176 * FUNCTION:    AcpiHwClearGpe
177 *
178 * PARAMETERS:  GpeEventInfo        - Info block for the GPE to be cleared
179 *
180 * RETURN:      Status
181 *
182 * DESCRIPTION: Clear the status bit for a single GPE.
183 *
184 ******************************************************************************/
185
186ACPI_STATUS
187AcpiHwClearGpe (
188    ACPI_GPE_EVENT_INFO     *GpeEventInfo)
189{
190    ACPI_STATUS             Status;
191    UINT8                   RegisterBit;
192
193
194    ACPI_FUNCTION_ENTRY ();
195
196
197    RegisterBit = (UINT8)
198        (1 << (GpeEventInfo->GpeNumber - GpeEventInfo->RegisterInfo->BaseGpeNumber));
199
200    /*
201     * Write a one to the appropriate bit in the status register to
202     * clear this GPE.
203     */
204    Status = AcpiHwLowLevelWrite (8, RegisterBit,
205                    &GpeEventInfo->RegisterInfo->StatusAddress);
206
207    return (Status);
208}
209
210
211/******************************************************************************
212 *
213 * FUNCTION:    AcpiHwGetGpeStatus
214 *
215 * PARAMETERS:  GpeEventInfo        - Info block for the GPE to queried
216 *              EventStatus         - Where the GPE status is returned
217 *
218 * RETURN:      Status
219 *
220 * DESCRIPTION: Return the status of a single GPE.
221 *
222 ******************************************************************************/
223
224ACPI_STATUS
225AcpiHwGetGpeStatus (
226    ACPI_GPE_EVENT_INFO     *GpeEventInfo,
227    ACPI_EVENT_STATUS       *EventStatus)
228{
229    UINT32                  InByte;
230    UINT8                   RegisterBit;
231    ACPI_GPE_REGISTER_INFO  *GpeRegisterInfo;
232    ACPI_STATUS             Status;
233    ACPI_EVENT_STATUS       LocalEventStatus = 0;
234
235
236    ACPI_FUNCTION_ENTRY ();
237
238
239    if (!EventStatus)
240    {
241        return (AE_BAD_PARAMETER);
242    }
243
244    /* Get the info block for the entire GPE register */
245
246    GpeRegisterInfo = GpeEventInfo->RegisterInfo;
247
248    /* Get the register bitmask for this GPE */
249
250    RegisterBit = (UINT8)
251        (1 << (GpeEventInfo->GpeNumber - GpeEventInfo->RegisterInfo->BaseGpeNumber));
252
253    /* GPE currently enabled? (enabled for runtime?) */
254
255    if (RegisterBit & GpeRegisterInfo->EnableForRun)
256    {
257        LocalEventStatus |= ACPI_EVENT_FLAG_ENABLED;
258    }
259
260    /* GPE enabled for wake? */
261
262    if (RegisterBit & GpeRegisterInfo->EnableForWake)
263    {
264        LocalEventStatus |= ACPI_EVENT_FLAG_WAKE_ENABLED;
265    }
266
267    /* GPE currently active (status bit == 1)? */
268
269    Status = AcpiHwLowLevelRead (8, &InByte, &GpeRegisterInfo->StatusAddress);
270    if (ACPI_FAILURE (Status))
271    {
272        goto UnlockAndExit;
273    }
274
275    if (RegisterBit & InByte)
276    {
277        LocalEventStatus |= ACPI_EVENT_FLAG_SET;
278    }
279
280    /* Set return value */
281
282    (*EventStatus) = LocalEventStatus;
283
284
285UnlockAndExit:
286    return (Status);
287}
288
289
290/******************************************************************************
291 *
292 * FUNCTION:    AcpiHwDisableGpeBlock
293 *
294 * PARAMETERS:  GpeXruptInfo        - GPE Interrupt info
295 *              GpeBlock            - Gpe Block info
296 *
297 * RETURN:      Status
298 *
299 * DESCRIPTION: Disable all GPEs within a single GPE block
300 *
301 ******************************************************************************/
302
303ACPI_STATUS
304AcpiHwDisableGpeBlock (
305    ACPI_GPE_XRUPT_INFO     *GpeXruptInfo,
306    ACPI_GPE_BLOCK_INFO     *GpeBlock)
307{
308    UINT32                  i;
309    ACPI_STATUS             Status;
310
311
312    /* Examine each GPE Register within the block */
313
314    for (i = 0; i < GpeBlock->RegisterCount; i++)
315    {
316        /* Disable all GPEs in this register */
317
318        Status = AcpiHwLowLevelWrite (8, 0x00,
319                    &GpeBlock->RegisterInfo[i].EnableAddress);
320        if (ACPI_FAILURE (Status))
321        {
322            return (Status);
323        }
324    }
325
326    return (AE_OK);
327}
328
329
330/******************************************************************************
331 *
332 * FUNCTION:    AcpiHwClearGpeBlock
333 *
334 * PARAMETERS:  GpeXruptInfo        - GPE Interrupt info
335 *              GpeBlock            - Gpe Block info
336 *
337 * RETURN:      Status
338 *
339 * DESCRIPTION: Clear status bits for all GPEs within a single GPE block
340 *
341 ******************************************************************************/
342
343ACPI_STATUS
344AcpiHwClearGpeBlock (
345    ACPI_GPE_XRUPT_INFO     *GpeXruptInfo,
346    ACPI_GPE_BLOCK_INFO     *GpeBlock)
347{
348    UINT32                  i;
349    ACPI_STATUS             Status;
350
351
352    /* Examine each GPE Register within the block */
353
354    for (i = 0; i < GpeBlock->RegisterCount; i++)
355    {
356        /* Clear status on all GPEs in this register */
357
358        Status = AcpiHwLowLevelWrite (8, 0xFF,
359                    &GpeBlock->RegisterInfo[i].StatusAddress);
360        if (ACPI_FAILURE (Status))
361        {
362            return (Status);
363        }
364    }
365
366    return (AE_OK);
367}
368
369
370/******************************************************************************
371 *
372 * FUNCTION:    AcpiHwEnableRuntimeGpeBlock
373 *
374 * PARAMETERS:  GpeXruptInfo        - GPE Interrupt info
375 *              GpeBlock            - Gpe Block info
376 *
377 * RETURN:      Status
378 *
379 * DESCRIPTION: Enable all "runtime" GPEs within a single GPE block. Includes
380 *              combination wake/run GPEs.
381 *
382 ******************************************************************************/
383
384ACPI_STATUS
385AcpiHwEnableRuntimeGpeBlock (
386    ACPI_GPE_XRUPT_INFO     *GpeXruptInfo,
387    ACPI_GPE_BLOCK_INFO     *GpeBlock)
388{
389    UINT32                  i;
390    ACPI_STATUS             Status;
391
392
393    /* NOTE: assumes that all GPEs are currently disabled */
394
395    /* Examine each GPE Register within the block */
396
397    for (i = 0; i < GpeBlock->RegisterCount; i++)
398    {
399        if (!GpeBlock->RegisterInfo[i].EnableForRun)
400        {
401            continue;
402        }
403
404        /* Enable all "runtime" GPEs in this register */
405
406        Status = AcpiHwLowLevelWrite (8, GpeBlock->RegisterInfo[i].EnableForRun,
407                    &GpeBlock->RegisterInfo[i].EnableAddress);
408        if (ACPI_FAILURE (Status))
409        {
410            return (Status);
411        }
412    }
413
414    return (AE_OK);
415}
416
417
418/******************************************************************************
419 *
420 * FUNCTION:    AcpiHwEnableWakeupGpeBlock
421 *
422 * PARAMETERS:  GpeXruptInfo        - GPE Interrupt info
423 *              GpeBlock            - Gpe Block info
424 *
425 * RETURN:      Status
426 *
427 * DESCRIPTION: Enable all "wake" GPEs within a single GPE block. Includes
428 *              combination wake/run GPEs.
429 *
430 ******************************************************************************/
431
432static ACPI_STATUS
433AcpiHwEnableWakeupGpeBlock (
434    ACPI_GPE_XRUPT_INFO     *GpeXruptInfo,
435    ACPI_GPE_BLOCK_INFO     *GpeBlock)
436{
437    UINT32                  i;
438    ACPI_STATUS             Status;
439
440
441    /* Examine each GPE Register within the block */
442
443    for (i = 0; i < GpeBlock->RegisterCount; i++)
444    {
445        if (!GpeBlock->RegisterInfo[i].EnableForWake)
446        {
447            continue;
448        }
449
450        /* Enable all "wake" GPEs in this register */
451
452        Status = AcpiHwLowLevelWrite (8,
453                    GpeBlock->RegisterInfo[i].EnableForWake,
454                    &GpeBlock->RegisterInfo[i].EnableAddress);
455        if (ACPI_FAILURE (Status))
456        {
457            return (Status);
458        }
459    }
460
461    return (AE_OK);
462}
463
464
465/******************************************************************************
466 *
467 * FUNCTION:    AcpiHwDisableAllGpes
468 *
469 * PARAMETERS:  None
470 *
471 * RETURN:      Status
472 *
473 * DESCRIPTION: Disable and clear all GPEs in all GPE blocks
474 *
475 ******************************************************************************/
476
477ACPI_STATUS
478AcpiHwDisableAllGpes (
479    void)
480{
481    ACPI_STATUS             Status;
482
483
484    ACPI_FUNCTION_TRACE (HwDisableAllGpes);
485
486
487    Status = AcpiEvWalkGpeList (AcpiHwDisableGpeBlock);
488    Status = AcpiEvWalkGpeList (AcpiHwClearGpeBlock);
489    return_ACPI_STATUS (Status);
490}
491
492
493/******************************************************************************
494 *
495 * FUNCTION:    AcpiHwEnableAllRuntimeGpes
496 *
497 * PARAMETERS:  None
498 *
499 * RETURN:      Status
500 *
501 * DESCRIPTION: Enable all "runtime" GPEs, in all GPE blocks
502 *
503 ******************************************************************************/
504
505ACPI_STATUS
506AcpiHwEnableAllRuntimeGpes (
507    void)
508{
509    ACPI_STATUS             Status;
510
511
512    ACPI_FUNCTION_TRACE (HwEnableAllRuntimeGpes);
513
514
515    Status = AcpiEvWalkGpeList (AcpiHwEnableRuntimeGpeBlock);
516    return_ACPI_STATUS (Status);
517}
518
519
520/******************************************************************************
521 *
522 * FUNCTION:    AcpiHwEnableAllWakeupGpes
523 *
524 * PARAMETERS:  None
525 *
526 * RETURN:      Status
527 *
528 * DESCRIPTION: Enable all "wakeup" GPEs, in all GPE blocks
529 *
530 ******************************************************************************/
531
532ACPI_STATUS
533AcpiHwEnableAllWakeupGpes (
534    void)
535{
536    ACPI_STATUS             Status;
537
538
539    ACPI_FUNCTION_TRACE (HwEnableAllWakeupGpes);
540
541
542    Status = AcpiEvWalkGpeList (AcpiHwEnableWakeupGpeBlock);
543    return_ACPI_STATUS (Status);
544}
545
546