// SPDX-License-Identifier: GPL-2.0-only
/*
 * INT3400 thermal driver
 *
 * Copyright (C) 2014, Intel Corporation
 * Authors: Zhang Rui <rui.zhang@intel.com>
 */

#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/acpi.h>
#include <linux/thermal.h>
#include "acpi_thermal_rel.h"

#define INT3400_THERMAL_TABLE_CHANGED 0x83
#define INT3400_ODVP_CHANGED 0x88

enum int3400_thermal_uuid {
	INT3400_THERMAL_PASSIVE_1,
	INT3400_THERMAL_ACTIVE,
	INT3400_THERMAL_CRITICAL,
	INT3400_THERMAL_ADAPTIVE_PERFORMANCE,
	INT3400_THERMAL_EMERGENCY_CALL_MODE,
	INT3400_THERMAL_PASSIVE_2,
	INT3400_THERMAL_POWER_BOSS,
	INT3400_THERMAL_VIRTUAL_SENSOR,
	INT3400_THERMAL_COOLING_MODE,
	INT3400_THERMAL_HARDWARE_DUTY_CYCLING,
	INT3400_THERMAL_MAXIMUM_UUID,
};

static char *int3400_thermal_uuids[INT3400_THERMAL_MAXIMUM_UUID] = {
	"42A441D6-AE6A-462b-A84B-4A8CE79027D3",
	"3A95C389-E4B8-4629-A526-C52C88626BAE",
	"97C68AE7-15FA-499c-B8C9-5DA81D606E0A",
	"63BE270F-1C11-48FD-A6F7-3AF253FF3E2D",
	"5349962F-71E6-431D-9AE8-0A635B710AEE",
	"9E04115A-AE87-4D1C-9500-0F3E340BFE75",
	"F5A35014-C209-46A4-993A-EB56DE7530A1",
	"6ED722A7-9240-48A5-B479-31EEF723D7CF",
	"16CAF1B7-DD38-40ED-B1C1-1B8A1913D531",
	"BE84BABF-C4D4-403D-B495-3128FD44dAC1",
};

struct odvp_attr;

struct int3400_thermal_priv {
	struct acpi_device *adev;
	struct platform_device *pdev;
	struct thermal_zone_device *thermal;
	int art_count;
	struct art *arts;
	int trt_count;
	struct trt *trts;
	u8 uuid_bitmap;
	int rel_misc_dev_res;
	int current_uuid_index;
	char *data_vault;
	int odvp_count;
	int *odvp;
	struct odvp_attr *odvp_attrs;
};

static int evaluate_odvp(struct int3400_thermal_priv *priv);

struct odvp_attr {
	int odvp;
	struct int3400_thermal_priv *priv;
	struct kobj_attribute attr;
};

static ssize_t data_vault_read(struct file *file, struct kobject *kobj,
	     struct bin_attribute *attr, char *buf, loff_t off, size_t count)
{
	memcpy(buf, attr->private + off, count);
	return count;
}

static BIN_ATTR_RO(data_vault, 0);

static struct bin_attribute *data_attributes[] = {
	&bin_attr_data_vault,
	NULL,
};

static const struct attribute_group data_attribute_group = {
	.bin_attrs = data_attributes,
};

static ssize_t available_uuids_show(struct device *dev,
				    struct device_attribute *attr,
				    char *buf)
{
	struct int3400_thermal_priv *priv = dev_get_drvdata(dev);
	int i;
	int length = 0;

	if (!priv->uuid_bitmap)
		return sprintf(buf, "UNKNOWN\n");

	for (i = 0; i < INT3400_THERMAL_MAXIMUM_UUID; i++) {
		if (priv->uuid_bitmap & (1 << i))
			if (PAGE_SIZE - length > 0)
				length += scnprintf(&buf[length],
						   PAGE_SIZE - length,
						   "%s\n",
						   int3400_thermal_uuids[i]);
	}

	return length;
}

static ssize_t current_uuid_show(struct device *dev,
				 struct device_attribute *devattr, char *buf)
{
	struct int3400_thermal_priv *priv = dev_get_drvdata(dev);

	if (priv->current_uuid_index == -1)
		return sprintf(buf, "INVALID\n");

	return sprintf(buf, "%s\n",
		       int3400_thermal_uuids[priv->current_uuid_index]);
}

static ssize_t current_uuid_store(struct device *dev,
				  struct device_attribute *attr,
				  const char *buf, size_t count)
{
	struct int3400_thermal_priv *priv = dev_get_drvdata(dev);
	int i;

	for (i = 0; i < INT3400_THERMAL_MAXIMUM_UUID; ++i) {
		if (!strncmp(buf, int3400_thermal_uuids[i],
			     sizeof(int3400_thermal_uuids[i]) - 1)) {
			/*
			 * If we have a list of supported UUIDs, make sure
			 * this one is supported.
			 */
			if (priv->uuid_bitmap &&
			    !(priv->uuid_bitmap & (1 << i)))
				return -EINVAL;

			priv->current_uuid_index = i;
			return count;
		}
	}

	return -EINVAL;
}

