// 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);

	ret = tz->ops.get_crit_temp(tz, &temperature);

	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);
