Ejemplo n.º 1
0
static int
acpi_battery_get_status (
	struct acpi_battery	*battery,
	struct acpi_battery_status **bst)
{
	int			result = 0;
	acpi_status 		status = 0;
	struct acpi_buffer	buffer = {ACPI_ALLOCATE_BUFFER, NULL};
	struct acpi_buffer	format = {sizeof(ACPI_BATTERY_FORMAT_BST),
						ACPI_BATTERY_FORMAT_BST};
	struct acpi_buffer	data = {0, NULL};
	union acpi_object	*package = NULL;

	ACPI_FUNCTION_TRACE("acpi_battery_get_status");

	if (!battery || !bst)
		return_VALUE(-EINVAL);

	/* Evalute _BST */

	status = acpi_evaluate_object(battery->handle, "_BST", NULL, &buffer);
	if (ACPI_FAILURE(status)) {
		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error evaluating _BST\n"));
		return_VALUE(-ENODEV);
	}

	package = (union acpi_object *) buffer.pointer;

	/* Extract Package Data */

	status = acpi_extract_package(package, &format, &data);
	if (status != AE_BUFFER_OVERFLOW) {
		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error extracting _BST\n"));
		result = -ENODEV;
		goto end;
	}

	data.pointer = kmalloc(data.length, GFP_KERNEL);
	if (!data.pointer) {
		result = -ENOMEM;
		goto end;
	}
	memset(data.pointer, 0, data.length);

	status = acpi_extract_package(package, &format, &data);
	if (ACPI_FAILURE(status)) {
		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error extracting _BST\n"));
		kfree(data.pointer);
		result = -ENODEV;
		goto end;
	}

end:
	acpi_os_free(buffer.pointer);

	if (!result)
		(*bst) = (struct acpi_battery_status *) data.pointer;

	return_VALUE(result);
}
static int
acpi_battery_get_status(struct acpi_battery *battery,
			struct acpi_battery_status **bst)
{
	int result = 0;
	acpi_status status = 0;
	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
	struct acpi_buffer format = { sizeof(ACPI_BATTERY_FORMAT_BST),
		ACPI_BATTERY_FORMAT_BST
	};
	struct acpi_buffer data = { 0, NULL };
	union acpi_object *package = NULL;


	if (!battery || !bst)
		return -EINVAL;

	/* Evalute _BST */

	status = acpi_evaluate_object(battery->device->handle, "_BST", NULL, &buffer);
	if (ACPI_FAILURE(status)) {
		ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BST"));
		return -ENODEV;
	}

	package = (union acpi_object *)buffer.pointer;

	/* Extract Package Data */

	status = acpi_extract_package(package, &format, &data);
	if (status != AE_BUFFER_OVERFLOW) {
		ACPI_EXCEPTION((AE_INFO, status, "Extracting _BST"));
		result = -ENODEV;
		goto end;
	}

	data.pointer = kmalloc(data.length, GFP_KERNEL);
	if (!data.pointer) {
		result = -ENOMEM;
		goto end;
	}
	memset(data.pointer, 0, data.length);

	status = acpi_extract_package(package, &format, &data);
	if (ACPI_FAILURE(status)) {
		ACPI_EXCEPTION((AE_INFO, status, "Extracting _BST"));
		kfree(data.pointer);
		result = -ENODEV;
		goto end;
	}

      end:
	kfree(buffer.pointer);

	if (!result)
		(*bst) = (struct acpi_battery_status *)data.pointer;

