Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6d44a344 authored by Ram Chandrasekar's avatar Ram Chandrasekar
Browse files

drivers: thermal: Add low limits monitoring governor



Add low limits monitor governor, which will place a predefined
mitigation action on a cooling device, when the sensor reading falls
below a trip threshold.

This governor will throttle the minimum floor of a cooling device and
doesn't place a maximum scaling cap on a cooling device. So the cooling
devices monitored by this governor should have support to handle the
minimum floor request from the governor. If the cooling device doesn't
support, then the mitigation request from the governor will be ignored
by the thermal sys framework.

Change-Id: I867eb21b18eb0fef42250e21ee2c5920dd547def
Signed-off-by: default avatarRam Chandrasekar <rkumbako@codeaurora.org>
parent 9d62754f
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -174,6 +174,8 @@ Optional property:
			"fair_share": Use fair share governor.
			"user_space": Use user space governor.
			"power_allocator": Use power allocator governor.
			"low_limits_floor": Use low limits floor
						mitigation governor.
  Type: string

- sustainable-power:	An estimate of the sustainable power (in mW) that the
+10 −0
Original line number Diff line number Diff line
@@ -118,6 +118,16 @@ config THERMAL_GOV_USER_SPACE
	help
	  Enable this to let the user space manage the platform thermals.

config THERMAL_GOV_LOW_LIMITS
	bool "Low limits mitigation governor"
	help
	  Enable this to manage platform limits using low limits
	  governor.

	  Enable this governor to monitor and trigger floor mitigation.
	  This governor will monitor the limits going below a
	  trip threshold to trigger a floor mitigation.

config THERMAL_GOV_POWER_ALLOCATOR
	bool "Power allocator thermal governor"
	help
+1 −0
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@ thermal_sys-$(CONFIG_THERMAL_GOV_FAIR_SHARE) += fair_share.o
thermal_sys-$(CONFIG_THERMAL_GOV_BANG_BANG)	+= gov_bang_bang.o
thermal_sys-$(CONFIG_THERMAL_GOV_STEP_WISE)	+= step_wise.o
thermal_sys-$(CONFIG_THERMAL_GOV_USER_SPACE)	+= user_space.o
thermal_sys-$(CONFIG_THERMAL_GOV_LOW_LIMITS) += gov_low_limits.o
thermal_sys-$(CONFIG_THERMAL_GOV_POWER_ALLOCATOR)	+= power_allocator.o

# cpufreq cooling
+123 −0
Original line number Diff line number Diff line
/*
 *  Copyright (C) 2012 Intel Corp
 *  Copyright (C) 2012 Durgadoss R <durgadoss.r@intel.com>
 *  Copyright (c) 2017, The Linux Foundation. All rights reserved.
 *
 *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; version 2 of the License.
 *
 *  This program is distributed in the hope that it will be useful, but
 *  WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  General Public License for more details.
 *
 *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 */

#include <linux/thermal.h>
#include <trace/events/thermal.h>

#include "thermal_core.h"

static void thermal_zone_trip_update(struct thermal_zone_device *tz, int trip)
{
	int trip_temp, trip_hyst;
	enum thermal_trip_type trip_type;
	struct thermal_instance *instance;
	bool throttle;
	int old_target;

	tz->ops->get_trip_temp(tz, trip, &trip_temp);
	tz->ops->get_trip_type(tz, trip, &trip_type);
	if (tz->ops->get_trip_hyst) {
		tz->ops->get_trip_hyst(tz, trip, &trip_hyst);
		trip_hyst = trip_temp + trip_hyst;
	} else {
		trip_hyst = trip_temp;
	}

	mutex_lock(&tz->lock);

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

		if ((tz->temperature <= trip_temp) ||
			(instance->target != THERMAL_NO_TARGET
				&& tz->temperature <= trip_hyst))
			throttle = true;
		else
			throttle = false;

		dev_dbg(&tz->device,
			"Trip%d[type=%d,temp=%d,hyst=%d],throttle=%d\n",
			trip, trip_type, trip_temp, trip_hyst, throttle);

		old_target = instance->target;
		instance->target = (throttle) ? instance->upper
					: THERMAL_NO_TARGET;
		dev_dbg(&instance->cdev->device, "old_target=%d, target=%d\n",
					old_target, (int)instance->target);

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

		if (old_target == THERMAL_NO_TARGET &&
				instance->target != THERMAL_NO_TARGET) {
			trace_thermal_zone_trip(tz, trip, trip_type);
			tz->passive += 1;
		} else if (old_target != THERMAL_NO_TARGET &&
				instance->target == THERMAL_NO_TARGET) {
			tz->passive -= 1;
		}

		instance->cdev->updated = false; /* cdev needs update */
	}

	mutex_unlock(&tz->lock);
}

/**
 * low_limits_throttle - throttles devices associated with the given zone
 * @tz - thermal_zone_device
 * @trip - the trip point
 *
 * Throttling Logic: If the sensor reading goes below a trip point, the
 * pre-defined mitigation will be applied for the cooling device.
 * If the sensor reading goes above the trip hysteresis, the
 * mitigation will be removed.
 */
static int low_limits_throttle(struct thermal_zone_device *tz, int trip)
{
	struct thermal_instance *instance;

	thermal_zone_trip_update(tz, trip);

	mutex_lock(&tz->lock);

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

	mutex_unlock(&tz->lock);

	return 0;
}

static struct thermal_governor thermal_gov_low_limits_floor = {
	.name		= "low_limits_floor",
	.throttle	= low_limits_throttle,
	.min_state_throttle = 1,
};

int thermal_gov_low_limits_register(void)
{
	return thermal_register_governor(&thermal_gov_low_limits_floor);
}

void thermal_gov_low_limits_unregister(void)
{
	thermal_unregister_governor(&thermal_gov_low_limits_floor);
}
+5 −0
Original line number Diff line number Diff line
@@ -2348,6 +2348,10 @@ static int __init thermal_register_governors(void)
	if (result)
		return result;

	result = thermal_gov_low_limits_register();
	if (result)
		return result;

	return thermal_gov_power_allocator_register();
}

@@ -2357,6 +2361,7 @@ static void thermal_unregister_governors(void)
	thermal_gov_fair_share_unregister();
	thermal_gov_bang_bang_unregister();
	thermal_gov_user_space_unregister();
	thermal_gov_low_limits_unregister();
	thermal_gov_power_allocator_unregister();
}

Loading