// SPDX-License-Identifier: GPL-2.0
/*
 *  thermal_hwmon.c - Generic Thermal Management hwmon support.
 *
 *  Code based on Intel thermal_core.c. Copyrights of the original code:
 *  Copyright (C) 2008 Intel Corp
 *  Copyright (C) 2008 Zhang Rui <rui.zhang@intel.com>
 *  Copyright (C) 2008 Sujith Thomas <sujith.thomas@intel.com>
 *
 *  Copyright (C) 2013 Texas Instruments
 *  Copyright (C) 2013 Eduardo Valentin <eduardo.valentin@ti.com>
 */
#include <linux/err.h>
#include <linux/export.h>
#include <linux/hwmon.h>
#include <linux/slab.h>
#include <linux/thermal.h>

#include "thermal_hwmon.h"
#include "thermal_core.h"

/* hwmon sys I/F */
/* thermal zone devices with the same type share one hwmon device */
struct thermal_hwmon_device {
	char type[THERMAL_NAME_LENGTH];
	struct device *device;
	int count;
	struct list_head tz_list;
	struct list_head node;
};

struct thermal_hwmon_attr {
	struct device_attribute attr;
	char name[16];
};

/* one temperature input for each thermal zone */
struct thermal_hwmon_temp {
	struct list_head hwmon_node;
	struct thermal_zone_device *tz;
	struct thermal_hwmon_attr temp_input;	/* hwmon sys attr */
	struct thermal_hwmon_attr temp_crit;	/* hwmon sys attr */
};

static LIST_HEAD(thermal_hwmon_list);

static DEFINE_MUTEX(thermal_hwmon_list_lock);

static ssize_t
temp_input_show(struct device *dev, struct device_attribute *attr, char *buf)
{
	int temperature;
	int ret;
	struct thermal_hwmon_attr *hwmon_attr
			= container_of(attr, struct thermal_hwmon_attr, attr);
	struct thermal_hwmon_temp *temp
			= container_of(hwmon_attr, struct thermal_hwmon_temp,
				       temp_input);
	struct thermal_zone_device *tz = temp->tz;

	ret = thermal_zone_get_temp(tz, &temperature);

	if (ret)
		return ret;

	return sprintf(buf, "%d\n", temperature);
}

static ssize_t
temp_crit_show(struct device *dev, struct device_attribute *attr, char *buf)
{
	struct thermal_hwmon_attr *hwmon_attr
			= container_of(attr, struct thermal_hwmon_attr, attr);
	struct thermal_hwmon_temp *temp
			= container_of(hwmon_attr, struct thermal_hwmon_temp,
				       temp_crit);
	struct thermal_zone_device *tz = temp->tz;
	int temperature;
	int ret;

	mutex_lock(&tz->lock);

	if (device_is_registered(&tz->device))
		ret = tz->ops->get_crit_temp(tz, &temperature);
	else
		ret = -ENODEV;

	mutex_unlock(&tz->lock);

	if (ret)
		return ret;

	return sprintf(buf, "%d\n", temperature);
}


static struct thermal_hwmon_device *
thermal_hwmon_lookup_by_type(const struct thermal_zone_device *tz)
{
	struct thermal_hwmon_device *hwmon;
	char type[THERMAL_NAME_LENGTH];

	mutex_lock(&thermal_hwmon_list_lock);
	list_for_each_entry(hwmon, &thermal_hwmon_list, node) {
		strcpy(type, tz->type);
		strreplace(type, '-', '_');
		if (!strcmp(hwmon->type, type)) {
			mutex_unlock(&thermal_hwmon_list_lock);
			return hwmon;
		}
	}
	mutex_unlock(&thermal_hwmon_list_lock);

	return NULL;
}

/* Find the temperature input matching a given thermal zone */
static struct thermal_hwmon_temp *
thermal_hwmon_lookup_temp(const struct thermal_hwmon_device *hwmon,
			  const struct thermal_zone_device *tz)
{
	struct thermal_hwmon_temp *temp;

	mutex_lock(&thermal_hwmon_list_lock);
	list_for_each_entry(temp, &hwmon->tz_list, hwmon_node)
		if (temp->tz == tz) {
			mutex_unlock(&thermal_hwmon_list_lock);
			return temp;
		}
	mutex_unlock(&thermal_hwmon_list_lock);

	return NULL;
}

static bool thermal_zone_crit_temp_valid(struct thermal_zone_device *tz)
{
	int temp;
	return tz->ops->get_crit_temp && !tz->ops->get_crit_temp(tz, &temp);
}