static DEVICE_ATTR_RW(current_uuid);
static DEVICE_ATTR_RO(available_uuids);
static struct attribute *uuid_attrs[] = {
	&dev_attr_available_uuids.attr,
	&dev_attr_current_uuid.attr,
	NULL
};

static const struct attribute_group uuid_attribute_group = {
	.attrs = uuid_attrs,
	.name = "uuids"
};

static int int3400_thermal_get_uuids(struct int3400_thermal_priv *priv)
{
	struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER, NULL};
	union acpi_object *obja, *objb;
	int i, j;
	int result = 0;
	acpi_status status;

	status = acpi_evaluate_object(priv->adev->handle, "IDSP", NULL, &buf);
	if (ACPI_FAILURE(status))
		return -ENODEV;

	obja = (union acpi_object *)buf.pointer;
	if (obja->type != ACPI_TYPE_PACKAGE) {
		result = -EINVAL;
		goto end;
	}

	for (i = 0; i < obja->package.count; i++) {
		objb = &obja->package.elements[i];
		if (objb->type != ACPI_TYPE_BUFFER) {
			result = -EINVAL;
			goto end;
		}

		/* UUID must be 16 bytes */
		if (objb->buffer.length != 16) {
			result = -EINVAL;
			goto end;
		}

		for (j = 0; j < INT3400_THERMAL_MAXIMUM_UUID; j++) {
			guid_t guid;

			guid_parse(int3400_thermal_uuids[j], &guid);
			if (guid_equal((guid_t *)objb->buffer.pointer, &guid)) {
				priv->uuid_bitmap |= (1 << j);
				break;
			}
		}
	}

end:
	kfree(buf.pointer);
	return result;
}

static int int3400_thermal_run_osc(acpi_handle handle,
				enum int3400_thermal_uuid uuid, bool enable)
{
	u32 ret, buf[2];
	acpi_status status;
	int result = 0;
	struct acpi_osc_context context = {
		.uuid_str = NULL,
		.rev = 1,
		.cap.length = 8,
	};

	if (uuid < 0 || uuid >= INT3400_THERMAL_MAXIMUM_UUID)
		return -EINVAL;

	context.uuid_str = int3400_thermal_uuids[uuid];

	buf[OSC_QUERY_DWORD] = 0;
	buf[OSC_SUPPORT_DWORD] = enable;

	context.cap.pointer = buf;

	status = acpi_run_osc(handle, &context);
	if (ACPI_SUCCESS(status)) {
		ret = *((u32 *)(context.ret.pointer + 4));
		if (ret != enable)
			result = -EPERM;
	} else
		result = -EPERM;

	kfree(context.ret.pointer);

	return result;
}

static ssize_t odvp_show(struct kobject *kobj, struct kobj_attribute *attr,
			 char *buf)
{
	struct odvp_attr *odvp_attr;

	odvp_attr = container_of(attr, struct odvp_attr, attr);

	return sprintf(buf, "%d\n", odvp_attr->priv->odvp[odvp_attr->odvp]);
}

static void cleanup_odvp(struct int3400_thermal_priv *priv)
{
	int i;

	if (priv->odvp_attrs) {
		for (i = 0; i < priv->odvp_count; i++) {
			sysfs_remove_file(&priv->pdev->dev.kobj,
					  &priv->odvp_attrs[i].attr.attr);
			kfree(priv->odvp_attrs[i].attr.attr.name);
		}
		kfree(priv->odvp_attrs);
	}
	kfree(priv->odvp);
	priv->odvp_count = 0;
}

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;
}

static void int3400_notify(acpi_handle handle,
			u32 event,
			void *data)
{
	struct int3400_thermal_priv *priv = data;
	char *thermal_prop[5];

	if (!priv)
		return;

	switch (event) {
	case INT3400_THERMAL_TABLE_CHANGED:
		thermal_prop[0] = kasprintf(GFP_KERNEL, "NAME=%s",
				priv->thermal->type);
		thermal_prop[1] = kasprintf(GFP_KERNEL, "TEMP=%d",
				priv->thermal->temperature);
		thermal_prop[2] = kasprintf(GFP_KERNEL, "TRIP=");
		thermal_prop[3] = kasprintf(GFP_KERNEL, "EVENT=%d",
				THERMAL_TABLE_CHANGED);
		thermal_prop[4] = NULL;
		kobject_uevent_env(&priv->thermal->device.kobj, KOBJ_CHANGE,
				thermal_prop);
		break;
	case INT3400_ODVP_CHANGED:
		evaluate_odvp(priv);
		break;
	default:
		/* Ignore unknown notification codes sent to INT3400 device */
		break;
	}
}

