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

Commit e97d6bf1 authored by Bob Moore's avatar Bob Moore Committed by Len Brown
Browse files

ACPICA: New: acpi_get_gpe_device interface



This function maps an input GPE index to a GPE block device. Also
Added acpi_current_gpe_count to track the current number of GPEs
that are being managed by the ACPICA core (both FADT-based GPEs
and the GPEs contained in GPE block devices.)

Modify drivers/acpi/system.c to use these 2 new interfaces

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 c1e3523c
Loading
Loading
Loading
Loading
+20 −5
Original line number Diff line number Diff line
@@ -124,6 +124,7 @@ u8 acpi_ev_valid_gpe_event(struct acpi_gpe_event_info *gpe_event_info)
 * FUNCTION:    acpi_ev_walk_gpe_list
 *
 * PARAMETERS:  gpe_walk_callback   - Routine called for each GPE block
 *              Context             - Value passed to callback
 *
 * RETURN:      Status
 *
@@ -131,7 +132,8 @@ u8 acpi_ev_valid_gpe_event(struct acpi_gpe_event_info *gpe_event_info)
 *
 ******************************************************************************/

acpi_status acpi_ev_walk_gpe_list(acpi_gpe_callback gpe_walk_callback)
acpi_status
acpi_ev_walk_gpe_list(acpi_gpe_callback gpe_walk_callback, void *context)
{
	struct acpi_gpe_block_info *gpe_block;
	struct acpi_gpe_xrupt_info *gpe_xrupt_info;
@@ -154,8 +156,13 @@ acpi_status acpi_ev_walk_gpe_list(acpi_gpe_callback gpe_walk_callback)

			/* One callback per GPE block */

			status = gpe_walk_callback(gpe_xrupt_info, gpe_block);
			status =
			    gpe_walk_callback(gpe_xrupt_info, gpe_block,
					      context);
			if (ACPI_FAILURE(status)) {
				if (status == AE_CTRL_END) {	/* Callback abort */
					status = AE_OK;
				}
				goto unlock_and_exit;
			}

@@ -186,7 +193,8 @@ acpi_status acpi_ev_walk_gpe_list(acpi_gpe_callback gpe_walk_callback)

acpi_status
acpi_ev_delete_gpe_handlers(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
			    struct acpi_gpe_block_info *gpe_block)
			    struct acpi_gpe_block_info *gpe_block,
			    void *context)
{
	struct acpi_gpe_event_info *gpe_event_info;
	u32 i;
@@ -690,7 +698,8 @@ acpi_status acpi_ev_delete_gpe_block(struct acpi_gpe_block_info *gpe_block)

	/* Disable all GPEs in this block */

	status = acpi_hw_disable_gpe_block(gpe_block->xrupt_block, gpe_block);
	status =
	    acpi_hw_disable_gpe_block(gpe_block->xrupt_block, gpe_block, NULL);

	if (!gpe_block->previous && !gpe_block->next) {

@@ -717,6 +726,9 @@ acpi_status acpi_ev_delete_gpe_block(struct acpi_gpe_block_info *gpe_block)
		acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
	}

	acpi_current_gpe_count -=
	    gpe_block->register_count * ACPI_GPE_REGISTER_WIDTH;

	/* Free the gpe_block */

	ACPI_FREE(gpe_block->register_info);
@@ -958,6 +970,9 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device,
			  gpe_device->name.ascii, gpe_block->register_count,
			  interrupt_number));

	/* Update global count of currently available GPEs */

	acpi_current_gpe_count += register_count * ACPI_GPE_REGISTER_WIDTH;
	return_ACPI_STATUS(AE_OK);
}

