// SPDX-License-Identifier: GPL-2.0-only
/*
 * ACPI INT3403 thermal driver
 * Copyright (c) 2013, Intel Corporation.
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/acpi.h>
#include <linux/thermal.h>
#include <linux/platform_device.h>
#include "int340x_thermal_zone.h"

#define INT3403_TYPE_SENSOR		0x03
#define INT3403_TYPE_CHARGER		0x0B
#define INT3403_TYPE_BATTERY		0x0C
#define INT3403_PERF_CHANGED_EVENT	0x80
#define INT3403_PERF_TRIP_POINT_CHANGED	0x81
#define INT3403_THERMAL_EVENT		0x90

/* Preserved structure for future expandbility */
struct int3403_sensor {
	struct int34x_thermal_zone *int340x_zone;
};

struct int3403_performance_state {
	u64 performance;
	u64 power;
	u64 latency;
	u64 linear;
	u64 control;
	u64 raw_performace;
	char *raw_unit;
	int reserved;
};

struct int3403_cdev {
	struct thermal_cooling_device *cdev;
	unsigned long max_state;
};

struct int3403_priv {
	struct platform_device *pdev;
	struct acpi_device *adev;
	unsigned long long type;
	void *priv;
};

static void int3403_notify(acpi_handle handle,
		u32 event, void *data)
{
	struct int3403_priv *priv = data;
	struct int3403_sensor *obj;

	if (!priv)
		return;

	obj = priv->priv;
	if (priv->type != INT3403_TYPE_SENSOR || !obj)
		return;

	switch (event) {
	case INT3403_PERF_CHANGED_EVENT:
		break;
	case INT3403_THERMAL_EVENT:
		int340x_thermal_zone_device_update(obj->int340x_zone,
						   THERMAL_TRIP_VIOLATED);
		break;
	case INT3403_PERF_TRIP_POINT_CHANGED:
		int340x_thermal_read_trips(obj->int340x_zone);
		int340x_thermal_zone_device_update(obj->int340x_zone,
						   THERMAL_TRIP_CHANGED);
		break;
	default:
		dev_dbg(&priv->pdev->dev, "Unsupported event [0x%x]\n", event);
		break;
	}
}

static int int3403_sensor_add(struct int3403_priv *priv)
{
	int result = 0;
	struct int3403_sensor *obj;

	obj = devm_kzalloc(&priv->pdev->dev, sizeof(*obj), GFP_KERNEL);
	if (!obj)
		return -ENOMEM;

	priv->priv = obj;

	obj->int340x_zone = int340x_thermal_zone_add(priv->adev, NULL);
	if (IS_ERR(obj->int340x_zone))
		return PTR_ERR(obj->int340x_zone);

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

	return 0;

 err_free_obj:
	int340x_thermal_zone_remove(obj->int340x_zone);
	return result;
}

static int int3403_sensor_remove(struct int3403_priv *priv)
{
	struct int3403_sensor *obj = priv->priv;

	acpi_remove_notify_handler(priv->adev->handle,
				   ACPI_DEVICE_NOTIFY, int3403_notify);
	int340x_thermal_zone_remove(obj->int340x_zone);

	return 0;
}

/* INT3403 Cooling devices */
static int int3403_get_max_state(struct thermal_cooling_device *cdev,
				 unsigned long *state)
{
	struct int3403_priv *priv = cdev->devdata;
	struct int3403_cdev *obj = priv->priv;

	*state = obj->max_state;
	return 0;
}

static int int3403_get_cur_state(struct thermal_cooling_device *cdev,
				 unsigned long *state)
{
	struct int3403_priv *priv = cdev->devdata;
	unsigned long long level;
	acpi_status status;

	status = acpi_evaluate_integer(priv->adev->handle, "PPPC", NULL, &level);
	if (ACPI_SUCCESS(status)) {
		*state = level;
		return 0;
	} else
		return -EINVAL;
}

