// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright 2024, Intel Corporation
 *
 * Author: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
 *
 * Thermal zone tempalates handling for thermal core testing.
 */

#define pr_fmt(fmt) "thermal-testing: " fmt

#include <linux/debugfs.h>
#include <linux/idr.h>
#include <linux/list.h>
#include <linux/thermal.h>

#include "thermal_testing.h"

#define TT_MAX_FILE_NAME_LENGTH		16

/**
 * struct tt_thermal_zone - Testing thermal zone template
 *
 * Represents a template of a thermal zone that can be used for registering
 * a test thermal zone with the thermal core.
 *
 * @list_node: Node in the list of all testing thermal zone templates.
 * @trips: List of trip point templates for this thermal zone template.
 * @d_tt_zone: Directory in debugfs representing this template.
 * @tz: Test thermal zone based on this template, if present.
 * @lock: Mutex for synchronizing changes of this template.
 * @ida: IDA for trip point IDs.
 * @id: The ID of this template for the debugfs interface.
 * @temp: Temperature value.
 * @tz_temp: Current thermal zone temperature (after registration).
 * @num_trips: Number of trip points in the @trips list.
 * @refcount: Reference counter for usage and removal synchronization.
 */
struct tt_thermal_zone {
	struct list_head list_node;
	struct list_head trips;
	struct dentry *d_tt_zone;
	struct thermal_zone_device *tz;
	struct mutex lock;
	struct ida ida;
	int id;
	int temp;
	int tz_temp;
	unsigned int num_trips;
	unsigned int refcount;
};

DEFINE_GUARD(tt_zone, struct tt_thermal_zone *, mutex_lock(&_T->lock), mutex_unlock(&_T->lock))

/**
 * struct tt_trip - Testing trip point template
 *
 * Represents a template of a trip point to be used for populating a trip point
 * during the registration of a thermal zone based on a given zone template.
 *
 * @list_node: Node in the list of all trip templates in the zone template.
 * @trip: Trip point data to use for thernal zone registration.
 * @id: The ID of this trip template for the debugfs interface.
 */
struct tt_trip {
	struct list_head list_node;
	struct thermal_trip trip;
	int id;
};

/*
 * It is both questionable and potentially problematic from the sychnronization
 * perspective to attempt to manipulate debugfs from within a debugfs file
 * "write" operation, so auxiliary work items are used for that.  The majority
 * of zone-related command functions have a part that runs from a workqueue and
 * make changes in debugs, among other things.
 */
struct tt_work {
	struct work_struct work;
	struct tt_thermal_zone *tt_zone;
	struct tt_trip *tt_trip;
};

static inline struct tt_work *tt_work_of_work(struct work_struct *work)
{
	return container_of(work, struct tt_work, work);
}

static LIST_HEAD(tt_thermal_zones);
static DEFINE_IDA(tt_thermal_zones_ida);
static DEFINE_MUTEX(tt_thermal_zones_lock);

static int tt_int_get(void *data, u64 *val)
{
	*val = *(int *)data;
	return 0;
}
static int tt_int_set(void *data, u64 val)
{
	if ((int)val < THERMAL_TEMP_INVALID)
		return -EINVAL;

	*(int *)data = val;
	return 0;
}
DEFINE_DEBUGFS_ATTRIBUTE_SIGNED(tt_int_attr, tt_int_get, tt_int_set, "%lld\n");
DEFINE_DEBUGFS_ATTRIBUTE(tt_unsigned_int_attr, tt_int_get, tt_int_set, "%llu\n");

static int tt_zone_tz_temp_get(void *data, u64 *val)
{
	struct tt_thermal_zone *tt_zone = data;

	guard(tt_zone)(tt_zone);

	if (!tt_zone->tz)
		return -EBUSY;

	*val = tt_zone->tz_temp;

	return 0;
}
static int tt_zone_tz_temp_set(void *data, u64 val)
{
	struct tt_thermal_zone *tt_zone = data;

	guard(tt_zone)(tt_zone);

	if (!tt_zone->tz)
		return -EBUSY;

	WRITE_ONCE(tt_zone->tz_temp, val);
	thermal_zone_device_update(tt_zone->tz, THERMAL_EVENT_TEMP_SAMPLE);

	return 0;
}
DEFINE_DEBUGFS_ATTRIBUTE_SIGNED(tt_zone_tz_temp_attr, tt_zone_tz_temp_get,
				tt_zone_tz_temp_set, "%lld\n");

static void tt_zone_free_trips(struct tt_thermal_zone *tt_zone)
{
	struct tt_trip *tt_trip, *aux;

	list_for_each_entry_safe(tt_trip, aux, &tt_zone->trips, list_node) {
		list_del(&tt_trip->list_node);
		ida_free(&tt_zone->ida, tt_trip->id);
		kfree(tt_trip);
	}
}