	return result;
}
Ejemplo n.º 3
0
static int acpi_processor_get_psd(struct acpi_processor	*pr)
{
	int result = 0;
	acpi_status status = AE_OK;
	struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
	struct acpi_buffer format = {sizeof("NNNNN"), "NNNNN"};
	struct acpi_buffer state = {0, NULL};
	union acpi_object  *psd = NULL;
	struct acpi_psd_package *pdomain;

	status = acpi_evaluate_object(pr->handle, "_PSD", NULL, &buffer);
	if (ACPI_FAILURE(status)) {
		return -ENODEV;
	}

	psd = buffer.pointer;
	if (!psd || (psd->type != ACPI_TYPE_PACKAGE)) {
		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PSD data\n"));
		result = -EFAULT;
		goto end;
	}

	if (psd->package.count != 1) {
		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PSD data\n"));
		result = -EFAULT;
		goto end;
	}

	pdomain = &(pr->performance->domain_info);

	state.length = sizeof(struct acpi_psd_package);
	state.pointer = pdomain;

	status = acpi_extract_package(&(psd->package.elements[0]),
		&format, &state);
	if (ACPI_FAILURE(status)) {
		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PSD data\n"));
		result = -EFAULT;
		goto end;
	}

	if (pdomain->num_entries != ACPI_PSD_REV0_ENTRIES) {
		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unknown _PSD:num_entries\n"));
		result = -EFAULT;
		goto end;
	}

	if (pdomain->revision != ACPI_PSD_REV0_REVISION) {
		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unknown _PSD:revision\n"));
		result = -EFAULT;
		goto end;
	}

end:
	kfree(buffer.pointer);
	return result;
}
Ejemplo n.º 4
0
static int acpi_get_psd(struct cpc_desc *cpc_ptr, acpi_handle handle)
{
	int result = -EFAULT;
	acpi_status status = AE_OK;
	struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
	struct acpi_buffer format = {sizeof("NNNNN"), "NNNNN"};
	struct acpi_buffer state = {0, NULL};
	union acpi_object  *psd = NULL;
	struct acpi_psd_package *pdomain;

	status = acpi_evaluate_object_typed(handle, "_PSD", NULL, &buffer,
			ACPI_TYPE_PACKAGE);
	if (ACPI_FAILURE(status))
		return -ENODEV;

	psd = buffer.pointer;
	if (!psd || psd->package.count != 1) {
		pr_debug("Invalid _PSD data\n");
		goto end;
	}

	pdomain = &(cpc_ptr->domain_info);

	state.length = sizeof(struct acpi_psd_package);
	state.pointer = pdomain;

	status = acpi_extract_package(&(psd->package.elements[0]),
		&format, &state);
	if (ACPI_FAILURE(status)) {
		pr_debug("Invalid _PSD data for CPU:%d\n", cpc_ptr->cpu_id);
		goto end;
	}

	if (pdomain->num_entries != ACPI_PSD_REV0_ENTRIES) {
		pr_debug("Unknown _PSD:num_entries for CPU:%d\n", cpc_ptr->cpu_id);
		goto end;
	}

	if (pdomain->revision != ACPI_PSD_REV0_REVISION) {
		pr_debug("Unknown _PSD:revision for CPU: %d\n", cpc_ptr->cpu_id);
		goto end;
	}

	if (pdomain->coord_type != DOMAIN_COORD_TYPE_SW_ALL &&
	    pdomain->coord_type != DOMAIN_COORD_TYPE_SW_ANY &&
	    pdomain->coord_type != DOMAIN_COORD_TYPE_HW_ALL) {
		pr_debug("Invalid _PSD:coord_type for CPU:%d\n", cpc_ptr->cpu_id);
		goto end;
	}

	result = 0;
end:
	kfree(buffer.pointer);
	return result;
}
Ejemplo n.º 5
0
static acpi_status snd_soc_acpi_find_package(acpi_handle handle, u32 level,
					     void *context, void **ret)
{
	struct acpi_device *adev;
	acpi_status status = AE_OK;
	struct snd_soc_acpi_package_context *pkg_ctx = context;

	pkg_ctx->data_valid = false;

	if (acpi_bus_get_device(handle, &adev))
		return AE_OK;

	if (adev->status.present && adev->status.functional) {
		struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
		union acpi_object  *myobj = NULL;

		status = acpi_evaluate_object_typed(handle, pkg_ctx->name,
						NULL, &buffer,
						ACPI_TYPE_PACKAGE);
		if (ACPI_FAILURE(status))
			return AE_OK;

		myobj = buffer.pointer;
		if (!myobj || myobj->package.count != pkg_ctx->length) {
			kfree(buffer.pointer);
			return AE_OK;
		}

		status = acpi_extract_package(myobj,
					pkg_ctx->format, pkg_ctx->state);
		if (ACPI_FAILURE(status)) {
			kfree(buffer.pointer);
			return AE_OK;
		}

		kfree(buffer.pointer);
		pkg_ctx->data_valid = true;
		return AE_CTRL_TERMINATE;
	}

	return AE_OK;
}
Ejemplo n.º 6
0
static int acpi_processor_get_performance_states(struct acpi_processor *pr)
{
	int result = 0;
	acpi_status status = AE_OK;
	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
	struct acpi_buffer format = { sizeof("NNNNNN"), "NNNNNN" };
	struct acpi_buffer state = { 0, NULL };
	union acpi_object *pss = NULL;
	int i;


	status = acpi_evaluate_object(pr->handle, "_PSS", NULL, &buffer);
	if (ACPI_FAILURE(status)) {
		ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PSS"));
		return -ENODEV;
	}

	pss = buffer.pointer;
	if (!pss || (pss->type != ACPI_TYPE_PACKAGE)) {
		printk(KERN_ERR PREFIX "Invalid _PSS data\n");
		result = -EFAULT;
		goto end;
	}

	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %d performance states\n",
			  pss->package.count));

	pr->performance->state_count = pss->package.count;
	pr->performance->states =
	    kmalloc(sizeof(struct acpi_processor_px) * pss->package.count,
		    GFP_KERNEL);
	if (!pr->performance->states) {
		result = -ENOMEM;
		goto end;
	}

	for (i = 0; i < pr->performance->state_count; i++) {

		struct acpi_processor_px *px = &(pr->performance->states[i]);

		state.length = sizeof(struct acpi_processor_px);
		state.pointer = px;

		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Extracting state %d\n", i));

		status = acpi_extract_package(&(pss->package.elements[i]),
					      &format, &state);
		if (ACPI_FAILURE(status)) {
			ACPI_EXCEPTION((AE_INFO, status, "Invalid _PSS data"));
			result = -EFAULT;
			kfree(pr->performance->states);
			goto end;
		}

		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
				  "State [%d]: core_frequency[%d] power[%d] transition_latency[%d] bus_master_latency[%d] control[0x%x] status[0x%x]\n",
				  i,
				  (u32) px->core_frequency,
				  (u32) px->power,
				  (u32) px->transition_latency,
				  (u32) px->bus_master_latency,
				  (u32) px->control, (u32) px->status));

		if (!px->core_frequency) {
			printk(KERN_ERR PREFIX
				    "Invalid _PSS data: freq is zero\n");
			result = -EFAULT;
			kfree(pr->performance->states);
			goto end;
		}
	}

      end:
	kfree(buffer.pointer);

	return result;
}
Ejemplo n.º 7
0
static int read_capabilities(struct acpi_power_meter_resource *resource)
{
	int res = 0;
	int i;
	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
	struct acpi_buffer state = { 0, NULL };
	struct acpi_buffer format = { sizeof("NNNNNNNNNNN"), "NNNNNNNNNNN" };
	union acpi_object *pss;
	acpi_string *str;
	acpi_status status;

	status = acpi_evaluate_object(resource->acpi_dev->handle, "_PMC", NULL,
				      &buffer);
	if (ACPI_FAILURE(status)) {
		ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PMC"));
		return -ENODEV;
	}

	pss = buffer.pointer;
	if (!pss ||
	    pss->type != ACPI_TYPE_PACKAGE ||
	    pss->package.count != 14) {
		dev_err(&resource->acpi_dev->dev, ACPI_POWER_METER_NAME
			"Invalid _PMC data\n");
		res = -EFAULT;
		goto end;
	}

	
	state.length = sizeof(struct acpi_power_meter_capabilities);
	state.pointer = &resource->caps;

	status = acpi_extract_package(pss, &format, &state);
	if (ACPI_FAILURE(status)) {
		ACPI_EXCEPTION((AE_INFO, status, "Invalid data"));
		res = -EFAULT;
		goto end;
	}

	if (resource->caps.units) {
		dev_err(&resource->acpi_dev->dev, ACPI_POWER_METER_NAME
			"Unknown units %llu.\n",
			resource->caps.units);
		res = -EINVAL;
		goto end;
	}

	
	str = &resource->model_number;

	for (i = 11; i < 14; i++) {
		union acpi_object *element = &(pss->package.elements[i]);

		if (element->type != ACPI_TYPE_STRING) {
			res = -EINVAL;
			goto error;
		}

		*str = kzalloc(sizeof(u8) * (element->string.length + 1),
			       GFP_KERNEL);
		if (!*str) {
			res = -ENOMEM;
			goto error;
		}

		strncpy(*str, element->string.pointer, element->string.length);
		str++;
	}

	dev_info(&resource->acpi_dev->dev, "Found ACPI power meter.\n");
	goto end;
error:
	str = &resource->model_number;
	for (i = 0; i < 3; i++, str++)
		kfree(*str);
end:
	kfree(buffer.pointer);
	return res;
}
Ejemplo n.º 8
0
/**
 * acpi_parse_trt - Thermal Relationship Table _TRT for passive cooling
 *
 * @handle: ACPI handle of the device contains _TRT
 * @trt_count: the number of valid entries resulted from parsing _TRT
 * @trtp: pointer to pointer of array of _TRT entries in parsing result
 * @create_dev: whether to create platform devices for target and source
 *
 */
