// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 */

#include <linux/module.h>
#include <linux/of_address.h>
#include <linux/platform_device.h>
#include <linux/thermal.h>

struct thermal_mmio {
	void __iomem *mmio_base;
	u32 (*read_mmio)(void __iomem *mmio_base);
	u32 mask;
	int factor;
};

static u32 thermal_mmio_readb(void __iomem *mmio_base)
{
	return readb(mmio_base);
}

static int thermal_mmio_get_temperature(struct thermal_zone_device *tz, int *temp)
{
	int t;
	struct thermal_mmio *sensor = tz->devdata;

	t = sensor->read_mmio(sensor->mmio_base) & sensor->mask;
	t *= sensor->factor;

	*temp = t;

	return 0;
}

static const struct thermal_zone_device_ops thermal_mmio_ops = {
	.get_temp = thermal_mmio_get_temperature,
};

static int thermal_mmio_probe(struct platform_device *pdev)
{
	struct thermal_mmio *sensor;
	int (*sensor_init_func)(struct platform_device *pdev,
				struct thermal_mmio *sensor);
	struct thermal_zone_device *thermal_zone;
	int ret;
	int temperature;

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

	sensor->mmio_base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
	if (IS_ERR(sensor->mmio_base))
		return PTR_ERR(sensor->mmio_base);

	sensor_init_func = device_get_match_data(&pdev->dev);
	if (sensor_init_func) {
		ret = sensor_init_func(pdev, sensor);
		if (ret) {
			dev_err(&pdev->dev,
				"failed to initialize sensor (%d)\n",
				ret);
			return ret;
		}
	}

	thermal_zone = devm_thermal_of_zone_register(&pdev->dev,
						     0,
						     sensor,
						     &thermal_mmio_ops);
	if (IS_ERR(thermal_zone)) {
		dev_err(&pdev->dev,
			"failed to register sensor (%ld)\n",
			PTR_ERR(thermal_zone));
		return PTR_ERR(thermal_zone);
	}

	thermal_mmio_get_temperature(thermal_zone, &temperature);
	dev_info(&pdev->dev,
		 "thermal mmio sensor %s registered, current temperature: %d\n",
		 pdev->name, temperature);

	return 0;
}

static int al_thermal_init(struct platform_device *pdev,
			   struct thermal_mmio *sensor)
{
	sensor->read_mmio = thermal_mmio_readb;
	sensor->mask = 0xff;
	sensor->factor = 1000;

	return 0;
}

static const struct of_device_id thermal_mmio_id_table[] = {
	{ .compatible = "amazon,al-thermal", .data = al_thermal_init},
	{}
};
MODULE_DEVICE_TABLE(of, thermal_mmio_id_table);

static struct platform_driver thermal_mmio_driver = {
	.probe = thermal_mmio_probe,
	.driver = {
		.name = "thermal-mmio",
		.of_match_table = thermal_mmio_id_table,
	},
};

module_platform_driver(thermal_mmio_driver);

MODULE_AUTHOR("Talel Shenhar <talel@amazon.com>");
MODULE_DESCRIPTION("Thermal MMIO Driver");
MODULE_LICENSE("GPL v2");
