Exemple #1
0
void
ec_query_handler (
	void                    *context)
{
	EC_CONTEXT		*ec = (EC_CONTEXT*)context;
	static char		object_name[5] = {'_','Q','0','0','\0'};
	const char		hex[] = {'0','1','2','3','4','5','6','7','8',
					'9','A','B','C','D','E','F'};

	FUNCTION_TRACE("ec_query_handler");

	if (!ec) {
		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid (NULL) context.\n"));
		return_VOID;
	}

	/*
	 * Evaluate _Qxx:
	 * --------------
	 * Evaluate corresponding _Qxx method.  Note that a zero query value
	 * indicates a spurious EC_SCI (no such thing as _Q00).
	 */
	object_name[2] = hex[((ec->query_data >> 4) & 0x0F)];
	object_name[3] = hex[(ec->query_data & 0x0F)];

	ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Evaluating [%s] for ec [%02x].\n", object_name, ec->device_handle));

	bm_evaluate_object(ec->acpi_handle, object_name, NULL, NULL);

	return_VOID;
}
Exemple #2
0
acpi_status
bm_pr_set_state (
	BM_POWER_RESOURCE	*pr,
	BM_POWER_STATE          target_state)
{
	acpi_status             status = AE_OK;

	FUNCTION_TRACE("bm_pr_set_state");

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

	status = bm_pr_get_state(pr);
	if (ACPI_FAILURE(status)) {
		return_ACPI_STATUS(status);
	}

	if (target_state == pr->state) {
		ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Power resource [%02x] already at target power state [D%d].\n", pr->device_handle, pr->state));
		return_ACPI_STATUS(AE_OK);
	}

	switch (target_state) {

	case ACPI_STATE_D0:
		ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Turning power resource [%02x] ON.\n", pr->device_handle));
		status = bm_evaluate_object(pr->acpi_handle, "_ON", NULL, NULL);
		break;

	case ACPI_STATE_D3:
		ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Turning power resource [%02x] OFF.\n", pr->device_handle));
		status = bm_evaluate_object(pr->acpi_handle, "_OFF", NULL, NULL);
		break;

	default:
		status = AE_BAD_PARAMETER;
		break;
	}

	status = bm_pr_get_state(pr);
	if (ACPI_FAILURE(status)) {
		return_ACPI_STATUS(status);
	}

	return_ACPI_STATUS(status);
}
Exemple #3
0
acpi_status
bm_evaluate_simple_integer (
	acpi_handle             handle,
	acpi_string             pathname,
	u32                     *data)
{
	acpi_status             status = AE_OK;
	acpi_object             *element = NULL;
	acpi_buffer             buffer;

	FUNCTION_TRACE("bm_evaluate_simple_integer");

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

	MEMSET(&buffer, 0, sizeof(acpi_buffer));

	/*
	 * Evaluate Object:
	 * ----------------
	 */
	status = bm_evaluate_object(handle, pathname, NULL, &buffer);
	if (ACPI_FAILURE(status)) {
		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "failed to evaluate object (%s)\n",
			acpi_format_exception(status)));
		goto end;
	}

	/*
	 * Validate Data:
	 * --------------
	 */
	status = bm_cast_buffer(&buffer, (void**)&element,
		sizeof(acpi_object));
	if (ACPI_FAILURE(status)) {
		DEBUG_EVAL_ERROR(ACPI_LV_WARN, handle, pathname, status);
		goto end;
	}

	if (element->type != ACPI_TYPE_INTEGER) {
		status = AE_BAD_DATA;
		DEBUG_EVAL_ERROR(ACPI_LV_WARN, handle, pathname, status);
		goto end;
	}

	*data = element->integer.value;