@@ -1057,7 +1072,7 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device,

	/* Enable all valid runtime GPEs found above */

	status = acpi_hw_enable_runtime_gpe_block(NULL, gpe_block);
	status = acpi_hw_enable_runtime_gpe_block(NULL, gpe_block, NULL);
	if (ACPI_FAILURE(status)) {
		ACPI_ERROR((AE_INFO, "Could not enable GPEs in GpeBlock %p",
			    gpe_block));
+2 −2
Original line number Diff line number Diff line
@@ -588,7 +588,7 @@ void acpi_ev_terminate(void)

		/* Disable all GPEs in all GPE blocks */

		status = acpi_ev_walk_gpe_list(acpi_hw_disable_gpe_block);
		status = acpi_ev_walk_gpe_list(acpi_hw_disable_gpe_block, NULL);

		/* Remove SCI handler */

@@ -606,7 +606,7 @@ void acpi_ev_terminate(void)

	/* Deallocate all handler objects installed within GPE info structs */

	status = acpi_ev_walk_gpe_list(acpi_ev_delete_gpe_handlers);
	status = acpi_ev_walk_gpe_list(acpi_ev_delete_gpe_handlers, NULL);

	/* Return to original mode if necessary */

+93 −0
Original line number Diff line number Diff line
@@ -49,6 +49,11 @@
#define _COMPONENT          ACPI_EVENTS
ACPI_MODULE_NAME("evxfevnt")

/* Local prototypes */
acpi_status
acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
		       struct acpi_gpe_block_info *gpe_block, void *context);

/*******************************************************************************
 *
 * FUNCTION:    acpi_enable
@@ -60,6 +65,7 @@ ACPI_MODULE_NAME("evxfevnt")
 * DESCRIPTION: Transfers the system into ACPI mode.
 *
 ******************************************************************************/

acpi_status acpi_enable(void)
{
	acpi_status status = AE_OK;
@@ -717,3 +723,90 @@ acpi_status acpi_remove_gpe_block(acpi_handle gpe_device)
}

ACPI_EXPORT_SYMBOL(acpi_remove_gpe_block)

/*******************************************************************************
 *
 * FUNCTION:    acpi_get_gpe_device
 *
 * PARAMETERS:  Index               - System GPE index (0-current_gpe_count)
 *              gpe_device          - Where the parent GPE Device is returned
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Obtain the GPE device associated with the input index. A NULL
 *              gpe device indicates that the gpe number is contained in one of
 *              the FADT-defined gpe blocks. Otherwise, the GPE block device.
 *
 ******************************************************************************/
acpi_status
acpi_get_gpe_device(u32 index, acpi_handle *gpe_device)
{
	struct acpi_gpe_device_info info;
	acpi_status status;

	ACPI_FUNCTION_TRACE(acpi_get_gpe_device);

	if (!gpe_device) {
		return_ACPI_STATUS(AE_BAD_PARAMETER);
	}

	if (index >= acpi_current_gpe_count) {
		return_ACPI_STATUS(AE_NOT_EXIST);
	}

	/* Setup and walk the GPE list */

	info.index = index;
	info.status = AE_NOT_EXIST;
	info.gpe_device = NULL;
	info.next_block_base_index = 0;

	status = acpi_ev_walk_gpe_list(acpi_ev_get_gpe_device, &info);
	if (ACPI_FAILURE(status)) {
		return_ACPI_STATUS(status);
	}

	*gpe_device = info.gpe_device;
	return_ACPI_STATUS(info.status);
}

ACPI_EXPORT_SYMBOL(acpi_get_gpe_device)

/*******************************************************************************
 *
 * FUNCTION:    acpi_ev_get_gpe_device
 *
 * PARAMETERS:  GPE_WALK_CALLBACK
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Matches the input GPE index (0-current_gpe_count) with a GPE
 *              block device. NULL if the GPE is one of the FADT-defined GPEs.
 *
 ******************************************************************************/
acpi_status
acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
		       struct acpi_gpe_block_info *gpe_block, void *context)
{
	struct acpi_gpe_device_info *info = context;

	/* Increment Index by the number of GPEs in this block */

	info->next_block_base_index +=
	    (gpe_block->register_count * ACPI_GPE_REGISTER_WIDTH);

	if (info->index < info->next_block_base_index) {
		/*
		 * The GPE index is within this block, get the node. Leave the node
		 * NULL for the FADT-defined GPEs
		 */
		if ((gpe_block->node)->type == ACPI_TYPE_DEVICE) {
			info->gpe_device = gpe_block->node;
		}

		info->status = AE_OK;
		return (AE_CTRL_END);
	}

