// SPDX-License-Identifier: GPL-2.0-only
/*
 *  step_wise.c - A step-by-step Thermal throttling governor
 *
 *  Copyright (C) 2012 Intel Corp
 *  Copyright (C) 2012 Durgadoss R <durgadoss.r@intel.com>
 *
 *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 */

#include <linux/thermal.h>
#include <linux/minmax.h>
#include "thermal_trace.h"

#include "thermal_core.h"

/*
 * If the temperature is higher than a trip point,
 *    a. if the trend is THERMAL_TREND_RAISING, use higher cooling
 *       state for this trip point
 *    b. if the trend is THERMAL_TREND_DROPPING, do nothing
 * If the temperature is lower than a trip point,
 *    a. if the trend is THERMAL_TREND_RAISING, do nothing
 *    b. if the trend is THERMAL_TREND_DROPPING, use lower cooling
 *       state for this trip point, if the cooling state already
 *       equals lower limit, deactivate the thermal instance
 */
static unsigned long get_target_state(struct thermal_instance *instance,
				enum thermal_trend trend, bool throttle)
{
	struct thermal_cooling_device *cdev = instance->cdev;
	unsigned long cur_state;
	unsigned long next_target;

	/*
	 * We keep this instance the way it is by default.
	 * Otherwise, we use the current state of the
	 * cdev in use to determine the next_target.
	 */
	cdev->ops->get_cur_state(cdev, &cur_state);
	next_target = instance->target;
	dev_dbg(&cdev->device, "cur_state=%ld\n", cur_state);

	if (!instance->initialized) {
		if (throttle) {
			next_target = clamp((cur_state + 1), instance->lower, instance->upper);
		} else {
			next_target = THERMAL_NO_TARGET;
		}

		return next_target;
	}

	if (throttle) {
		if (trend == THERMAL_TREND_RAISING)
			next_target = clamp((cur_state + 1), instance->lower, instance->upper);
	} else {
		if (trend == THERMAL_TREND_DROPPING) {
			if (cur_state <= instance->lower)
				next_target = THERMAL_NO_TARGET;
			else
				next_target = clamp((cur_state - 1), instance->lower, instance->upper);
		}
	}

	return next_target;
}

static void thermal_zone_trip_update(struct thermal_zone_device *tz,
				     const struct thermal_trip *trip)
{
	int trip_id = thermal_zone_trip_id(tz, trip);
	enum thermal_trend trend;
	struct thermal_instance *instance;
	bool throttle = false;
	int old_target;

	trend = get_tz_trend(tz, trip);

	if (tz->temperature >= trip->temperature) {
		throttle = true;
		trace_thermal_zone_trip(tz, trip_id, trip->type);
	}

	dev_dbg(&tz->device, "Trip%d[type=%d,temp=%d]:trend=%d,throttle=%d\n",
		trip_id, trip->type, trip->temperature, trend, throttle);

	list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
		if (instance->trip != trip)
			continue;

		old_target = instance->target;
		instance->target = get_target_state(instance, trend, throttle);
		dev_dbg(&instance->cdev->device, "old_target=%d, target=%d\n",
					old_target, (int)instance->target);

		if (instance->initialized && old_target == instance->target)
			continue;

		if (old_target == THERMAL_NO_TARGET &&
		    instance->target != THERMAL_NO_TARGET) {
			/* Activate a passive thermal instance */
			if (trip->type == THERMAL_TRIP_PASSIVE)
				tz->passive++;
		} else if (old_target != THERMAL_NO_TARGET &&
			   instance->target == THERMAL_NO_TARGET) {
			/* Deactivate a passive thermal instance */
			if (trip->type == THERMAL_TRIP_PASSIVE)
				tz->passive--;
		}

		instance->initialized = true;
		mutex_lock(&instance->cdev->lock);
		instance->cdev->updated = false; /* cdev needs update */
		mutex_unlock(&instance->cdev->lock);
	}
}

/**
 * step_wise_throttle - throttles devices associated with the given zone
 * @tz: thermal_zone_device
 * @trip: trip point
 *
 * Throttling Logic: This uses the trend of the thermal zone to throttle.
 * If the thermal zone is 'heating up' this throttles all the cooling
 * devices associated with the zone and its particular trip point, by one
 * step. If the zone is 'cooling down' it brings back the performance of
 * the devices by one step.
 */
static int step_wise_throttle(struct thermal_zone_device *tz,
			      const struct thermal_trip *trip)
{
	struct thermal_instance *instance;

	lockdep_assert_held(&tz->lock);

	thermal_zone_trip_update(tz, trip);

	list_for_each_entry(instance, &tz->thermal_instances, tz_node)
		thermal_cdev_update(instance->cdev);

	return 0;
}

static struct thermal_governor thermal_gov_step_wise = {
	.name		= "step_wise",
	.throttle	= step_wise_throttle,
};
THERMAL_GOVERNOR_DECLARE(thermal_gov_step_wise);
