// 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 resource *resource;
	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;

	resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	sensor->mmio_base = devm_ioremap_resource(&pdev->dev, resource);
	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");