	return (AE_OK);
}
+14 −12
Original line number Diff line number Diff line
@@ -51,7 +51,8 @@ ACPI_MODULE_NAME("hwgpe")
/* Local prototypes */
static acpi_status
acpi_hw_enable_wakeup_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
				struct acpi_gpe_block_info *gpe_block);
				struct acpi_gpe_block_info *gpe_block,
				void *context);

/******************************************************************************
 *
@@ -261,7 +262,7 @@ acpi_hw_get_gpe_status(struct acpi_gpe_event_info * gpe_event_info,

acpi_status
acpi_hw_disable_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
			  struct acpi_gpe_block_info * gpe_block)
			  struct acpi_gpe_block_info *gpe_block, void *context)
{
	u32 i;
	acpi_status status;
@@ -298,7 +299,7 @@ acpi_hw_disable_gpe_block(struct acpi_gpe_xrupt_info * gpe_xrupt_info,

acpi_status
acpi_hw_clear_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
			struct acpi_gpe_block_info * gpe_block)
			struct acpi_gpe_block_info *gpe_block, void *context)
{
	u32 i;
	acpi_status status;
@@ -336,7 +337,7 @@ acpi_hw_clear_gpe_block(struct acpi_gpe_xrupt_info * gpe_xrupt_info,

acpi_status
acpi_hw_enable_runtime_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
				 struct acpi_gpe_block_info * gpe_block)
				 struct acpi_gpe_block_info *gpe_block, void *context)
{
	u32 i;
	acpi_status status;
@@ -382,7 +383,8 @@ acpi_hw_enable_runtime_gpe_block(struct acpi_gpe_xrupt_info * gpe_xrupt_info,

static acpi_status
acpi_hw_enable_wakeup_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
				struct acpi_gpe_block_info *gpe_block)
				struct acpi_gpe_block_info *gpe_block,
				void *context)
{
	u32 i;
	acpi_status status;
@@ -427,8 +429,8 @@ acpi_status acpi_hw_disable_all_gpes(void)

	ACPI_FUNCTION_TRACE(hw_disable_all_gpes);

	status = acpi_ev_walk_gpe_list(acpi_hw_disable_gpe_block);
	status = acpi_ev_walk_gpe_list(acpi_hw_clear_gpe_block);
	status = acpi_ev_walk_gpe_list(acpi_hw_disable_gpe_block, NULL);
	status = acpi_ev_walk_gpe_list(acpi_hw_clear_gpe_block, NULL);
	return_ACPI_STATUS(status);
}

@@ -450,7 +452,7 @@ acpi_status acpi_hw_enable_all_runtime_gpes(void)

	ACPI_FUNCTION_TRACE(hw_enable_all_runtime_gpes);

	status = acpi_ev_walk_gpe_list(acpi_hw_enable_runtime_gpe_block);
	status = acpi_ev_walk_gpe_list(acpi_hw_enable_runtime_gpe_block, NULL);
	return_ACPI_STATUS(status);
}

@@ -472,6 +474,6 @@ acpi_status acpi_hw_enable_all_wakeup_gpes(void)

	ACPI_FUNCTION_TRACE(hw_enable_all_wakeup_gpes);

	status = acpi_ev_walk_gpe_list(acpi_hw_enable_wakeup_gpe_block);
	status = acpi_ev_walk_gpe_list(acpi_hw_enable_wakeup_gpe_block, NULL);
	return_ACPI_STATUS(status);
}
+1 −1
Original line number Diff line number Diff line
@@ -94,7 +94,7 @@ acpi_status acpi_hw_clear_acpi_status(void)

	/* Clear the GPE Bits in all GPE registers in all GPE blocks */

	status = acpi_ev_walk_gpe_list(acpi_hw_clear_gpe_block);
	status = acpi_ev_walk_gpe_list(acpi_hw_clear_gpe_block, NULL);

      unlock_and_exit:
	acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags);
Loading