ACPICA: Events: Introduce acpi_mask_gpe() to implement GPE masking mechanism
ACPICA commit 23a417ca406a527e7ae1710893e59a8b6db30e14 There is a facility in Linux, developers can control the enabling/disabling of a GPE via /sys/firmware/acpi/interrupts/gpexx. This is mainly for debugging purposes. But many users expect to use this facility to implement quirks to mask a specific GPE when there is a gap in Linux causing this GPE to flood. This is not working correctly because currently this facility invokes enabling/disabling counting based GPE driver APIs: acpi_enable_gpe()/acpi_disable_gpe() and the GPE drivers can still affect the count to mess up the GPE masking purposes. However, most of the IRQ chip designs allow masking/unmasking IRQs via a masking bit which is different from the enabled bit to achieve the same purpose. But the GPE hardware doesn't contain such a feature, this brings the trouble. In this patch, we introduce a software mechanism to implement the GPE masking feature, and acpi_mask_gpe() are provided to the OSPMs to mask/unmask GPEs in the above mentioned situation instead of acpi_enable_gpe()/acpi_disable_gpe(). ACPICA BZ 1102. Lv Zheng. Link: https://github.com/acpica/acpica/commit/23a417ca Link: https://bugs.acpica.org/show_bug.cgi?id=1102 Signed-off-by: Lv Zheng <lv.zheng@intel.com> Signed-off-by: Bob Moore <robert.moore@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
这个提交包含在:
@@ -235,11 +235,13 @@ acpi_status acpi_set_gpe(acpi_handle gpe_device, u32 gpe_number, u8 action)
|
||||
case ACPI_GPE_ENABLE:
|
||||
|
||||
status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_ENABLE);
|
||||
gpe_event_info->disable_for_dispatch = FALSE;
|
||||
break;
|
||||
|
||||
case ACPI_GPE_DISABLE:
|
||||
|
||||
status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE);
|
||||
gpe_event_info->disable_for_dispatch = TRUE;
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -255,6 +257,47 @@ unlock_and_exit:
|
||||
|
||||
ACPI_EXPORT_SYMBOL(acpi_set_gpe)
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_mask_gpe
|
||||
*
|
||||
* PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
|
||||
* gpe_number - GPE level within the GPE block
|
||||
* is_masked - Whether the GPE is masked or not
|
||||
*
|
||||
* RETURN: Status
|
||||
*
|
||||
* DESCRIPTION: Unconditionally mask/unmask the an individual GPE, ex., to
|
||||
* prevent a GPE flooding.
|
||||
*
|
||||
******************************************************************************/
|
||||
acpi_status acpi_mask_gpe(acpi_handle gpe_device, u32 gpe_number, u8 is_masked)
|
||||
{
|
||||
struct acpi_gpe_event_info *gpe_event_info;
|
||||
acpi_status status;
|
||||
acpi_cpu_flags flags;
|
||||
|
||||
ACPI_FUNCTION_TRACE(acpi_mask_gpe);
|
||||
|
||||
flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
|
||||
|
||||
/* Ensure that we have a valid GPE number */
|
||||
|
||||
gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
|
||||
if (!gpe_event_info) {
|
||||
status = AE_BAD_PARAMETER;
|
||||
goto unlock_and_exit;
|
||||
}
|
||||
|
||||
status = acpi_ev_mask_gpe(gpe_event_info, is_masked);
|
||||
|
||||
unlock_and_exit:
|
||||
acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
ACPI_EXPORT_SYMBOL(acpi_mask_gpe)
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_mark_gpe_for_wake
|
||||
|
在新工单中引用
屏蔽一个用户