Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *  gov_bang_bang.c - A simple thermal throttling governor using hysteresis
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  *  Copyright (C) 2014 Peter Kaestle <peter@piie.net>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  *  Based on step_wise.c with following Copyrights:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  *  Copyright (C) 2012 Intel Corp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  *  Copyright (C) 2012 Durgadoss R <durgadoss.r@intel.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/thermal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include "thermal_core.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) static void thermal_zone_trip_update(struct thermal_zone_device *tz, int trip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 	int trip_temp, trip_hyst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) 	struct thermal_instance *instance;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 	tz->ops->get_trip_temp(tz, trip, &trip_temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 	if (!tz->ops->get_trip_hyst) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 		pr_warn_once("Undefined get_trip_hyst for thermal zone %s - "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 				"running with default hysteresis zero\n", tz->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 		trip_hyst = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 		tz->ops->get_trip_hyst(tz, trip, &trip_hyst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 	dev_dbg(&tz->device, "Trip%d[temp=%d]:temp=%d:hyst=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 				trip, trip_temp, tz->temperature,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 				trip_hyst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	mutex_lock(&tz->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 	list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 		if (instance->trip != trip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 		/* in case fan is in initial state, switch the fan off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 		if (instance->target == THERMAL_NO_TARGET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 			instance->target = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 		/* in case fan is neither on nor off set the fan to active */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 		if (instance->target != 0 && instance->target != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 			pr_warn("Thermal instance %s controlled by bang-bang has unexpected state: %ld\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 					instance->name, instance->target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 			instance->target = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 		 * enable fan when temperature exceeds trip_temp and disable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 		 * the fan in case it falls below trip_temp minus hysteresis
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 		if (instance->target == 0 && tz->temperature >= trip_temp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 			instance->target = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 		else if (instance->target == 1 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 				tz->temperature <= trip_temp - trip_hyst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 			instance->target = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 		dev_dbg(&instance->cdev->device, "target=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 					(int)instance->target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 		mutex_lock(&instance->cdev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 		instance->cdev->updated = false; /* cdev needs update */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 		mutex_unlock(&instance->cdev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	mutex_unlock(&tz->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73)  * bang_bang_control - controls devices associated with the given zone
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74)  * @tz: thermal_zone_device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75)  * @trip: the trip point
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77)  * Regulation Logic: a two point regulation, deliver cooling state depending
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78)  * on the previous state shown in this diagram:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80)  *                Fan:   OFF    ON
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82)  *                              |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83)  *                              |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84)  *          trip_temp:    +---->+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85)  *                        |     |        ^
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86)  *                        |     |        |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87)  *                        |     |   Temperature
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88)  * (trip_temp - hyst):    +<----+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89)  *                        |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90)  *                        |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91)  *                        |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93)  *   * If the fan is not running and temperature exceeds trip_temp, the fan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94)  *     gets turned on.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95)  *   * In case the fan is running, temperature must fall below
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96)  *     (trip_temp - hyst) so that the fan gets turned off again.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) static int bang_bang_control(struct thermal_zone_device *tz, int trip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	struct thermal_instance *instance;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	thermal_zone_trip_update(tz, trip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	mutex_lock(&tz->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	list_for_each_entry(instance, &tz->thermal_instances, tz_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 		thermal_cdev_update(instance->cdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	mutex_unlock(&tz->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) static struct thermal_governor thermal_gov_bang_bang = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	.name		= "bang_bang",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	.throttle	= bang_bang_control,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) THERMAL_GOVERNOR_DECLARE(thermal_gov_bang_bang);