static int
int3403_set_cur_state(struct thermal_cooling_device *cdev, unsigned long state)
{
	struct int3403_priv *priv = cdev->devdata;
	acpi_status status;

	status = acpi_execute_simple_method(priv->adev->handle, "SPPC", state);
	if (ACPI_SUCCESS(status))
		return 0;
	else
		return -EINVAL;
}

static const struct thermal_cooling_device_ops int3403_cooling_ops = {
	.get_max_state = int3403_get_max_state,
	.get_cur_state = int3403_get_cur_state,
	.set_cur_state = int3403_set_cur_state,
};

static int int3403_cdev_add(struct int3403_priv *priv)
{
	int result = 0;
	acpi_status status;
	struct int3403_cdev *obj;
	struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER, NULL };
	union acpi_object *p;

	obj = devm_kzalloc(&priv->pdev->dev, sizeof(*obj), GFP_KERNEL);
	if (!obj)
		return -ENOMEM;

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

	p = buf.pointer;
	if (!p || (p->type != ACPI_TYPE_PACKAGE)) {
		pr_warn("Invalid PPSS data\n");
		kfree(buf.pointer);
		return -EFAULT;
	}

	priv->priv = obj;
	obj->max_state = p->package.count - 1;
	obj->cdev =
		thermal_cooling_device_register(acpi_device_bid(priv->adev),
				priv, &int3403_cooling_ops);
	if (IS_ERR(obj->cdev))
		result = PTR_ERR(obj->cdev);

	kfree(buf.pointer);
	/* TODO: add ACPI notification support */

	return result;
}

static int int3403_cdev_remove(struct int3403_priv *priv)
{
	struct int3403_cdev *obj = priv->priv;

	thermal_cooling_device_unregister(obj->cdev);
	return 0;
}

static int int3403_add(struct platform_device *pdev)
{
	struct int3403_priv *priv;
	int result = 0;
	unsigned long long tmp;
	acpi_status status;

	priv = devm_kzalloc(&pdev->dev, sizeof(struct int3403_priv),
			    GFP_KERNEL);
	if (!priv)
		return -ENOMEM;

	priv->pdev = pdev;
	priv->adev = ACPI_COMPANION(&(pdev->dev));
	if (!priv->adev) {
		result = -EINVAL;
		goto err;
	}


	status = acpi_evaluate_integer(priv->adev->handle, "_TMP",
				       NULL, &tmp);
	if (ACPI_FAILURE(status)) {
		status = acpi_evaluate_integer(priv->adev->handle, "PTYP",
				       NULL, &priv->type);
		if (ACPI_FAILURE(status)) {
			result = -EINVAL;
			goto err;
		}
	} else {
		priv->type = INT3403_TYPE_SENSOR;
	}

	platform_set_drvdata(pdev, priv);
	switch (priv->type) {
	case INT3403_TYPE_SENSOR:
		result = int3403_sensor_add(priv);
		break;
	case INT3403_TYPE_CHARGER:
	case INT3403_TYPE_BATTERY:
		result = int3403_cdev_add(priv);
		break;
	default:
		result = -EINVAL;
	}

	if (result)
		goto err;
	return result;

err:
	return result;
}

static int int3403_remove(struct platform_device *pdev)
{
	struct int3403_priv *priv = platform_get_drvdata(pdev);

	switch (priv->type) {
	case INT3403_TYPE_SENSOR:
		int3403_sensor_remove(priv);
		break;
	case INT3403_TYPE_CHARGER:
	case INT3403_TYPE_BATTERY:
		int3403_cdev_remove(priv);
		break;
	default:
		break;
	}

	return 0;
}

static const struct acpi_device_id int3403_device_ids[] = {
	{"INT3403", 0},
	{"", 0},
};
MODULE_DEVICE_TABLE(acpi, int3403_device_ids);

static struct platform_driver int3403_driver = {
	.probe = int3403_add,
	.remove = int3403_remove,
	.driver = {
		.name = "int3403 thermal",
		.acpi_match_table = int3403_device_ids,
	},
};

module_platform_driver(int3403_driver);

MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>");
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("ACPI INT3403 thermal driver");