static int int3400_thermal_get_temp(struct thermal_zone_device *thermal,
			int *temp)
{
	*temp = 20 * 1000; /* faked temp sensor with 20C */
	return 0;
}

static int int3400_thermal_change_mode(struct thermal_zone_device *thermal,
				       enum thermal_device_mode mode)
{
	struct int3400_thermal_priv *priv = thermal->devdata;
	int result = 0;

	if (!priv)
		return -EINVAL;

	if (mode != thermal->mode)
		result = int3400_thermal_run_osc(priv->adev->handle,
						priv->current_uuid_index,
						mode == THERMAL_DEVICE_ENABLED);


	evaluate_odvp(priv);

	return result;
}

static struct thermal_zone_device_ops int3400_thermal_ops = {
	.get_temp = int3400_thermal_get_temp,
	.change_mode = int3400_thermal_change_mode,
};

static struct thermal_zone_params int3400_thermal_params = {
	.governor_name = "user_space",
	.no_hwmon = true,
};

static void int3400_setup_gddv(struct int3400_thermal_priv *priv)
{
	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
	union acpi_object *obj;
	acpi_status status;

	status = acpi_evaluate_object(priv->adev->handle, "GDDV", NULL,
				      &buffer);
	if (ACPI_FAILURE(status) || !buffer.length)
		return;

	obj = buffer.pointer;
	if (obj->type != ACPI_TYPE_PACKAGE || obj->package.count != 1
	    || obj->package.elements[0].type != ACPI_TYPE_BUFFER) {
		kfree(buffer.pointer);
		return;
	}

	priv->data_vault = kmemdup(obj->package.elements[0].buffer.pointer,
				   obj->package.elements[0].buffer.length,
				   GFP_KERNEL);
	bin_attr_data_vault.private = priv->data_vault;
	bin_attr_data_vault.size = obj->package.elements[0].buffer.length;
	kfree(buffer.pointer);
}

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->pdev = pdev;
	priv->adev = adev;

	result = int3400_thermal_get_uuids(priv);

	/* Missing IDSP isn't fatal */
	if (result && result != -ENODEV)
		goto free_priv;

	priv->current_uuid_index = -1;

	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);

	int3400_setup_gddv(priv);

	evaluate_odvp(priv);

	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_rel_misc;

	if (priv->data_vault) {
		result = sysfs_create_group(&pdev->dev.kobj,
					    &data_attribute_group);
		if (result)
			goto free_uuid;
	}

	result = acpi_install_notify_handler(
			priv->adev->handle, ACPI_DEVICE_NOTIFY, int3400_notify,
			(void *)priv);
	if (result)
		goto free_sysfs;

	return 0;

free_sysfs:
	cleanup_odvp(priv);
	if (priv->data_vault) {
		sysfs_remove_group(&pdev->dev.kobj, &data_attribute_group);
		kfree(priv->data_vault);
	}
free_uuid:
	sysfs_remove_group(&pdev->dev.kobj, &uuid_attribute_group);
free_rel_misc:
	if (!priv->rel_misc_dev_res)
		acpi_thermal_rel_misc_device_remove(priv->adev->handle);
	thermal_zone_device_unregister(priv->thermal);
free_art_trt:
	kfree(priv->trts);
	kfree(priv->arts);
free_priv:
	kfree(priv);
	return result;
}

static int int3400_thermal_remove(struct platform_device *pdev)
{
	struct int3400_thermal_priv *priv = platform_get_drvdata(pdev);

	acpi_remove_notify_handler(
			priv->adev->handle, ACPI_DEVICE_NOTIFY,
			int3400_notify);

	cleanup_odvp(priv);

	if (!priv->rel_misc_dev_res)
		acpi_thermal_rel_misc_device_remove(priv->adev->handle);

	if (priv->data_vault)
		sysfs_remove_group(&pdev->dev.kobj, &data_attribute_group);
	sysfs_remove_group(&pdev->dev.kobj, &uuid_attribute_group);
	thermal_zone_device_unregister(priv->thermal);
	kfree(priv->data_vault);
	kfree(priv->trts);
	kfree(priv->arts);
	kfree(priv);
	return 0;
}

static const struct acpi_device_id int3400_thermal_match[] = {
	{"INT3400", 0},
	{"INTC1040", 0},
	{}
};

MODULE_DEVICE_TABLE(acpi, int3400_thermal_match);

static struct platform_driver int3400_thermal_driver = {
	.probe = int3400_thermal_probe,
	.remove = int3400_thermal_remove,
	.driver = {
		   .name = "int3400 thermal",
		   .acpi_match_table = ACPI_PTR(int3400_thermal_match),
		   },
};

module_platform_driver(int3400_thermal_driver);

MODULE_DESCRIPTION("INT3400 Thermal driver");
MODULE_AUTHOR("Zhang Rui <rui.zhang@intel.com>");
MODULE_LICENSE("GPL");
