// 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 mode;
	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 = int3400_thermal_uuids[uuid],
		.rev = 1,
		.cap.length = 8,
	};

	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_get_mode(struct thermal_zone_device *thermal,
				enum thermal_device_mode *mode)
{
	struct int3400_thermal_priv *priv = thermal->devdata;

	if (!priv)
		return -EINVAL;

	*mode = priv->mode;

	return 0;
}

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

	if (!priv)
		return -EINVAL;

	if (mode == THERMAL_DEVICE_ENABLED)
		enable = true;
	else if (mode == THERMAL_DEVICE_DISABLED)
		enable = false;
	else
		return -EINVAL;

	if (enable != priv->mode) {
		priv->mode = enable;
		result = int3400_thermal_run_osc(priv->adev->handle,
						 priv->current_uuid_index,
						 enable);
	}

	evaluate_odvp(priv);

	return result;
}

static struct thermal_zone_device_ops int3400_thermal_ops = {
	.get_temp = int3400_thermal_get_temp,
	.get_mode = int3400_thermal_get_mode,
	.set_mode = int3400_thermal_set_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");
