Blame view

drivers/thermal/gov_bang_bang.c 3.33 KB
50acfb2b7   Thomas Gleixner   treewide: Replace...
1
  // SPDX-License-Identifier: GPL-2.0-only
e4dbf98f7   Peter Feuerer   thermal: Added Ba...
2
3
4
  /*
   *  gov_bang_bang.c - A simple thermal throttling governor using hysteresis
   *
d3f5b7366   Peter Kaestle   treewide: Rename ...
5
   *  Copyright (C) 2014 Peter Kaestle <peter@piie.net>
e4dbf98f7   Peter Feuerer   thermal: Added Ba...
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   Peter Feuerer   thermal: Added Ba...
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   Sascha Hauer   thermal: consiste...
18
  	int trip_temp, trip_hyst;
e4dbf98f7   Peter Feuerer   thermal: Added Ba...
19
20
21
  	struct thermal_instance *instance;
  
  	tz->ops->get_trip_temp(tz, trip, &trip_temp);
191b07541   Michele Di Giorgio   thermal: check va...
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   Peter Feuerer   thermal: Added Ba...
30

17e8351a7   Sascha Hauer   thermal: consiste...
31
32
  	dev_dbg(&tz->device, "Trip%d[temp=%d]:temp=%d:hyst=%d
  ",
e4dbf98f7   Peter Feuerer   thermal: Added Ba...
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   Sascha Hauer   thermal: bang-ban...
61
  				tz->temperature <= trip_temp - trip_hyst)
e4dbf98f7   Peter Feuerer   thermal: Added Ba...
62
63
64
65
66
  			instance->target = 0;
  
  		dev_dbg(&instance->cdev->device, "target=%d
  ",
  					(int)instance->target);
d0b7306d2   Michele Di Giorgio   thermal: fix race...
67
  		mutex_lock(&instance->cdev->lock);
e4dbf98f7   Peter Feuerer   thermal: Added Ba...
68
  		instance->cdev->updated = false; /* cdev needs update */
d0b7306d2   Michele Di Giorgio   thermal: fix race...
69
  		mutex_unlock(&instance->cdev->lock);
e4dbf98f7   Peter Feuerer   thermal: Added Ba...
70
71
72
73
74
75
76
  	}
  
  	mutex_unlock(&tz->lock);
  }
  
  /**
   * bang_bang_control - controls devices associated with the given zone
53d256e79   Amit Kucheria   thermal: step_wis...
77
78
   * @tz: thermal_zone_device
   * @trip: the trip point
e4dbf98f7   Peter Feuerer   thermal: Added Ba...
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   Daniel Lezcano   thermal/drivers/c...
122
  THERMAL_GOVERNOR_DECLARE(thermal_gov_bang_bang);