end:
	acpi_os_free(buffer.pointer);

	return_ACPI_STATUS(status);
}
Exemple #4
0
acpi_status  
bm_evaluate_reference_list (
	acpi_handle             handle,
	acpi_string             pathname,
	BM_HANDLE_LIST          *reference_list)
{
	acpi_status             status = AE_OK;
	acpi_object             *package = NULL;
	acpi_object             *element = NULL;
	acpi_handle  		reference_handle = NULL;
	acpi_buffer             buffer;
	u32                     i = 0;

	FUNCTION_TRACE("bm_evaluate_reference_list");

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

	MEMSET(&buffer, 0, sizeof(acpi_buffer));

	/*
	 * Evaluate Object:
	 * ----------------
	 */
	status = bm_evaluate_object(handle, pathname, NULL, &buffer);
	if (ACPI_FAILURE(status)) {
		goto end;
	}

	/*
	 * Validate Package:
	 * -----------------
	 */
	status = bm_cast_buffer(&buffer, (void**)&package,
		sizeof(acpi_object));
	if (ACPI_FAILURE(status)) {
		DEBUG_EVAL_ERROR(ACPI_LV_WARN, handle, pathname, status);
		goto end;
	}

	if (package->type != ACPI_TYPE_PACKAGE) {
		status = AE_BAD_DATA;
		DEBUG_EVAL_ERROR(ACPI_LV_WARN, handle, pathname, status);
		goto end;
	}

	if (package->package.count > BM_HANDLES_MAX) {
		package->package.count = BM_HANDLES_MAX;
	}

	/*
	 * Parse Package Data:
	 * -------------------
	 */
	for (i = 0; i < package->package.count; i++) {

		element = &(package->package.elements[i]);

		if (!element || (element->type != ACPI_TYPE_STRING)) {
			status = AE_BAD_DATA;
			ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid element in package (not a device reference).\n"));
			DEBUG_EVAL_ERROR (ACPI_LV_WARN, handle, pathname, status);
			break;
		}

		/*
		 * Resolve reference string (e.g. "\_PR_.CPU_") to an
		 * acpi_handle.
		 */
		status = acpi_get_handle(handle,
			element->string.pointer, &reference_handle);
		if (ACPI_FAILURE(status)) {
			status = AE_BAD_DATA;
			ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Unable to resolve device reference [%s].\n", element->string.pointer));
			DEBUG_EVAL_ERROR (ACPI_LV_WARN, handle, pathname, status);
			break;
		}

		/*
		 * Resolve acpi_handle to BM_HANDLE.
		 */
		status = bm_get_handle(reference_handle,
			&(reference_list->handles[i]));
		if (ACPI_FAILURE(status)) {
			status = AE_BAD_DATA;
			ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Unable to resolve device reference for [%p].\n", reference_handle));
			DEBUG_EVAL_ERROR (ACPI_LV_WARN, handle, pathname, status);
			break;
		}

		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resolved reference [%s]->[%p]->[%02x]\n", element->string.pointer, reference_handle, reference_list->handles[i]));

		(reference_list->count)++;
	}

end:
	acpi_os_free(buffer.pointer);

	return_ACPI_STATUS(status);
}
acpi_status
bm_set_power_state (
	BM_NODE			*node,
	BM_POWER_STATE          state)
{
	acpi_status             status = AE_OK;
	BM_DEVICE		*device = NULL;
	BM_DEVICE		*parent_device = NULL;
	BM_HANDLE_LIST          current_list;
	BM_HANDLE_LIST          target_list;
	char                    object_name[5] = {'_','P','R','0','\0'};

	FUNCTION_TRACE("bm_set_power_state");

	if (!node || !node->parent || (state > ACPI_STATE_D3)) {
		return_ACPI_STATUS(AE_BAD_PARAMETER);
	}

	MEMSET(&current_list, 0, sizeof(BM_HANDLE_LIST));
	MEMSET(&target_list, 0, sizeof(BM_HANDLE_LIST));

	device = &(node->device);
	parent_device = &(node->parent->device);

	/*
	 * Power Control?
	 * --------------
	 * If this device isn't directly power manageable (e.g. doesn't
	 * include _PR0/_PS0) then return an error (can't set state).
	 */
	if (!BM_IS_POWER_CONTROL(device)) {
		return_ACPI_STATUS(AE_ERROR);
	}

	/*
	 * Parent Present?
	 * ---------------
	 * Make sure the parent is present before mucking with the child.
	 */
	if (!BM_NODE_PRESENT(node->parent)) {
		return_ACPI_STATUS(AE_NOT_EXIST);
	}
	
	/*
	 * Check Parent's Power State:
	 * ---------------------------
	 * Can't be in a higher power state (lower Dx value) than parent.
	 */
	if (state < parent_device->power.state) {
		ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "Cannot set device [%02x] to a higher-powered state than parent_device.\n", device->handle));
		return_ACPI_STATUS(AE_ERROR);
	}

	/*
	 * Get Resources:
	 * --------------
	 * Get the power resources associated with the device's current
	 * and target power states.
	 */
	if (device->power.state != ACPI_STATE_UNKNOWN) {
		object_name[3] = '0' + device->power.state;
		bm_evaluate_reference_list(device->acpi_handle,
			object_name, &current_list);
	}

	object_name[3] = '0' + state;
	bm_evaluate_reference_list(device->acpi_handle, object_name,
		&target_list);

	/*
	 * Transition Resources:
	 * ---------------------
	 * Transition all power resources referenced by this device to
	 * the correct power state (taking into consideration sequencing
	 * and dependencies to other devices).
	 */
	if (current_list.count || target_list.count) {
		status = bm_pr_list_transition(&current_list, &target_list);
	}
	if (ACPI_FAILURE(status)) {
		return_ACPI_STATUS(status);
	}

	/*
	 * Execute _PSx:
	 * -------------
	 * Execute the _PSx method corresponding to the target Dx state,
	 * if it exists.
	 */
	object_name[2] = 'S';
	object_name[3] = '0' + state;
	bm_evaluate_object(device->acpi_handle, object_name, NULL, NULL);

	if (ACPI_SUCCESS(status)) {
		ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Device [%02x] is now at [D%d].\n", device->handle, state));
		device->power.state = state;
	}

	return_ACPI_STATUS(status);
}