blob: 1a0e3a2a1a7f86111e5a7358a8750a7a1f423bf0 [file] [log] [blame]
Ram Chandrasekar14a48f52021-04-06 13:25:32 -07001/*
2 * Copyright (c) 2021, The Linux Foundation. All rights reserved.
Manaf Meethalavalappu Pallikunhiab1e3c52022-05-14 01:53:29 +05303 * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
Ram Chandrasekar14a48f52021-04-06 13:25:32 -07004 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following
12 * disclaimer in the documentation and/or other materials provided
13 * with the distribution.
14 * * Neither the name of The Linux Foundation nor the names of its
15 * contributors may be used to endorse or promote products derived
16 * from this software without specific prior written permission.
17 *
18 *
19 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
20 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
26 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
28 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
29 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
Bavyasritha Alahari0a344f42023-04-26 17:16:51 -070032/* Changes from Qualcomm Innovation Center are provided under the following license:
33
Priyansh Jainc5ea5602024-08-12 11:18:21 +053034Copyright (c) 2023, 2025 Qualcomm Innovation Center, Inc. All rights reserved.
Bavyasritha Alahari0a344f42023-04-26 17:16:51 -070035SPDX-License-Identifier: BSD-3-Clause-Clear */
36
Ram Chandrasekar14a48f52021-04-06 13:25:32 -070037#include <android-base/file.h>
38#include <android-base/logging.h>
39#include <android-base/properties.h>
40#include <android-base/stringprintf.h>
41#include <android-base/strings.h>
Ram Chandrasekar14a48f52021-04-06 13:25:32 -070042
43#include "thermalConfig.h"
44#include "thermalUtilsNetlink.h"
45
Bavyasritha Alahari0a344f42023-04-26 17:16:51 -070046namespace aidl {
Ram Chandrasekar14a48f52021-04-06 13:25:32 -070047namespace android {
48namespace hardware {
49namespace thermal {
Ram Chandrasekar14a48f52021-04-06 13:25:32 -070050
51ThermalUtils::ThermalUtils(const ueventCB &inp_cb):
52 cfg(),
53 cmnInst(),
54 monitor(std::bind(&ThermalUtils::eventParse, this,
55 std::placeholders::_1,
56 std::placeholders::_2),
57 std::bind(&ThermalUtils::sampleParse, this,
58 std::placeholders::_1,
Manaf Meethalavalappu Pallikunhiab1e3c52022-05-14 01:53:29 +053059 std::placeholders::_2),
60 std::bind(&ThermalUtils::eventCreateParse, this,
61 std::placeholders::_1,
Ram Chandrasekar14a48f52021-04-06 13:25:32 -070062 std::placeholders::_2)),
63 cb(inp_cb)
64{
65 int ret = 0;
66 std::vector<struct therm_sensor> sensorList;
67 std::vector<struct target_therm_cfg> therm_cfg = cfg.fetchConfig();
68
Ram Chandrasekar14a48f52021-04-06 13:25:32 -070069 is_cdev_init = false;
70 ret = cmnInst.initThermalZones(therm_cfg);
71 if (ret > 0) {
Ram Chandrasekar14a48f52021-04-06 13:25:32 -070072 sensorList = cmnInst.fetch_sensor_list();
73 std::lock_guard<std::mutex> _lock(sens_cb_mutex);
74 for (struct therm_sensor sens: sensorList) {
75 thermalConfig[sens.tzn] = sens;
76 cmnInst.read_temperature(sens);
77 cmnInst.estimateSeverity(sens);
78 cmnInst.initThreshold(sens);
79 }
Ram Chandrasekar14a48f52021-04-06 13:25:32 -070080 }
Manaf Meethalavalappu Pallikunhiab1e3c52022-05-14 01:53:29 +053081 monitor.start();
Ram Chandrasekar14a48f52021-04-06 13:25:32 -070082 ret = cmnInst.initCdev();
83 if (ret > 0) {
84 is_cdev_init = true;
85 cdevList = cmnInst.fetch_cdev_list();
86 }
87}
88
Priyansh Jainc5ea5602024-08-12 11:18:21 +053089bool ThermalUtils::isSensorInitialized()
90{
91 std::lock_guard<std::mutex> _lock(sens_cb_mutex);
92
93 if (thermalConfig.begin() == thermalConfig.end())
94 return false;
95
96 return true;
97}
98
99bool ThermalUtils::isSensorInitialized(TemperatureType type)
100{
101 std::unordered_map<int, struct therm_sensor>::iterator it;
102 std::lock_guard<std::mutex> _lock(sens_cb_mutex);
103
104 if (thermalConfig.begin() == thermalConfig.end())
105 return false;
106
107 for (it = thermalConfig.begin(); it != thermalConfig.end();
108 it++) {
109 struct therm_sensor& sens = it->second;
110 if (sens.t.type == type)
111 return true;
112 }
113
114 return false;
115}
116
Ram Chandrasekar14a48f52021-04-06 13:25:32 -0700117void ThermalUtils::Notify(struct therm_sensor& sens)
118{
119 int severity = cmnInst.estimateSeverity(sens);
120 if (severity != -1) {
121 LOG(INFO) << "sensor: " << sens.sensor_name <<" temperature: "
122 << sens.t.value << " old: " <<
123 (int)sens.lastThrottleStatus << " new: " <<
124 (int)sens.t.throttlingStatus << std::endl;
125 cb(sens.t);
126 cmnInst.initThreshold(sens);
127 }
128}
129
130void ThermalUtils::eventParse(int tzn, int trip)
131{
132 if (trip != 1)
133 return;
134 if (thermalConfig.find(tzn) == thermalConfig.end()) {
135 LOG(DEBUG) << "sensor is not monitored:" << tzn
136 << std::endl;
137 return;
138 }
139 std::lock_guard<std::mutex> _lock(sens_cb_mutex);
140 struct therm_sensor& sens = thermalConfig[tzn];
141 return Notify(sens);
142}
143
144void ThermalUtils::sampleParse(int tzn, int temp)
145{
146 if (thermalConfig.find(tzn) == thermalConfig.end()) {
147 LOG(DEBUG) << "sensor is not monitored:" << tzn
148 << std::endl;
149 return;
150 }
151 std::lock_guard<std::mutex> _lock(sens_cb_mutex);
152 struct therm_sensor& sens = thermalConfig[tzn];
153 sens.t.value = (float)temp / (float)sens.mulFactor;
Ram Chandrasekar372b9342021-07-22 12:55:33 -0700154 return Notify(sens);
Ram Chandrasekar14a48f52021-04-06 13:25:32 -0700155}
156
Manaf Meethalavalappu Pallikunhiab1e3c52022-05-14 01:53:29 +0530157void ThermalUtils::eventCreateParse(int tzn, const char *name)
158{
159 int ret = 0;
160 std::vector<struct therm_sensor> sensorList;
161 std::vector<struct target_therm_cfg> therm_cfg = cfg.fetchConfig();
162 std::vector<struct target_therm_cfg>::iterator it_vec;
163 std::vector<std::string>::iterator it;
164
Priyansh Jainc5ea5602024-08-12 11:18:21 +0530165 if (thermalConfig.find(tzn) != thermalConfig.end())
Manaf Meethalavalappu Pallikunhiab1e3c52022-05-14 01:53:29 +0530166 return;
Priyansh Jainc5ea5602024-08-12 11:18:21 +0530167
Manaf Meethalavalappu Pallikunhiab1e3c52022-05-14 01:53:29 +0530168 for (it_vec = therm_cfg.begin();
169 it_vec != therm_cfg.end(); it_vec++) {
170 for (it = it_vec->sensor_list.begin();
171 it != it_vec->sensor_list.end(); it++) {
172 if (!it->compare(name))
173 break;
174 }
175 if (it != it_vec->sensor_list.end())
176 break;
177 }
178 if (it_vec == therm_cfg.end()) {
179 LOG(DEBUG) << "sensor is not monitored:" << tzn
180 << std::endl;
181 return;
182 }
Priyansh Jainc5ea5602024-08-12 11:18:21 +0530183 ret = cmnInst.initNewThermalZone(*it_vec);
Manaf Meethalavalappu Pallikunhiab1e3c52022-05-14 01:53:29 +0530184 if (ret > 0) {
Manaf Meethalavalappu Pallikunhiab1e3c52022-05-14 01:53:29 +0530185 sensorList = cmnInst.fetch_sensor_list();
186 std::lock_guard<std::mutex> _lock(sens_cb_mutex);
187 for (struct therm_sensor sens: sensorList) {
Priyansh Jainc5ea5602024-08-12 11:18:21 +0530188 if (sens.sensor_name != name)
189 continue;
Manaf Meethalavalappu Pallikunhiab1e3c52022-05-14 01:53:29 +0530190 thermalConfig[sens.tzn] = sens;
191 cmnInst.read_temperature(sens);
192 cmnInst.estimateSeverity(sens);
193 cmnInst.initThreshold(sens);
Priyansh Jainc5ea5602024-08-12 11:18:21 +0530194 break;
Manaf Meethalavalappu Pallikunhiab1e3c52022-05-14 01:53:29 +0530195 }
196 }
197}
198
Bavyasritha Alahari0a344f42023-04-26 17:16:51 -0700199int ThermalUtils::readTemperatures(std::vector<Temperature>& temp)
Ram Chandrasekar14a48f52021-04-06 13:25:32 -0700200{
201 std::unordered_map<int, struct therm_sensor>::iterator it;
202 int ret = 0;
203 std::vector<Temperature> _temp;
204
205 std::lock_guard<std::mutex> _lock(sens_cb_mutex);
206 for (it = thermalConfig.begin(); it != thermalConfig.end(); it++) {
207 struct therm_sensor& sens = it->second;
208
Bavyasritha Alahari0a344f42023-04-26 17:16:51 -0700209 ret = cmnInst.read_temperature(sens);
210 if (ret < 0)
211 return ret;
212 Notify(sens);
213 _temp.push_back(sens.t);
214 }
215
216 temp = _temp;
217 return temp.size();
218}
219
220int ThermalUtils::readTemperatures(TemperatureType type,
221 std::vector<Temperature>& temp)
222{
223 std::unordered_map<int, struct therm_sensor>::iterator it;
224 int ret = 0;
225 std::vector<Temperature> _temp;
226
227 std::lock_guard<std::mutex> _lock(sens_cb_mutex);
228 for (it = thermalConfig.begin(); it != thermalConfig.end(); it++) {
229 struct therm_sensor& sens = it->second;
230
231 if (sens.t.type != type)
Ram Chandrasekar14a48f52021-04-06 13:25:32 -0700232 continue;
233 ret = cmnInst.read_temperature(sens);
234 if (ret < 0)
235 return ret;
236 Notify(sens);
237 _temp.push_back(sens.t);
238 }
239
240 temp = _temp;
241 return temp.size();
242}
243
Bavyasritha Alahari0a344f42023-04-26 17:16:51 -0700244int ThermalUtils::readTemperatureThreshold(std::vector<TemperatureThreshold>& thresh)
Ram Chandrasekar14a48f52021-04-06 13:25:32 -0700245{
246 std::unordered_map<int, struct therm_sensor>::iterator it;
247 std::vector<TemperatureThreshold> _thresh;
248
249 for (it = thermalConfig.begin(); it != thermalConfig.end(); it++) {
250 struct therm_sensor& sens = it->second;
251
Bavyasritha Alahari0a344f42023-04-26 17:16:51 -0700252 _thresh.push_back(sens.thresh);
253 }
254
255 thresh = _thresh;
256 return thresh.size();
257}
258
259int ThermalUtils::readTemperatureThreshold(TemperatureType type,
260 std::vector<TemperatureThreshold>& thresh)
261{
262 std::unordered_map<int, struct therm_sensor>::iterator it;
263 std::vector<TemperatureThreshold> _thresh;
264
265 for (it = thermalConfig.begin(); it != thermalConfig.end(); it++) {
266 struct therm_sensor& sens = it->second;
267
268 if (sens.t.type != type)
Ram Chandrasekar14a48f52021-04-06 13:25:32 -0700269 continue;
270 _thresh.push_back(sens.thresh);
271 }
272
273 thresh = _thresh;
274 return thresh.size();
275}
276
Bavyasritha Alahari0a344f42023-04-26 17:16:51 -0700277int ThermalUtils::readCdevStates(std::vector<CoolingDevice>& cdev_out)
Ram Chandrasekar14a48f52021-04-06 13:25:32 -0700278{
279 int ret = 0;
280 std::vector<CoolingDevice> _cdev;
281
282 for (struct therm_cdev cdev: cdevList) {
283
Bavyasritha Alahari0a344f42023-04-26 17:16:51 -0700284 ret = cmnInst.read_cdev_state(cdev);
285 if (ret < 0)
286 return ret;
287 _cdev.push_back(cdev.c);
288 }
289
290 cdev_out = _cdev;
291
292 return cdev_out.size();
293}
294
295int ThermalUtils::readCdevStates(cdevType type,
296 std::vector<CoolingDevice>& cdev_out)
297{
298 int ret = 0;
299 std::vector<CoolingDevice> _cdev;
300
301 for (struct therm_cdev cdev: cdevList) {
302
303 if (cdev.c.type != type)
Ram Chandrasekar14a48f52021-04-06 13:25:32 -0700304 continue;
305 ret = cmnInst.read_cdev_state(cdev);
306 if (ret < 0)
307 return ret;
308 _cdev.push_back(cdev.c);
309 }
310
311 cdev_out = _cdev;
312
313 return cdev_out.size();
314}
315
Ram Chandrasekar14a48f52021-04-06 13:25:32 -0700316} // namespace thermal
317} // namespace hardware
318} // namespace android
Bavyasritha Alahari0a344f42023-04-26 17:16:51 -0700319} // namespace aidl