// 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 <linux/workqueue.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)
{
	struct tt_thermal_zone *tt_zone __free(kfree);
	struct tt_work *tt_work __free(kfree);
	int ret;

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

	tt_work = kzalloc(sizeof(*tt_work), GFP_KERNEL);
	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);
	schedule_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_work *tt_work __free(kfree);
	struct tt_thermal_zone *tt_zone, *aux;
	int ret;
	int id;

	ret = sscanf(arg, "%d", &id);
	if (ret != 1)
		return -EINVAL;

	tt_work = kzalloc(sizeof(*tt_work), GFP_KERNEL);
	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;
	schedule_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 = sscanf(arg, "%d", &id);
	if (ret != 1)
		return ERR_PTR(-EINVAL);

	guard(mutex)(&tt_thermal_zones_lock);

	ret = -EINVAL;
	list_for_each_entry(tt_zone, &tt_thermal_zones, list_node) {
		if (tt_zone->id == id) {
			tt_zone->refcount++;
			ret = 0;
			break;
		}
	}

	if (ret)
		return ERR_PTR(ret);

	return tt_zone;
}

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

	tt_zone->refcount--;
}

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)
{
	struct tt_work *tt_work __free(kfree);
	struct tt_trip *tt_trip __free(kfree);
	struct tt_thermal_zone *tt_zone;
	int id;

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

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

	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) {
		tt_put_tt_zone(tt_zone);
		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 = tt_zone;
	tt_work->tt_trip = no_free_ptr(tt_trip);
	schedule_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 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_trip *trips __free(kfree);
	struct thermal_zone_device *tz;
	struct tt_trip *tt_trip;
	int i;

	guard(tt_zone)(tt_zone);

	if (tt_zone->tz)
		return -EINVAL;

	trips = kcalloc(tt_zone->num_trips, sizeof(*trips), GFP_KERNEL);
	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;
	int ret;

	tt_zone = tt_get_tt_zone(arg);
	if (IS_ERR(tt_zone))
		return PTR_ERR(tt_zone);

	ret = tt_zone_register_tz(tt_zone);

	tt_put_tt_zone(tt_zone);

	return ret;
}

int tt_zone_unreg(const char *arg)
{
	struct tt_thermal_zone *tt_zone;

	tt_zone = tt_get_tt_zone(arg);
	if (IS_ERR(tt_zone))
		return PTR_ERR(tt_zone);

	tt_zone_unregister_tz(tt_zone);

	tt_put_tt_zone(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);
	}
}
