Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6ec5e120 authored by Lv Zheng's avatar Lv Zheng Committed by Rafael J. Wysocki
Browse files

ACPICA: Events: Fix edge-triggered GPE by disabling before acknowledging it.



Due to ACPI specificiation 5, chapter 5.6.4 General-Purpose Event Handling,
OSPMs need to disable GPE before clearing the status bit for edge-triggered
GPEs.

Signed-off-by: default avatarLv Zheng <lv.zheng@intel.com>
Tested-by: default avatarGareth Williams <gareth@garethwilliams.me.uk>
Tested-by: default avatarSteffen Weber <steffen.weber@gmail.com>
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent 0a00fd5e
Loading
Loading
Loading
Loading
+17 −15
Original line number Diff line number Diff line
@@ -697,21 +697,6 @@ acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device,
					      acpi_gbl_global_event_handler_context);
	}

	/*
	 * If edge-triggered, clear the GPE status bit now. Note that
	 * level-triggered events are cleared after the GPE is serviced.
	 */
	if ((gpe_event_info->flags & ACPI_GPE_XRUPT_TYPE_MASK) ==
	    ACPI_GPE_EDGE_TRIGGERED) {
		status = acpi_hw_clear_gpe(gpe_event_info);
		if (ACPI_FAILURE(status)) {
			ACPI_EXCEPTION((AE_INFO, status,
					"Unable to clear GPE %02X",
					gpe_number));
			return_UINT32(ACPI_INTERRUPT_NOT_HANDLED);
		}
	}

	/*
	 * Always disable the GPE so that it does not keep firing before
	 * any asynchronous activity completes (either from the execution
@@ -728,6 +713,23 @@ acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device,
		return_UINT32(ACPI_INTERRUPT_NOT_HANDLED);
	}

	/*
	 * If edge-triggered, clear the GPE status bit now. Note that
	 * level-triggered events are cleared after the GPE is serviced.
	 */
	if ((gpe_event_info->flags & ACPI_GPE_XRUPT_TYPE_MASK) ==
	    ACPI_GPE_EDGE_TRIGGERED) {
		status = acpi_hw_clear_gpe(gpe_event_info);
		if (ACPI_FAILURE(status)) {
			ACPI_EXCEPTION((AE_INFO, status,
					"Unable to clear GPE %02X",
					gpe_number));
			(void)acpi_hw_low_set_gpe(gpe_event_info,
						  ACPI_GPE_CONDITIONAL_ENABLE);
			return_UINT32(ACPI_INTERRUPT_NOT_HANDLED);
		}
	}

	/*
	 * Dispatch the GPE to either an installed handler or the control
	 * method associated with this GPE (_Lxx or _Exx). If a handler