// SPDX-License-Identifier: GPL-2.0+
/*
 * Author: zhanghongchen <zhanghongchen@loongson.cn>
 *         Yinbo Zhu <zhuyinbo@loongson.cn>
 * Copyright (C) 2022-2023 Loongson Technology Corporation Limited
 */

#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/minmax.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/thermal.h>
#include <linux/units.h>
#include "thermal_hwmon.h"

#define LOONGSON2_MAX_SENSOR_SEL_NUM			3

#define LOONGSON2_THSENS_CTRL_HI_REG			0x0
#define LOONGSON2_THSENS_CTRL_LOW_REG			0x8
#define LOONGSON2_THSENS_STATUS_REG			0x10
#define LOONGSON2_THSENS_OUT_REG			0x14

#define LOONGSON2_THSENS_INT_LO				BIT(0)
#define LOONGSON2_THSENS_INT_HIGH			BIT(1)
#define LOONGSON2_THSENS_OUT_MASK			0xFF

struct loongson2_thermal_chip_data {
	unsigned int	thermal_sensor_sel;
};

struct loongson2_thermal_data {
	void __iomem	*regs;
	const struct loongson2_thermal_chip_data *chip_data;
};

static int loongson2_thermal_set(struct loongson2_thermal_data *data,
					int low, int high, bool enable)
{
	u64 reg_ctrl = 0;
	int reg_off = data->chip_data->thermal_sensor_sel * 2;

	low = clamp(-40, low, high);
	high = clamp(125, low, high);

	low += HECTO;
	high += HECTO;

	reg_ctrl = low;
	reg_ctrl |= enable ? 0x100 : 0;
	writew(reg_ctrl, data->regs + LOONGSON2_THSENS_CTRL_LOW_REG + reg_off);

	reg_ctrl = high;
	reg_ctrl |= enable ? 0x100 : 0;
	writew(reg_ctrl, data->regs + LOONGSON2_THSENS_CTRL_HI_REG + reg_off);

	return 0;
}

static int loongson2_thermal_get_temp(struct thermal_zone_device *tz, int *temp)
{
	u32 reg_val;
	struct loongson2_thermal_data *data = thermal_zone_device_priv(tz);

	reg_val = readl(data->regs + LOONGSON2_THSENS_OUT_REG);
	*temp = ((reg_val & LOONGSON2_THSENS_OUT_MASK) - HECTO) * KILO;

	return 0;
}

static irqreturn_t loongson2_thermal_irq_thread(int irq, void *dev)
{
	struct thermal_zone_device *tzd = dev;
	struct loongson2_thermal_data *data = thermal_zone_device_priv(tzd);

	writeb(LOONGSON2_THSENS_INT_LO | LOONGSON2_THSENS_INT_HIGH, data->regs +
		LOONGSON2_THSENS_STATUS_REG);

	thermal_zone_device_update(tzd, THERMAL_EVENT_UNSPECIFIED);

	return IRQ_HANDLED;
}

static int loongson2_thermal_set_trips(struct thermal_zone_device *tz, int low, int high)
{
	struct loongson2_thermal_data *data = thermal_zone_device_priv(tz);

	return loongson2_thermal_set(data, low/MILLI, high/MILLI, true);
}

static const struct thermal_zone_device_ops loongson2_of_thermal_ops = {
	.get_temp = loongson2_thermal_get_temp,
	.set_trips = loongson2_thermal_set_trips,
};

static int loongson2_thermal_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct loongson2_thermal_data *data;
	struct thermal_zone_device *tzd;
	int ret, irq, i;

	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
	if (!data)
		return -ENOMEM;

	data->chip_data = device_get_match_data(dev);

	data->regs = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(data->regs))
		return PTR_ERR(data->regs);

	irq = platform_get_irq(pdev, 0);
	if (irq < 0)
		return irq;

	writeb(LOONGSON2_THSENS_INT_LO | LOONGSON2_THSENS_INT_HIGH, data->regs +
		LOONGSON2_THSENS_STATUS_REG);

	loongson2_thermal_set(data, 0, 0, false);

	for (i = 0; i <= LOONGSON2_MAX_SENSOR_SEL_NUM; i++) {
		tzd = devm_thermal_of_zone_register(dev, i, data,
			&loongson2_of_thermal_ops);

		if (!IS_ERR(tzd))
			break;

		if (PTR_ERR(tzd) != ENODEV)
			continue;

		return dev_err_probe(dev, PTR_ERR(tzd), "failed to register");
	}

	ret = devm_request_threaded_irq(dev, irq, NULL, loongson2_thermal_irq_thread,
			IRQF_ONESHOT, "loongson2_thermal", tzd);
	if (ret < 0)
		return dev_err_probe(dev, ret, "failed to request alarm irq\n");

	devm_thermal_add_hwmon_sysfs(dev, tzd);

	return 0;
}

static const struct loongson2_thermal_chip_data loongson2_thermal_ls2k1000_data = {
	.thermal_sensor_sel = 0,
};

static const struct of_device_id of_loongson2_thermal_match[] = {
	{
		.compatible = "loongson,ls2k1000-thermal",
		.data = &loongson2_thermal_ls2k1000_data,
	},
	{ /* end */ }
};
MODULE_DEVICE_TABLE(of, of_loongson2_thermal_match);

static struct platform_driver loongson2_thermal_driver = {
	.driver = {
		.name		= "loongson2_thermal",
		.of_match_table = of_loongson2_thermal_match,
	},
	.probe	= loongson2_thermal_probe,
};
module_platform_driver(loongson2_thermal_driver);

MODULE_DESCRIPTION("Loongson2 thermal driver");
MODULE_LICENSE("GPL");
