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