int acpi_parse_trt(acpi_handle handle, int *trt_count, struct trt **trtp,
		bool create_dev)
{
	acpi_status status;
	int result = 0;
	int i;
	int nr_bad_entries = 0;
	struct trt *trts;
	struct acpi_device *adev;
	union acpi_object *p;
	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
	struct acpi_buffer element = { 0, NULL };
	struct acpi_buffer trt_format = { sizeof("RRNNNNNN"), "RRNNNNNN" };

	if (!acpi_has_method(handle, "_TRT"))
		return -ENODEV;

	status = acpi_evaluate_object(handle, "_TRT", NULL, &buffer);
	if (ACPI_FAILURE(status))
		return -ENODEV;

	p = buffer.pointer;
	if (!p || (p->type != ACPI_TYPE_PACKAGE)) {
		pr_err("Invalid _TRT data\n");
		result = -EFAULT;
		goto end;
	}

	*trt_count = p->package.count;
	trts = kcalloc(*trt_count, sizeof(struct trt), GFP_KERNEL);
	if (!trts) {
		result = -ENOMEM;
		goto end;
	}

	for (i = 0; i < *trt_count; i++) {
		struct trt *trt = &trts[i - nr_bad_entries];

		element.length = sizeof(struct trt);
		element.pointer = trt;

		status = acpi_extract_package(&(p->package.elements[i]),
					      &trt_format, &element);
		if (ACPI_FAILURE(status)) {
			nr_bad_entries++;
			pr_warn("_TRT package %d is invalid, ignored\n", i);
			continue;
		}
		if (!create_dev)
			continue;

		result = acpi_bus_get_device(trt->source, &adev);
		if (result)
			pr_warn("Failed to get source ACPI device\n");

		result = acpi_bus_get_device(trt->target, &adev);
		if (result)
			pr_warn("Failed to get target ACPI device\n");
	}

	result = 0;

	*trtp = trts;
	/* don't count bad entries */
	*trt_count -= nr_bad_entries;
end:
	kfree(buffer.pointer);
	return result;
}
Ejemplo n.º 9
0
/**
 * acpi_parse_art - Parse Active Relationship Table _ART
 *
 * @handle: ACPI handle of the device contains _ART
 * @art_count: the number of valid entries resulted from parsing _ART
 * @artp: pointer to pointer of array of art entries in parsing result
 * @create_dev: whether to create platform devices for target and source
 *
 */
