Exemplo n.º 1
0
static long acpi_thermal_rel_ioctl(struct file *f, unsigned int cmd,
				   unsigned long __arg)
{
	int ret = 0;
	unsigned long length = 0;
	int count = 0;
	char __user *arg = (void __user *)__arg;
	struct trt *trts = NULL;
	struct art *arts = NULL;

	switch (cmd) {
	case ACPI_THERMAL_GET_TRT_COUNT:
		ret = acpi_parse_trt(acpi_thermal_rel_handle, &count,
				&trts, false);
		kfree(trts);
		if (!ret)
			return put_user(count, (unsigned long __user *)__arg);
		return ret;
	case ACPI_THERMAL_GET_TRT_LEN:
		ret = acpi_parse_trt(acpi_thermal_rel_handle, &count,
				&trts, false);
		kfree(trts);
		length = count * sizeof(union trt_object);
		if (!ret)
			return put_user(length, (unsigned long __user *)__arg);
		return ret;
	case ACPI_THERMAL_GET_TRT:
		return fill_trt(arg);
	case ACPI_THERMAL_GET_ART_COUNT:
		ret = acpi_parse_art(acpi_thermal_rel_handle, &count,
				&arts, false);
		kfree(arts);
		if (!ret)
			return put_user(count, (unsigned long __user *)__arg);
		return ret;
	case ACPI_THERMAL_GET_ART_LEN:
		ret = acpi_parse_art(acpi_thermal_rel_handle, &count,
				&arts, false);
		kfree(arts);
		length = count * sizeof(union art_object);
		if (!ret)
			return put_user(length, (unsigned long __user *)__arg);
		return ret;

	case ACPI_THERMAL_GET_ART:
		return fill_art(arg);

	default:
		return -ENOTTY;
	}
}
Exemplo n.º 2
0
static int fill_art(char __user *ubuf)
{
	int i;
	int ret;
	int count;
	int art_len;
	struct art *arts = NULL;
	union art_object *art_user;

	ret = acpi_parse_art(acpi_thermal_rel_handle, &count, &arts, false);
	if (ret)
		goto free_art;
	art_len = count * sizeof(union art_object);
	art_user = kzalloc(art_len, GFP_KERNEL);
	if (!art_user) {
		ret = -ENOMEM;
		goto free_art;
	}
	/* now fill in user art data */
	for (i = 0; i < count; i++) {
		/* userspace art needs device name instead of acpi reference */
		get_single_name(arts[i].source, art_user[i].source_device);
		get_single_name(arts[i].target, art_user[i].target_device);
		/* copy the rest int data in addition to source and target */
		memcpy(&art_user[i].weight, &arts[i].weight,
			sizeof(u64) * (ACPI_NR_ART_ELEMENTS - 2));
	}

	if (copy_to_user(ubuf, art_user, art_len))
		ret = -EFAULT;
	kfree(art_user);
free_art:
	kfree(arts);
	return ret;
}
Exemplo n.º 3
0
static int int3400_thermal_probe(struct platform_device *pdev)
{
	struct acpi_device *adev = ACPI_COMPANION(&pdev->dev);
	struct int3400_thermal_priv *priv;
	int result;

	if (!adev)
		return -ENODEV;

	priv = kzalloc(sizeof(struct int3400_thermal_priv), GFP_KERNEL);
	if (!priv)
		return -ENOMEM;

	priv->adev = adev;

	result = int3400_thermal_get_uuids(priv);
	if (result)
		goto free_priv;

	result = acpi_parse_art(priv->adev->handle, &priv->art_count,
				&priv->arts, true);
	if (result)
		dev_dbg(&pdev->dev, "_ART table parsing error\n");

	result = acpi_parse_trt(priv->adev->handle, &priv->trt_count,
				&priv->trts, true);
	if (result)
		dev_dbg(&pdev->dev, "_TRT table parsing error\n");

	platform_set_drvdata(pdev, priv);

	if (priv->uuid_bitmap & 1 << INT3400_THERMAL_PASSIVE_1) {
		int3400_thermal_ops.get_mode = int3400_thermal_get_mode;
		int3400_thermal_ops.set_mode = int3400_thermal_set_mode;
	}
	priv->thermal = thermal_zone_device_register("INT3400 Thermal", 0, 0,
						priv, &int3400_thermal_ops,
						&int3400_thermal_params, 0, 0);
	if (IS_ERR(priv->thermal)) {
		result = PTR_ERR(priv->thermal);
		goto free_art_trt;
	}

	priv->rel_misc_dev_res = acpi_thermal_rel_misc_device_add(
							priv->adev->handle);

	result = sysfs_create_group(&pdev->dev.kobj, &uuid_attribute_group);
	if (result)
		goto free_zone;

	return 0;

free_zone:
	thermal_zone_device_unregister(priv->thermal);
free_art_trt:
	kfree(priv->trts);
	kfree(priv->arts);
free_priv:
	kfree(priv);
	return result;
}