static void tt_zone_free(struct tt_thermal_zone *tt_zone)
{
	tt_zone_free_trips(tt_zone);
	ida_free(&tt_thermal_zones_ida, tt_zone->id);
	ida_destroy(&tt_zone->ida);
	kfree(tt_zone);
}

static void tt_add_tz_work_fn(struct work_struct *work)
{
	struct tt_work *tt_work = tt_work_of_work(work);
	struct tt_thermal_zone *tt_zone = tt_work->tt_zone;
	char f_name[TT_MAX_FILE_NAME_LENGTH];

	kfree(tt_work);

	snprintf(f_name, TT_MAX_FILE_NAME_LENGTH, "tz%d", tt_zone->id);
	tt_zone->d_tt_zone = debugfs_create_dir(f_name, d_testing);
	if (IS_ERR(tt_zone->d_tt_zone)) {
		tt_zone_free(tt_zone);
		return;
	}

	debugfs_create_file_unsafe("temp", 0600, tt_zone->d_tt_zone, tt_zone,
				   &tt_zone_tz_temp_attr);

	debugfs_create_file_unsafe("init_temp", 0600, tt_zone->d_tt_zone,
				   &tt_zone->temp, &tt_int_attr);

	guard(mutex)(&tt_thermal_zones_lock);

	list_add_tail(&tt_zone->list_node, &tt_thermal_zones);
}

int tt_add_tz(void)
{
	int ret;

	struct tt_thermal_zone *tt_zone __free(kfree) = kzalloc_obj(*tt_zone);
	if (!tt_zone)
		return -ENOMEM;

	struct tt_work *tt_work __free(kfree) = kzalloc_obj(*tt_work);
	if (!tt_work)
		return -ENOMEM;

	INIT_LIST_HEAD(&tt_zone->trips);
	mutex_init(&tt_zone->lock);
	ida_init(&tt_zone->ida);
	tt_zone->temp = THERMAL_TEMP_INVALID;

	ret = ida_alloc(&tt_thermal_zones_ida, GFP_KERNEL);
	if (ret < 0)
		return ret;

	tt_zone->id = ret;

	INIT_WORK(&tt_work->work, tt_add_tz_work_fn);
	tt_work->tt_zone = no_free_ptr(tt_zone);
	tt_queue_work(&(no_free_ptr(tt_work)->work));

	return 0;
}

static void tt_del_tz_work_fn(struct work_struct *work)
{
	struct tt_work *tt_work = tt_work_of_work(work);
	struct tt_thermal_zone *tt_zone = tt_work->tt_zone;

	kfree(tt_work);

	debugfs_remove(tt_zone->d_tt_zone);
	tt_zone_free(tt_zone);
}

static void tt_zone_unregister_tz(struct tt_thermal_zone *tt_zone)
{
	guard(tt_zone)(tt_zone);

	if (tt_zone->tz) {
		thermal_zone_device_unregister(tt_zone->tz);
		tt_zone->tz = NULL;
	}
}

int tt_del_tz(const char *arg)
{
	struct tt_thermal_zone *tt_zone, *aux;
	int ret;
	int id;

	ret = kstrtoint(arg, 10, &id);
	if (ret < 0)
		return ret;

	struct tt_work *tt_work __free(kfree) = kzalloc_obj(*tt_work);
	if (!tt_work)
		return -ENOMEM;

	guard(mutex)(&tt_thermal_zones_lock);

	ret = -EINVAL;
	list_for_each_entry_safe(tt_zone, aux, &tt_thermal_zones, list_node) {
		if (tt_zone->id == id) {
			if (tt_zone->refcount) {
				ret = -EBUSY;
			} else {
				list_del(&tt_zone->list_node);
				ret = 0;
			}
			break;
		}
	}

	if (ret)
		return ret;

	tt_zone_unregister_tz(tt_zone);

	INIT_WORK(&tt_work->work, tt_del_tz_work_fn);
	tt_work->tt_zone = tt_zone;
	tt_queue_work(&(no_free_ptr(tt_work)->work));

	return 0;
}

static struct tt_thermal_zone *tt_get_tt_zone(const char *arg)
{
	struct tt_thermal_zone *tt_zone;
	int ret, id;

	ret = kstrtoint(arg, 10, &id);
	if (ret < 0)
		return ERR_PTR(ret);

	guard(mutex)(&tt_thermal_zones_lock);

	list_for_each_entry(tt_zone, &tt_thermal_zones, list_node) {
		if (tt_zone->id == id) {
			tt_zone->refcount++;
			return tt_zone;
		}
	}

	return ERR_PTR(-EINVAL);
}

static void tt_put_tt_zone(struct tt_thermal_zone *tt_zone)
{
	guard(mutex)(&tt_thermal_zones_lock);

	tt_zone->refcount--;
}

DEFINE_FREE(put_tt_zone, struct tt_thermal_zone *,
	    if (!IS_ERR_OR_NULL(_T)) tt_put_tt_zone(_T))

