1 /******************************************************************************
3 * Module Name: hwgpe - Low level GPE enable/disable/clear functions
5 *****************************************************************************/
8 * Copyright (C) 2000 - 2015, 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;
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 /* Write the updated enable mask */
169 Status = AcpiHwWrite (EnableMask, &GpeRegisterInfo->EnableAddress);
174 /******************************************************************************
176 * FUNCTION: AcpiHwClearGpe
178 * PARAMETERS: GpeEventInfo - Info block for the GPE to be cleared
182 * DESCRIPTION: Clear the status bit for a single GPE.
184 ******************************************************************************/
188 ACPI_GPE_EVENT_INFO *GpeEventInfo)
190 ACPI_GPE_REGISTER_INFO *GpeRegisterInfo;
195 ACPI_FUNCTION_ENTRY ();
197 /* Get the info block for the entire GPE register */
199 GpeRegisterInfo = GpeEventInfo->RegisterInfo;
200 if (!GpeRegisterInfo)
202 return (AE_NOT_EXIST);
206 * Write a one to the appropriate bit in the status register to
209 RegisterBit = AcpiHwGetGpeRegisterBit (GpeEventInfo);
211 Status = AcpiHwWrite (RegisterBit,
212 &GpeRegisterInfo->StatusAddress);
218 /******************************************************************************
220 * FUNCTION: AcpiHwGetGpeStatus
222 * PARAMETERS: GpeEventInfo - Info block for the GPE to queried
223 * EventStatus - Where the GPE status is returned
227 * DESCRIPTION: Return the status of a single GPE.
229 ******************************************************************************/
233 ACPI_GPE_EVENT_INFO *GpeEventInfo,
234 ACPI_EVENT_STATUS *EventStatus)
238 ACPI_GPE_REGISTER_INFO *GpeRegisterInfo;
239 ACPI_EVENT_STATUS LocalEventStatus = 0;
243 ACPI_FUNCTION_ENTRY ();
248 return (AE_BAD_PARAMETER);
251 /* GPE currently handled? */
253 if (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) !=
254 ACPI_GPE_DISPATCH_NONE)
256 LocalEventStatus |= ACPI_EVENT_FLAG_HAS_HANDLER;
259 /* Get the info block for the entire GPE register */
261 GpeRegisterInfo = GpeEventInfo->RegisterInfo;
263 /* Get the register bitmask for this GPE */
265 RegisterBit = AcpiHwGetGpeRegisterBit (GpeEventInfo);
267 /* GPE currently enabled? (enabled for runtime?) */
269 if (RegisterBit & GpeRegisterInfo->EnableForRun)
271 LocalEventStatus |= ACPI_EVENT_FLAG_ENABLED;
274 /* GPE enabled for wake? */
276 if (RegisterBit & GpeRegisterInfo->EnableForWake)
278 LocalEventStatus |= ACPI_EVENT_FLAG_WAKE_ENABLED;
281 /* GPE currently enabled (enable bit == 1)? */
283 Status = AcpiHwRead (&InByte, &GpeRegisterInfo->EnableAddress);
284 if (ACPI_FAILURE (Status))
289 if (RegisterBit & InByte)
291 LocalEventStatus |= ACPI_EVENT_FLAG_ENABLE_SET;
294 /* GPE currently active (status bit == 1)? */
296 Status = AcpiHwRead (&InByte, &GpeRegisterInfo->StatusAddress);
297 if (ACPI_FAILURE (Status))
302 if (RegisterBit & InByte)
304 LocalEventStatus |= ACPI_EVENT_FLAG_STATUS_SET;
307 /* Set return value */
309 (*EventStatus) = LocalEventStatus;
314 /******************************************************************************
316 * FUNCTION: AcpiHwGpeEnableWrite
318 * PARAMETERS: EnableMask - Bit mask to write to the GPE register
319 * GpeRegisterInfo - Gpe Register info
323 * DESCRIPTION: Write the enable mask byte to the given GPE register.
325 ******************************************************************************/
328 AcpiHwGpeEnableWrite (
330 ACPI_GPE_REGISTER_INFO *GpeRegisterInfo)
335 GpeRegisterInfo->EnableMask = EnableMask;
336 Status = AcpiHwWrite (EnableMask, &GpeRegisterInfo->EnableAddress);
342 /******************************************************************************
344 * FUNCTION: AcpiHwDisableGpeBlock
346 * PARAMETERS: GpeXruptInfo - GPE Interrupt info
347 * GpeBlock - Gpe Block info
351 * DESCRIPTION: Disable all GPEs within a single GPE block
353 ******************************************************************************/
356 AcpiHwDisableGpeBlock (
357 ACPI_GPE_XRUPT_INFO *GpeXruptInfo,
358 ACPI_GPE_BLOCK_INFO *GpeBlock,
365 /* Examine each GPE Register within the block */
367 for (i = 0; i < GpeBlock->RegisterCount; i++)
369 /* Disable all GPEs in this register */
371 Status = AcpiHwGpeEnableWrite (0x00, &GpeBlock->RegisterInfo[i]);
372 if (ACPI_FAILURE (Status))
382 /******************************************************************************
384 * FUNCTION: AcpiHwClearGpeBlock
386 * PARAMETERS: GpeXruptInfo - GPE Interrupt info
387 * GpeBlock - Gpe Block info
391 * DESCRIPTION: Clear status bits for all GPEs within a single GPE block
393 ******************************************************************************/
396 AcpiHwClearGpeBlock (
397 ACPI_GPE_XRUPT_INFO *GpeXruptInfo,
398 ACPI_GPE_BLOCK_INFO *GpeBlock,
405 /* Examine each GPE Register within the block */
407 for (i = 0; i < GpeBlock->RegisterCount; i++)
409 /* Clear status on all GPEs in this register */
411 Status = AcpiHwWrite (0xFF, &GpeBlock->RegisterInfo[i].StatusAddress);
412 if (ACPI_FAILURE (Status))
422 /******************************************************************************
424 * FUNCTION: AcpiHwEnableRuntimeGpeBlock
426 * PARAMETERS: GpeXruptInfo - GPE Interrupt info
427 * GpeBlock - Gpe Block info
431 * DESCRIPTION: Enable all "runtime" GPEs within a single GPE block. Includes
432 * combination wake/run GPEs.
434 ******************************************************************************/
437 AcpiHwEnableRuntimeGpeBlock (
438 ACPI_GPE_XRUPT_INFO *GpeXruptInfo,
439 ACPI_GPE_BLOCK_INFO *GpeBlock,
444 ACPI_GPE_REGISTER_INFO *GpeRegisterInfo;
447 /* NOTE: assumes that all GPEs are currently disabled */
449 /* Examine each GPE Register within the block */
451 for (i = 0; i < GpeBlock->RegisterCount; i++)
453 GpeRegisterInfo = &GpeBlock->RegisterInfo[i];
454 if (!GpeRegisterInfo->EnableForRun)
459 /* Enable all "runtime" GPEs in this register */
461 Status = AcpiHwGpeEnableWrite (GpeRegisterInfo->EnableForRun,
463 if (ACPI_FAILURE (Status))
473 /******************************************************************************
475 * FUNCTION: AcpiHwEnableWakeupGpeBlock
477 * PARAMETERS: GpeXruptInfo - GPE Interrupt info
478 * GpeBlock - Gpe Block info
482 * DESCRIPTION: Enable all "wake" GPEs within a single GPE block. Includes
483 * combination wake/run GPEs.
485 ******************************************************************************/
488 AcpiHwEnableWakeupGpeBlock (
489 ACPI_GPE_XRUPT_INFO *GpeXruptInfo,
490 ACPI_GPE_BLOCK_INFO *GpeBlock,
495 ACPI_GPE_REGISTER_INFO *GpeRegisterInfo;
498 /* Examine each GPE Register within the block */
500 for (i = 0; i < GpeBlock->RegisterCount; i++)
502 GpeRegisterInfo = &GpeBlock->RegisterInfo[i];
505 * Enable all "wake" GPEs in this register and disable the
508 Status = AcpiHwGpeEnableWrite (GpeRegisterInfo->EnableForWake,
510 if (ACPI_FAILURE (Status))
520 /******************************************************************************
522 * FUNCTION: AcpiHwDisableAllGpes
528 * DESCRIPTION: Disable and clear all GPEs in all GPE blocks
530 ******************************************************************************/
533 AcpiHwDisableAllGpes (
539 ACPI_FUNCTION_TRACE (HwDisableAllGpes);
542 Status = AcpiEvWalkGpeList (AcpiHwDisableGpeBlock, NULL);
543 Status = AcpiEvWalkGpeList (AcpiHwClearGpeBlock, NULL);
544 return_ACPI_STATUS (Status);
548 /******************************************************************************
550 * FUNCTION: AcpiHwEnableAllRuntimeGpes
556 * DESCRIPTION: Enable all "runtime" GPEs, in all GPE blocks
558 ******************************************************************************/
561 AcpiHwEnableAllRuntimeGpes (
567 ACPI_FUNCTION_TRACE (HwEnableAllRuntimeGpes);
570 Status = AcpiEvWalkGpeList (AcpiHwEnableRuntimeGpeBlock, NULL);
571 return_ACPI_STATUS (Status);
575 /******************************************************************************
577 * FUNCTION: AcpiHwEnableAllWakeupGpes
583 * DESCRIPTION: Enable all "wakeup" GPEs, in all GPE blocks
585 ******************************************************************************/
588 AcpiHwEnableAllWakeupGpes (
594 ACPI_FUNCTION_TRACE (HwEnableAllWakeupGpes);
597 Status = AcpiEvWalkGpeList (AcpiHwEnableWakeupGpeBlock, NULL);
598 return_ACPI_STATUS (Status);
601 #endif /* !ACPI_REDUCED_HARDWARE */