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

Commit 3bd741bd authored by Rafael J. Wysocki's avatar Rafael J. Wysocki Committed by Len Brown
Browse files

ACPICA: Use low-level GPE enable during GPE block initialization



The GPE block initialization code in acpi_ev_initialize_gpe_block()
uses acpi_set_gpe() to make sure that the GPEs with nonzero
runtime counter will remain enabled, but since it already has
a struct acpi_gpe_event_info object for each GPE, it might use
the low-level GPE enabling function, acpi_clear_and_enable_gpe(),
for this purpose.

To make that happen, move acpi_clear_and_enable_gpe() to
drivers/acpi/acpica/evgpe.c and rename it to acpi_ev_enable_gpe(),
modify the two existing users of it accordingly and modify
acpi_ev_initialize_gpe_block() to use it instead of acpi_set_gpe()
and to check its return value.

Signed-off-by: default avatarRafael J. Wysocki <rjw@sisk.pl>
Signed-off-by: default avatarLen Brown <len.brown@intel.com>
Signed-off-by: default avatarBob Moore <robert.moore@intel.com>
Signed-off-by: default avatarLin Ming <ming.m.lin@intel.com>
Signed-off-by: default avatarLen Brown <len.brown@intel.com>
parent 3784730b
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -80,6 +80,8 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info *gpe_xrupt_list);
acpi_status
acpi_ev_update_gpe_enable_mask(struct acpi_gpe_event_info *gpe_event_info);

acpi_status acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info);

struct acpi_gpe_event_info *acpi_ev_get_gpe_event_info(acpi_handle gpe_device,
						       u32 gpe_number);

+40 −0
Original line number Diff line number Diff line
@@ -94,6 +94,46 @@ acpi_ev_update_gpe_enable_mask(struct acpi_gpe_event_info *gpe_event_info)
	return_ACPI_STATUS(AE_OK);
}

/*******************************************************************************
 *
 * FUNCTION:    acpi_ev_enable_gpe
 *
 * PARAMETERS:  gpe_event_info  - GPE to enable
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Clear the given GPE from stale events and enable it.
 *
 ******************************************************************************/
acpi_status
acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info)
{
	acpi_status status;

	ACPI_FUNCTION_TRACE(ev_enable_gpe);

	/*
	 * We will only allow a GPE to be enabled if it has either an
	 * associated method (_Lxx/_Exx) or a handler. Otherwise, the
	 * GPE will be immediately disabled by acpi_ev_gpe_dispatch the
	 * first time it fires.
	 */
	if (!(gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK)) {
		return_ACPI_STATUS(AE_NO_HANDLER);
	}

	/* Clear the GPE (of stale events) */
	status = acpi_hw_clear_gpe(gpe_event_info);
	if (ACPI_FAILURE(status)) {
		return_ACPI_STATUS(status);
	}

	/* Enable the requested GPE */
	status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_ENABLE);

	return_ACPI_STATUS(status);
}


/*******************************************************************************
 *
+3 −4
Original line number Diff line number Diff line
@@ -508,10 +508,8 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device,
			 * increment its reference counter.
			 */
			if (gpe_event_info->runtime_count) {
				acpi_set_gpe(gpe_device, gpe_number,
						ACPI_GPE_ENABLE);
				gpe_enabled_count++;
				continue;
				status = acpi_ev_enable_gpe(gpe_event_info);
				goto enabled;
			}

			if (gpe_event_info->flags & ACPI_GPE_CAN_WAKE) {
@@ -530,6 +528,7 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device,
			/* Enable this GPE */

			status = acpi_enable_gpe(gpe_device, gpe_number);
		      enabled:
			if (ACPI_FAILURE(status)) {
				ACPI_EXCEPTION((AE_INFO, status,
						"Could not enable GPE 0x%02X",
+2 −40
Original line number Diff line number Diff line
@@ -208,44 +208,6 @@ acpi_status acpi_enable_event(u32 event, u32 flags)

ACPI_EXPORT_SYMBOL(acpi_enable_event)

/*******************************************************************************
 *
 * FUNCTION:    acpi_clear_and_enable_gpe
 *
 * PARAMETERS:  gpe_event_info  - GPE to enable
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Clear the given GPE from stale events and enable it.
 *
 ******************************************************************************/
static acpi_status
acpi_clear_and_enable_gpe(struct acpi_gpe_event_info *gpe_event_info)
{
	acpi_status status;

	/*
	 * We will only allow a GPE to be enabled if it has either an
	 * associated method (_Lxx/_Exx) or a handler. Otherwise, the
	 * GPE will be immediately disabled by acpi_ev_gpe_dispatch the
	 * first time it fires.
	 */
	if (!(gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK)) {
		return_ACPI_STATUS(AE_NO_HANDLER);
	}

	/* Clear the GPE (of stale events) */
	status = acpi_hw_clear_gpe(gpe_event_info);
	if (ACPI_FAILURE(status)) {
		return_ACPI_STATUS(status);
	}

	/* Enable the requested GPE */
	status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_ENABLE);

	return_ACPI_STATUS(status);
}

/*******************************************************************************
 *
 * FUNCTION:    acpi_set_gpe
@@ -287,7 +249,7 @@ acpi_status acpi_set_gpe(acpi_handle gpe_device, u32 gpe_number, u8 action)

	switch (action) {
	case ACPI_GPE_ENABLE:
		status = acpi_clear_and_enable_gpe(gpe_event_info);
		status = acpi_ev_enable_gpe(gpe_event_info);
		break;

	case ACPI_GPE_DISABLE:
@@ -414,7 +376,7 @@ acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number)
	if (gpe_event_info->runtime_count == 1) {
		status = acpi_ev_update_gpe_enable_mask(gpe_event_info);
		if (ACPI_SUCCESS(status)) {
			status = acpi_clear_and_enable_gpe(gpe_event_info);
			status = acpi_ev_enable_gpe(gpe_event_info);
		}
		if (ACPI_FAILURE(status)) {
			gpe_event_info->runtime_count--;