static void tt_zone_add_trip_work_fn(struct work_struct *work)
{
	struct tt_work *tt_work = tt_work_of_work(work);
	struct tt_thermal_zone *tt_zone = tt_work->tt_zone;
	struct tt_trip *tt_trip = tt_work->tt_trip;
	char d_name[TT_MAX_FILE_NAME_LENGTH];

	kfree(tt_work);

	snprintf(d_name, TT_MAX_FILE_NAME_LENGTH, "trip_%d_temp", tt_trip->id);
	debugfs_create_file_unsafe(d_name, 0600, tt_zone->d_tt_zone,
				   &tt_trip->trip.temperature, &tt_int_attr);

	snprintf(d_name, TT_MAX_FILE_NAME_LENGTH, "trip_%d_hyst", tt_trip->id);
	debugfs_create_file_unsafe(d_name, 0600, tt_zone->d_tt_zone,
				   &tt_trip->trip.hysteresis, &tt_unsigned_int_attr);

	tt_put_tt_zone(tt_zone);
}

int tt_zone_add_trip(const char *arg)
{
	int id;

	struct tt_work *tt_work __free(kfree) = kzalloc_obj(*tt_work);
	if (!tt_work)
		return -ENOMEM;

	struct tt_trip *tt_trip __free(kfree) = kzalloc_obj(*tt_trip);
	if (!tt_trip)
		return -ENOMEM;

	struct tt_thermal_zone *tt_zone __free(put_tt_zone) = tt_get_tt_zone(arg);
	if (IS_ERR(tt_zone))
		return PTR_ERR(tt_zone);

	id = ida_alloc(&tt_zone->ida, GFP_KERNEL);
	if (id < 0)
		return id;

	tt_trip->trip.type = THERMAL_TRIP_ACTIVE;
	tt_trip->trip.temperature = THERMAL_TEMP_INVALID;
	tt_trip->trip.flags = THERMAL_TRIP_FLAG_RW;
	tt_trip->id = id;

	guard(tt_zone)(tt_zone);

	list_add_tail(&tt_trip->list_node, &tt_zone->trips);
	tt_zone->num_trips++;

	INIT_WORK(&tt_work->work, tt_zone_add_trip_work_fn);
	tt_work->tt_zone = no_free_ptr(tt_zone);
	tt_work->tt_trip = no_free_ptr(tt_trip);
	tt_queue_work(&(no_free_ptr(tt_work)->work));

	return 0;
}

static int tt_zone_get_temp(struct thermal_zone_device *tz, int *temp)
{
	struct tt_thermal_zone *tt_zone = thermal_zone_device_priv(tz);

	*temp = READ_ONCE(tt_zone->tz_temp);

	if (*temp < THERMAL_TEMP_INVALID)
		return -ENODATA;

	return 0;
}

static const struct thermal_zone_device_ops tt_zone_ops = {
	.get_temp = tt_zone_get_temp,
};

static int tt_zone_register_tz(struct tt_thermal_zone *tt_zone)
{
	struct thermal_zone_device *tz;
	struct tt_trip *tt_trip;
	int i;

	guard(tt_zone)(tt_zone);

	if (tt_zone->tz)
		return -EINVAL;

	struct thermal_trip *trips __free(kfree) = kzalloc_objs(*trips,
								tt_zone->num_trips);
	if (!trips)
		return -ENOMEM;

	i = 0;
	list_for_each_entry(tt_trip, &tt_zone->trips, list_node)
		trips[i++] = tt_trip->trip;

	tt_zone->tz_temp = tt_zone->temp;

	tz = thermal_zone_device_register_with_trips("test_tz", trips, i, tt_zone,
						     &tt_zone_ops, NULL, 0, 0);
	if (IS_ERR(tz))
		return PTR_ERR(tz);

	tt_zone->tz = tz;

	thermal_zone_device_enable(tz);

	return 0;
}

int tt_zone_reg(const char *arg)
{
	struct tt_thermal_zone *tt_zone __free(put_tt_zone) = tt_get_tt_zone(arg);
	if (IS_ERR(tt_zone))
		return PTR_ERR(tt_zone);

	return tt_zone_register_tz(tt_zone);
}

int tt_zone_unreg(const char *arg)
{
	struct tt_thermal_zone *tt_zone __free(put_tt_zone) = tt_get_tt_zone(arg);
	if (IS_ERR(tt_zone))
		return PTR_ERR(tt_zone);

	tt_zone_unregister_tz(tt_zone);

	return 0;
}

void tt_zone_cleanup(void)
{
	struct tt_thermal_zone *tt_zone, *aux;

	list_for_each_entry_safe(tt_zone, aux, &tt_thermal_zones, list_node) {
		tt_zone_unregister_tz(tt_zone);

		list_del(&tt_zone->list_node);

		tt_zone_free(tt_zone);
	}
}