int thermal_add_hwmon_sysfs(struct thermal_zone_device *tz)
{
	struct thermal_hwmon_device *hwmon;
	struct thermal_hwmon_temp *temp;
	int new_hwmon_device = 1;
	int result;

	hwmon = thermal_hwmon_lookup_by_type(tz);
	if (hwmon) {
		new_hwmon_device = 0;
		goto register_sys_interface;
	}

	hwmon = kzalloc(sizeof(*hwmon), GFP_KERNEL);
	if (!hwmon)
		return -ENOMEM;

	INIT_LIST_HEAD(&hwmon->tz_list);
	strscpy(hwmon->type, tz->type, THERMAL_NAME_LENGTH);
	strreplace(hwmon->type, '-', '_');
	hwmon->device = hwmon_device_register_for_thermal(&tz->device,
							  hwmon->type, hwmon);
	if (IS_ERR(hwmon->device)) {
		result = PTR_ERR(hwmon->device);
		goto free_mem;
	}

 register_sys_interface:
	temp = kzalloc(sizeof(*temp), GFP_KERNEL);
	if (!temp) {
		result = -ENOMEM;
		goto unregister_name;
	}

	temp->tz = tz;
	hwmon->count++;

	snprintf(temp->temp_input.name, sizeof(temp->temp_input.name),
		 "temp%d_input", hwmon->count);
	temp->temp_input.attr.attr.name = temp->temp_input.name;
	temp->temp_input.attr.attr.mode = 0444;
	temp->temp_input.attr.show = temp_input_show;
	sysfs_attr_init(&temp->temp_input.attr.attr);
	result = device_create_file(hwmon->device, &temp->temp_input.attr);
	if (result)
		goto free_temp_mem;

	if (thermal_zone_crit_temp_valid(tz)) {
		snprintf(temp->temp_crit.name,
				sizeof(temp->temp_crit.name),
				"temp%d_crit", hwmon->count);
		temp->temp_crit.attr.attr.name = temp->temp_crit.name;
		temp->temp_crit.attr.attr.mode = 0444;
		temp->temp_crit.attr.show = temp_crit_show;
		sysfs_attr_init(&temp->temp_crit.attr.attr);
		result = device_create_file(hwmon->device,
					    &temp->temp_crit.attr);
		if (result)
			goto unregister_input;
	}

	mutex_lock(&thermal_hwmon_list_lock);
	if (new_hwmon_device)
		list_add_tail(&hwmon->node, &thermal_hwmon_list);
	list_add_tail(&temp->hwmon_node, &hwmon->tz_list);
	mutex_unlock(&thermal_hwmon_list_lock);

	return 0;

 unregister_input:
	device_remove_file(hwmon->device, &temp->temp_input.attr);
 free_temp_mem:
	kfree(temp);
 unregister_name:
	if (new_hwmon_device)
		hwmon_device_unregister(hwmon->device);
 free_mem:
	kfree(hwmon);

	return result;
}
EXPORT_SYMBOL_GPL(thermal_add_hwmon_sysfs);

void thermal_remove_hwmon_sysfs(struct thermal_zone_device *tz)
{
	struct thermal_hwmon_device *hwmon;
	struct thermal_hwmon_temp *temp;

	hwmon = thermal_hwmon_lookup_by_type(tz);
	if (unlikely(!hwmon)) {
		/* Should never happen... */
		dev_dbg(&tz->device, "hwmon device lookup failed!\n");
		return;
	}

	temp = thermal_hwmon_lookup_temp(hwmon, tz);
	if (unlikely(!temp)) {
		/* Should never happen... */
		dev_dbg(&tz->device, "temperature input lookup failed!\n");
		return;
	}

	device_remove_file(hwmon->device, &temp->temp_input.attr);
	if (thermal_zone_crit_temp_valid(tz))
		device_remove_file(hwmon->device, &temp->temp_crit.attr);

	mutex_lock(&thermal_hwmon_list_lock);
	list_del(&temp->hwmon_node);
	kfree(temp);
	if (!list_empty(&hwmon->tz_list)) {
		mutex_unlock(&thermal_hwmon_list_lock);
		return;
	}
	list_del(&hwmon->node);
	mutex_unlock(&thermal_hwmon_list_lock);

	hwmon_device_unregister(hwmon->device);
	kfree(hwmon);
}
EXPORT_SYMBOL_GPL(thermal_remove_hwmon_sysfs);

static void devm_thermal_hwmon_release(struct device *dev, void *res)
{
	thermal_remove_hwmon_sysfs(*(struct thermal_zone_device **)res);
}

int devm_thermal_add_hwmon_sysfs(struct device *dev, struct thermal_zone_device *tz)
{
	struct thermal_zone_device **ptr;
	int ret;

	ptr = devres_alloc(devm_thermal_hwmon_release, sizeof(*ptr),
			   GFP_KERNEL);
	if (!ptr) {
		dev_warn(dev, "Failed to allocate device resource data\n");
		return -ENOMEM;
	}

	ret = thermal_add_hwmon_sysfs(tz);
	if (ret) {
		dev_warn(dev, "Failed to add hwmon sysfs attributes\n");
		devres_free(ptr);
		return ret;
	}

	*ptr = tz;
	devres_add(dev, ptr);

	return ret;
}
EXPORT_SYMBOL_GPL(devm_thermal_add_hwmon_sysfs);

MODULE_IMPORT_NS(HWMON_THERMAL);
