static int evaluate_odvp()

in intel/int340x_thermal/int3400_thermal.c [300:372]


static int evaluate_odvp(struct int3400_thermal_priv *priv)
{
	struct acpi_buffer odvp = { ACPI_ALLOCATE_BUFFER, NULL };
	union acpi_object *obj = NULL;
	acpi_status status;
	int i, ret;

	status = acpi_evaluate_object(priv->adev->handle, "ODVP", NULL, &odvp);
	if (ACPI_FAILURE(status)) {
		ret = -EINVAL;
		goto out_err;
	}

	obj = odvp.pointer;
	if (obj->type != ACPI_TYPE_PACKAGE) {
		ret = -EINVAL;
		goto out_err;
	}

	if (priv->odvp == NULL) {
		priv->odvp_count = obj->package.count;
		priv->odvp = kmalloc_array(priv->odvp_count, sizeof(int),
				     GFP_KERNEL);
		if (!priv->odvp) {
			ret = -ENOMEM;
			goto out_err;
		}
	}

	if (priv->odvp_attrs == NULL) {
		priv->odvp_attrs = kcalloc(priv->odvp_count,
					   sizeof(struct odvp_attr),
					   GFP_KERNEL);
		if (!priv->odvp_attrs) {
			ret = -ENOMEM;
			goto out_err;
		}
		for (i = 0; i < priv->odvp_count; i++) {
			struct odvp_attr *odvp = &priv->odvp_attrs[i];

			sysfs_attr_init(&odvp->attr.attr);
			odvp->priv = priv;
			odvp->odvp = i;
			odvp->attr.attr.name = kasprintf(GFP_KERNEL,
							 "odvp%d", i);

			if (!odvp->attr.attr.name) {
				ret = -ENOMEM;
				goto out_err;
			}
			odvp->attr.attr.mode = 0444;
			odvp->attr.show = odvp_show;
			odvp->attr.store = NULL;
			ret = sysfs_create_file(&priv->pdev->dev.kobj,
						&odvp->attr.attr);
			if (ret)
				goto out_err;
		}
	}

	for (i = 0; i < obj->package.count; i++) {
		if (obj->package.elements[i].type == ACPI_TYPE_INTEGER)
			priv->odvp[i] = obj->package.elements[i].integer.value;
	}

	kfree(obj);
	return 0;

out_err:
	cleanup_odvp(priv);
	kfree(obj);
	return ret;
}