1 /******************************************************************************
3 * Module Name: hwgpe - Low level GPE enable/disable/clear functions
5 *****************************************************************************/
8 * Copyright (C) 2000 - 2018, Intel Corp.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
48 #define _COMPONENT ACPI_HARDWARE
49 ACPI_MODULE_NAME ("hwgpe")
51 #if (!ACPI_REDUCED_HARDWARE) /* Entire module */
53 /* Local prototypes */
56 AcpiHwEnableWakeupGpeBlock (
57 ACPI_GPE_XRUPT_INFO
*GpeXruptInfo
,
58 ACPI_GPE_BLOCK_INFO
*GpeBlock
,
62 AcpiHwGpeEnableWrite (
64 ACPI_GPE_REGISTER_INFO
*GpeRegisterInfo
);
67 /******************************************************************************
69 * FUNCTION: AcpiHwGetGpeRegisterBit
71 * PARAMETERS: GpeEventInfo - Info block for the GPE
73 * RETURN: Register mask with a one in the GPE bit position
75 * DESCRIPTION: Compute the register mask for this GPE. One bit is set in the
76 * correct position for the input GPE.
78 ******************************************************************************/
81 AcpiHwGetGpeRegisterBit (
82 ACPI_GPE_EVENT_INFO
*GpeEventInfo
)
86 (GpeEventInfo
->GpeNumber
- GpeEventInfo
->RegisterInfo
->BaseGpeNumber
));
90 /******************************************************************************
92 * FUNCTION: AcpiHwLowSetGpe
94 * PARAMETERS: GpeEventInfo - Info block for the GPE to be disabled
95 * Action - Enable or disable
99 * DESCRIPTION: Enable or disable a single GPE in the parent enable register.
100 * The EnableMask field of the involved GPE register must be
101 * updated by the caller if necessary.
103 ******************************************************************************/
107 ACPI_GPE_EVENT_INFO
*GpeEventInfo
,
110 ACPI_GPE_REGISTER_INFO
*GpeRegisterInfo
;
111 ACPI_STATUS Status
= AE_OK
;
116 ACPI_FUNCTION_ENTRY ();
119 /* Get the info block for the entire GPE register */
121 GpeRegisterInfo
= GpeEventInfo
->RegisterInfo
;
122 if (!GpeRegisterInfo
)
124 return (AE_NOT_EXIST
);
127 /* Get current value of the enable register that contains this GPE */
129 Status
= AcpiHwRead (&EnableMask
, &GpeRegisterInfo
->EnableAddress
);
130 if (ACPI_FAILURE (Status
))
135 /* Set or clear just the bit that corresponds to this GPE */
137 RegisterBit
= AcpiHwGetGpeRegisterBit (GpeEventInfo
);
140 case ACPI_GPE_CONDITIONAL_ENABLE
:
142 /* Only enable if the corresponding EnableMask bit is set */
144 if (!(RegisterBit
& GpeRegisterInfo
->EnableMask
))
146 return (AE_BAD_PARAMETER
);
149 /*lint -fallthrough */
151 case ACPI_GPE_ENABLE
:
153 ACPI_SET_BIT (EnableMask
, RegisterBit
);
156 case ACPI_GPE_DISABLE
:
158 ACPI_CLEAR_BIT (EnableMask
, RegisterBit
);
163 ACPI_ERROR ((AE_INFO
, "Invalid GPE Action, %u", Action
));
164 return (AE_BAD_PARAMETER
);
167 if (!(RegisterBit
& GpeRegisterInfo
->MaskForRun
))
169 /* Write the updated enable mask */
171 Status
= AcpiHwWrite (EnableMask
, &GpeRegisterInfo
->EnableAddress
);
177 /******************************************************************************
179 * FUNCTION: AcpiHwClearGpe
181 * PARAMETERS: GpeEventInfo - Info block for the GPE to be cleared
185 * DESCRIPTION: Clear the status bit for a single GPE.
187 ******************************************************************************/
191 ACPI_GPE_EVENT_INFO
*GpeEventInfo
)
193 ACPI_GPE_REGISTER_INFO
*GpeRegisterInfo
;
198 ACPI_FUNCTION_ENTRY ();
200 /* Get the info block for the entire GPE register */
202 GpeRegisterInfo
= GpeEventInfo
->RegisterInfo
;
203 if (!GpeRegisterInfo
)
205 return (AE_NOT_EXIST
);
209 * Write a one to the appropriate bit in the status register to
212 RegisterBit
= AcpiHwGetGpeRegisterBit (GpeEventInfo
);
214 Status
= AcpiHwWrite (RegisterBit
, &GpeRegisterInfo
->StatusAddress
);
219 /******************************************************************************
221 * FUNCTION: AcpiHwGetGpeStatus
223 * PARAMETERS: GpeEventInfo - Info block for the GPE to queried
224 * EventStatus - Where the GPE status is returned
228 * DESCRIPTION: Return the status of a single GPE.
230 ******************************************************************************/
234 ACPI_GPE_EVENT_INFO
*GpeEventInfo
,
235 ACPI_EVENT_STATUS
*EventStatus
)
239 ACPI_GPE_REGISTER_INFO
*GpeRegisterInfo
;
240 ACPI_EVENT_STATUS LocalEventStatus
= 0;
244 ACPI_FUNCTION_ENTRY ();
249 return (AE_BAD_PARAMETER
);
252 /* GPE currently handled? */
254 if (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo
->Flags
) !=
255 ACPI_GPE_DISPATCH_NONE
)
257 LocalEventStatus
|= ACPI_EVENT_FLAG_HAS_HANDLER
;
260 /* Get the info block for the entire GPE register */
262 GpeRegisterInfo
= GpeEventInfo
->RegisterInfo
;
264 /* Get the register bitmask for this GPE */
266 RegisterBit
= AcpiHwGetGpeRegisterBit (GpeEventInfo
);
268 /* GPE currently enabled? (enabled for runtime?) */
270 if (RegisterBit
& GpeRegisterInfo
->EnableForRun
)
272 LocalEventStatus
|= ACPI_EVENT_FLAG_ENABLED
;
275 /* GPE currently masked? (masked for runtime?) */
277 if (RegisterBit
& GpeRegisterInfo
->MaskForRun
)
279 LocalEventStatus
|= ACPI_EVENT_FLAG_MASKED
;
282 /* GPE enabled for wake? */
284 if (RegisterBit
& GpeRegisterInfo
->EnableForWake
)
286 LocalEventStatus
|= ACPI_EVENT_FLAG_WAKE_ENABLED
;
289 /* GPE currently enabled (enable bit == 1)? */
291 Status
= AcpiHwRead (&InByte
, &GpeRegisterInfo
->EnableAddress
);
292 if (ACPI_FAILURE (Status
))
297 if (RegisterBit
& InByte
)
299 LocalEventStatus
|= ACPI_EVENT_FLAG_ENABLE_SET
;
302 /* GPE currently active (status bit == 1)? */
304 Status
= AcpiHwRead (&InByte
, &GpeRegisterInfo
->StatusAddress
);
305 if (ACPI_FAILURE (Status
))
310 if (RegisterBit
& InByte
)
312 LocalEventStatus
|= ACPI_EVENT_FLAG_STATUS_SET
;
315 /* Set return value */
317 (*EventStatus
) = LocalEventStatus
;
322 /******************************************************************************
324 * FUNCTION: AcpiHwGpeEnableWrite
326 * PARAMETERS: EnableMask - Bit mask to write to the GPE register
327 * GpeRegisterInfo - Gpe Register info
331 * DESCRIPTION: Write the enable mask byte to the given GPE register.
333 ******************************************************************************/
336 AcpiHwGpeEnableWrite (
338 ACPI_GPE_REGISTER_INFO
*GpeRegisterInfo
)
343 GpeRegisterInfo
->EnableMask
= EnableMask
;
345 Status
= AcpiHwWrite (EnableMask
, &GpeRegisterInfo
->EnableAddress
);
350 /******************************************************************************
352 * FUNCTION: AcpiHwDisableGpeBlock
354 * PARAMETERS: GpeXruptInfo - GPE Interrupt info
355 * GpeBlock - Gpe Block info
359 * DESCRIPTION: Disable all GPEs within a single GPE block
361 ******************************************************************************/
364 AcpiHwDisableGpeBlock (
365 ACPI_GPE_XRUPT_INFO
*GpeXruptInfo
,
366 ACPI_GPE_BLOCK_INFO
*GpeBlock
,
373 /* Examine each GPE Register within the block */
375 for (i
= 0; i
< GpeBlock
->RegisterCount
; i
++)
377 /* Disable all GPEs in this register */
379 Status
= AcpiHwGpeEnableWrite (0x00, &GpeBlock
->RegisterInfo
[i
]);
380 if (ACPI_FAILURE (Status
))
390 /******************************************************************************
392 * FUNCTION: AcpiHwClearGpeBlock
394 * PARAMETERS: GpeXruptInfo - GPE Interrupt info
395 * GpeBlock - Gpe Block info
399 * DESCRIPTION: Clear status bits for all GPEs within a single GPE block
401 ******************************************************************************/
404 AcpiHwClearGpeBlock (
405 ACPI_GPE_XRUPT_INFO
*GpeXruptInfo
,
406 ACPI_GPE_BLOCK_INFO
*GpeBlock
,
413 /* Examine each GPE Register within the block */
415 for (i
= 0; i
< GpeBlock
->RegisterCount
; i
++)
417 /* Clear status on all GPEs in this register */
419 Status
= AcpiHwWrite (0xFF, &GpeBlock
->RegisterInfo
[i
].StatusAddress
);
420 if (ACPI_FAILURE (Status
))
430 /******************************************************************************
432 * FUNCTION: AcpiHwEnableRuntimeGpeBlock
434 * PARAMETERS: GpeXruptInfo - GPE Interrupt info
435 * GpeBlock - Gpe Block info
439 * DESCRIPTION: Enable all "runtime" GPEs within a single GPE block. Includes
440 * combination wake/run GPEs.
442 ******************************************************************************/
445 AcpiHwEnableRuntimeGpeBlock (
446 ACPI_GPE_XRUPT_INFO
*GpeXruptInfo
,
447 ACPI_GPE_BLOCK_INFO
*GpeBlock
,
452 ACPI_GPE_REGISTER_INFO
*GpeRegisterInfo
;
456 /* NOTE: assumes that all GPEs are currently disabled */
458 /* Examine each GPE Register within the block */
460 for (i
= 0; i
< GpeBlock
->RegisterCount
; i
++)
462 GpeRegisterInfo
= &GpeBlock
->RegisterInfo
[i
];
463 if (!GpeRegisterInfo
->EnableForRun
)
468 /* Enable all "runtime" GPEs in this register */
470 EnableMask
= GpeRegisterInfo
->EnableForRun
&
471 ~GpeRegisterInfo
->MaskForRun
;
472 Status
= AcpiHwGpeEnableWrite (EnableMask
, GpeRegisterInfo
);
473 if (ACPI_FAILURE (Status
))
483 /******************************************************************************
485 * FUNCTION: AcpiHwEnableWakeupGpeBlock
487 * PARAMETERS: GpeXruptInfo - GPE Interrupt info
488 * GpeBlock - Gpe Block info
492 * DESCRIPTION: Enable all "wake" GPEs within a single GPE block. Includes
493 * combination wake/run GPEs.
495 ******************************************************************************/
498 AcpiHwEnableWakeupGpeBlock (
499 ACPI_GPE_XRUPT_INFO
*GpeXruptInfo
,
500 ACPI_GPE_BLOCK_INFO
*GpeBlock
,
505 ACPI_GPE_REGISTER_INFO
*GpeRegisterInfo
;
508 /* Examine each GPE Register within the block */
510 for (i
= 0; i
< GpeBlock
->RegisterCount
; i
++)
512 GpeRegisterInfo
= &GpeBlock
->RegisterInfo
[i
];
515 * Enable all "wake" GPEs in this register and disable the
518 Status
= AcpiHwGpeEnableWrite (GpeRegisterInfo
->EnableForWake
,
520 if (ACPI_FAILURE (Status
))
530 /******************************************************************************
532 * FUNCTION: AcpiHwDisableAllGpes
538 * DESCRIPTION: Disable and clear all GPEs in all GPE blocks
540 ******************************************************************************/
543 AcpiHwDisableAllGpes (
549 ACPI_FUNCTION_TRACE (HwDisableAllGpes
);
552 Status
= AcpiEvWalkGpeList (AcpiHwDisableGpeBlock
, NULL
);
553 return_ACPI_STATUS (Status
);
557 /******************************************************************************
559 * FUNCTION: AcpiHwEnableAllRuntimeGpes
565 * DESCRIPTION: Enable all "runtime" GPEs, in all GPE blocks
567 ******************************************************************************/
570 AcpiHwEnableAllRuntimeGpes (
576 ACPI_FUNCTION_TRACE (HwEnableAllRuntimeGpes
);
579 Status
= AcpiEvWalkGpeList (AcpiHwEnableRuntimeGpeBlock
, NULL
);
580 return_ACPI_STATUS (Status
);
584 /******************************************************************************
586 * FUNCTION: AcpiHwEnableAllWakeupGpes
592 * DESCRIPTION: Enable all "wakeup" GPEs, in all GPE blocks
594 ******************************************************************************/
597 AcpiHwEnableAllWakeupGpes (
603 ACPI_FUNCTION_TRACE (HwEnableAllWakeupGpes
);
606 Status
= AcpiEvWalkGpeList (AcpiHwEnableWakeupGpeBlock
, NULL
);
607 return_ACPI_STATUS (Status
);
610 #endif /* !ACPI_REDUCED_HARDWARE */