int acpi_parse_art(acpi_handle handle, int *art_count, struct art **artp,
		bool create_dev)
{
	acpi_status status;
	int result = 0;
	int i;
	int nr_bad_entries = 0;
	struct art *arts;
	struct acpi_device *adev;
	union acpi_object *p;
	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
	struct acpi_buffer element = { 0, NULL };
	struct acpi_buffer art_format =	{
		sizeof("RRNNNNNNNNNNN"), "RRNNNNNNNNNNN" };

	if (!acpi_has_method(handle, "_ART"))
		return 0;

	status = acpi_evaluate_object(handle, "_ART", NULL, &buffer);
	if (ACPI_FAILURE(status))
		return -ENODEV;

	p = buffer.pointer;
	if (!p || (p->type != ACPI_TYPE_PACKAGE)) {
		pr_err("Invalid _ART data\n");
		result = -EFAULT;
		goto end;
	}

	/* ignore p->package.elements[0], as this is _ART Revision field */
	*art_count = p->package.count - 1;
	arts = kzalloc(*art_count * sizeof(struct art), GFP_KERNEL);
	if (!arts) {
		result = -ENOMEM;
		goto end;
	}

	for (i = 0; i < *art_count; i++) {
		struct art *art = &arts[i - nr_bad_entries];

		element.length = sizeof(struct art);
		element.pointer = art;

		status = acpi_extract_package(&(p->package.elements[i + 1]),
					      &art_format, &element);
		if (ACPI_FAILURE(status)) {
			pr_warn("_ART package %d is invalid, ignored", i);
			nr_bad_entries++;
			continue;
		}
		if (!create_dev)
			continue;

		if (art->source) {
			result = acpi_bus_get_device(art->source, &adev);
			if (!result)
				acpi_create_platform_device(adev);
			else
				pr_warn("Failed to get source ACPI device\n");
		}
		if (art->target) {
			result = acpi_bus_get_device(art->target, &adev);
			if (!result)
				acpi_create_platform_device(adev);
			else
				pr_warn("Failed to get source ACPI device\n");
		}
	}

	*artp = arts;
	/* don't count bad entries */
	*art_count -= nr_bad_entries;
end:
	kfree(buffer.pointer);
	return result;
}