// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright 2024 Linaro Limited
 *
 * Author: Daniel Lezcano <daniel.lezcano@linaro.org>
 *
 * Thermal thresholds
 */
#include <linux/list.h>
#include <linux/list_sort.h>
#include <linux/slab.h>

#include "thermal_core.h"
#include "thermal_thresholds.h"

int thermal_thresholds_init(struct thermal_zone_device *tz)
{
	INIT_LIST_HEAD(&tz->user_thresholds);

	return 0;
}

static void __thermal_thresholds_flush(struct thermal_zone_device *tz)
{
	struct list_head *thresholds = &tz->user_thresholds;
	struct user_threshold *entry, *tmp;

	list_for_each_entry_safe(entry, tmp, thresholds, list_node) {
		list_del(&entry->list_node);
		kfree(entry);
	}
}

void thermal_thresholds_flush(struct thermal_zone_device *tz)
{
	lockdep_assert_held(&tz->lock);

	__thermal_thresholds_flush(tz);

	thermal_notify_threshold_flush(tz);

	__thermal_zone_device_update(tz, THERMAL_TZ_FLUSH_THRESHOLDS);
}

void thermal_thresholds_exit(struct thermal_zone_device *tz)
{
	__thermal_thresholds_flush(tz);
}

static int __thermal_thresholds_cmp(void *data,
				    const struct list_head *l1,
				    const struct list_head *l2)
{
	struct user_threshold *t1 = container_of(l1, struct user_threshold, list_node);
	struct user_threshold *t2 = container_of(l2, struct user_threshold, list_node);

	return t1->temperature - t2->temperature;
}

static struct user_threshold *__thermal_thresholds_find(const struct list_head *thresholds,
							int temperature)
{
	struct user_threshold *t;

	list_for_each_entry(t, thresholds, list_node)
		if (t->temperature == temperature)
			return t;

	return NULL;
}

static bool thermal_thresholds_handle_raising(struct list_head *thresholds, int temperature,
					      int last_temperature)
{
	struct user_threshold *t;

	list_for_each_entry(t, thresholds, list_node) {

		if (!(t->direction & THERMAL_THRESHOLD_WAY_UP))
		    continue;

		if (temperature >= t->temperature &&
		    last_temperature < t->temperature)
			return true;
	}

	return false;
}

static bool thermal_thresholds_handle_dropping(struct list_head *thresholds, int temperature,
					       int last_temperature)
{
	struct user_threshold *t;

	list_for_each_entry_reverse(t, thresholds, list_node) {

		if (!(t->direction & THERMAL_THRESHOLD_WAY_DOWN))
		    continue;

		if (temperature <= t->temperature &&
		    last_temperature > t->temperature)
			return true;
	}

	return false;
}

static void thermal_threshold_find_boundaries(struct list_head *thresholds, int temperature,
					      int *low, int *high)
{
	struct user_threshold *t;

	list_for_each_entry(t, thresholds, list_node) {
		if (temperature < t->temperature &&
		    (t->direction & THERMAL_THRESHOLD_WAY_UP) &&
		    *high > t->temperature)
			*high = t->temperature;
	}

	list_for_each_entry_reverse(t, thresholds, list_node) {
		if (temperature > t->temperature &&
		    (t->direction & THERMAL_THRESHOLD_WAY_DOWN) &&
		    *low < t->temperature)
			*low = t->temperature;
	}
}

void thermal_thresholds_handle(struct thermal_zone_device *tz, int *low, int *high)
{
	struct list_head *thresholds = &tz->user_thresholds;

	int temperature = tz->temperature;
	int last_temperature = tz->last_temperature;

	lockdep_assert_held(&tz->lock);

	thermal_threshold_find_boundaries(thresholds, temperature, low, high);

	/*
	 * We need a second update in order to detect a threshold being crossed
	 */
	if (last_temperature == THERMAL_TEMP_INVALID)
		return;

	/*
	 * The temperature is stable, so obviously we can not have
	 * crossed a threshold.
	 */
	if (last_temperature == temperature)
		return;

	/*
	 * Since last update the temperature:
	 * - increased : thresholds are crossed the way up
	 * - decreased : thresholds are crossed the way down
	 */
	if (temperature > last_temperature) {
		if (thermal_thresholds_handle_raising(thresholds,
						      temperature, last_temperature))
			thermal_notify_threshold_up(tz);
	} else {
		if (thermal_thresholds_handle_dropping(thresholds,
						       temperature, last_temperature))
			thermal_notify_threshold_down(tz);
	}
}

int thermal_thresholds_add(struct thermal_zone_device *tz,
			   int temperature, int direction)
{
	struct list_head *thresholds = &tz->user_thresholds;
	struct user_threshold *t;

	lockdep_assert_held(&tz->lock);

	t = __thermal_thresholds_find(thresholds, temperature);
	if (t) {
		if (t->direction == direction)
			return -EEXIST;

		t->direction |= direction;
	} else {

		t = kmalloc_obj(*t);
		if (!t)
			return -ENOMEM;

		INIT_LIST_HEAD(&t->list_node);
		t->temperature = temperature;
		t->direction = direction;
		list_add(&t->list_node, thresholds);
		list_sort(NULL, thresholds, __thermal_thresholds_cmp);
	}

	thermal_notify_threshold_add(tz, temperature, direction);

	__thermal_zone_device_update(tz, THERMAL_TZ_ADD_THRESHOLD);

	return 0;
}

int thermal_thresholds_delete(struct thermal_zone_device *tz,
			      int temperature, int direction)
{
	struct list_head *thresholds = &tz->user_thresholds;
	struct user_threshold *t;

	lockdep_assert_held(&tz->lock);

	t = __thermal_thresholds_find(thresholds, temperature);
	if (!t)
		return -ENOENT;

	if (t->direction == direction) {
		list_del(&t->list_node);
		kfree(t);
	} else {
		t->direction &= ~direction;
	}

	thermal_notify_threshold_delete(tz, temperature, direction);

	__thermal_zone_device_update(tz, THERMAL_TZ_DEL_THRESHOLD);

	return 0;
}

int thermal_thresholds_for_each(struct thermal_zone_device *tz,
				int (*cb)(struct user_threshold *, void *arg), void *arg)
{
	struct list_head *thresholds = &tz->user_thresholds;
	struct user_threshold *entry;
	int ret;

	guard(thermal_zone)(tz);

	list_for_each_entry(entry, thresholds, list_node) {
		ret = cb(entry, arg);
		if (ret)
			return ret;
	}

	return 0;
}
