1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "thermal_device_mitigation.h"
17
18 #include <cstdio>
19 #include <cstdlib>
20 #include <fcntl.h>
21 #include <fstream>
22 #include <unistd.h>
23
24 #include "hdf_base.h"
25 #include "securec.h"
26 #include "utils/hdf_log.h"
27 #include "thermal_log.h"
28
29 #define HDF_LOG_TAG ThermalDeviceMitigation
30
31 namespace OHOS {
32 namespace HDI {
33 namespace Thermal {
34 namespace V1_0 {
35 namespace {
36 const int32_t MAX_PATH = 256;
37 const int32_t MAX_BUF_PATH = 256;
38 const std::string SIM_CPU_FREQ_PATH = "/data/service/el0/thermal/cooling/cpu/freq";
39 const std::string GPU_FREQ_PATH = "/data/service/el0/thermal/cooling/gpu/freq";
40 const std::string BATTERY_CHARGER_CURRENT_PATH = "/data/service/el0/thermal/cooling/charger/current";
41 const std::string SIM_BATTERY_CURRENT_PATH = "/data/service/el0/thermal/cooling/battery/current";
42 const std::string BATTERY_VOLTAGE_PATH = "/data/service/el0/thermal/cooling/battery/voltage";
43 const std::string ACTUAL_BATTERY_CURRENT_PATH = "/sys/class/power_supply/battery/input_current_limited";
44 const int32_t NUM_ZERO = 0;
45 }
WriteSysfsFd(int32_t fd,std::string buf,size_t bytesSize)46 int32_t ThermalDeviceMitigation::WriteSysfsFd(int32_t fd, std::string buf, size_t bytesSize)
47 {
48 ssize_t pos = 0;
49 do {
50 ssize_t recever = write(fd, buf.c_str() + (size_t) pos, bytesSize - (size_t)pos);
51 if (recever < NUM_ZERO) {
52 return recever;
53 }
54 pos += recever;
55 } while ((ssize_t)bytesSize > pos);
56
57 return (int32_t)bytesSize;
58 }
59
OpenSysfsFile(std::string filePath,int32_t flags)60 int32_t ThermalDeviceMitigation::OpenSysfsFile(std::string filePath, int32_t flags)
61 {
62 int32_t ret;
63
64 if (filePath.empty()) {
65 return HDF_ERR_INVALID_PARAM;
66 }
67
68 ret = open(filePath.c_str(), flags);
69 if (ret < NUM_ZERO) {
70 THERMAL_HILOGE(COMP_HDI, "failed to open file");
71 return ret;
72 }
73 return ret;
74 }
75
WriteSysfsFile(std::string filePath,std::string buf,size_t bytesSize)76 int32_t ThermalDeviceMitigation::WriteSysfsFile(std::string filePath, std::string buf, size_t bytesSize)
77 {
78 std::fstream file(filePath.c_str(), std::ios::out | std::ios::trunc);
79 file.close();
80 int32_t fd = OpenSysfsFile(filePath.c_str(), O_RDWR);
81 if (fd < NUM_ZERO) {
82 THERMAL_HILOGE(COMP_HDI, "failed to open file");
83 return HDF_ERR_IO;
84 }
85 int32_t ret = WriteSysfsFd(fd, buf.c_str(), bytesSize);
86 close(fd);
87 return ret;
88 }
89
SetFlag(bool flag)90 int32_t ThermalDeviceMitigation::SetFlag(bool flag)
91 {
92 flag_ = flag;
93 return HDF_SUCCESS;
94 }
95
ExecuteCpuRequest(uint32_t freq,const std::string & path)96 int32_t ThermalDeviceMitigation::ExecuteCpuRequest(uint32_t freq, const std::string &path)
97 {
98 int32_t ret = HDF_FAILURE;
99 char freqBuf[MAX_PATH] = {0};
100 char nodeBuf[MAX_BUF_PATH] = {0};
101 if (access(path.c_str(), 0) != NUM_ZERO) {
102 return ret;
103 }
104 std::lock_guard<std::mutex> lock(mutex_);
105 if (snprintf_s(nodeBuf, MAX_BUF_PATH, sizeof(nodeBuf) - 1, "%s", path.c_str()) < EOK) {
106 return ret;
107 }
108 if (snprintf_s(freqBuf, MAX_PATH, sizeof(freqBuf) - 1, "%d", freq) < EOK) {
109 return ret;
110 }
111 if (WriteSysfsFile(nodeBuf, freqBuf, strlen(freqBuf)) > NUM_ZERO) {
112 THERMAL_HILOGI(COMP_HDI, "Set freq to %{public}d", freq);
113 ret = HDF_SUCCESS;
114 } else {
115 THERMAL_HILOGE(COMP_HDI, "failed to set freq");
116 ret = HDF_FAILURE;
117 }
118 return ret;
119 }
120
CpuRequest(uint32_t freq)121 int32_t ThermalDeviceMitigation::CpuRequest(uint32_t freq)
122 {
123 int32_t ret = ExecuteCpuRequest(freq, SIM_CPU_FREQ_PATH);
124 if (ret != HDF_SUCCESS) {
125 return HDF_FAILURE;
126 }
127 return HDF_SUCCESS;
128 }
129
ChargerRequest(uint32_t current)130 int32_t ThermalDeviceMitigation::ChargerRequest(uint32_t current)
131 {
132 int32_t ret = ExecuteChargerRequest(current, ACTUAL_BATTERY_CURRENT_PATH);
133 if (ret != HDF_SUCCESS) {
134 THERMAL_HILOGE(COMP_HDI, "failed to really set current");
135 }
136 ret = ExecuteChargerRequest(current, SIM_BATTERY_CURRENT_PATH);
137 if (ret != HDF_SUCCESS) {
138 return HDF_FAILURE;
139 }
140 return HDF_SUCCESS;
141 }
142
GpuRequest(uint32_t freq)143 int32_t ThermalDeviceMitigation::GpuRequest(uint32_t freq)
144 {
145 int32_t ret = HDF_FAILURE;
146 char freqBuf[MAX_PATH] = {0};
147 char nodeBuf[MAX_BUF_PATH] = {0};
148
149 std::lock_guard<std::mutex> lock(mutex_);
150 ret = snprintf_s(nodeBuf, MAX_BUF_PATH, sizeof(nodeBuf) - 1, "%s", GPU_FREQ_PATH.c_str());
151 if (ret < EOK) {
152 return ret;
153 }
154 ret = snprintf_s(freqBuf, MAX_PATH, sizeof(freqBuf) - 1, "%d", freq);
155 if (ret < EOK) {
156 return ret;
157 }
158 if (WriteSysfsFile(nodeBuf, freqBuf, strlen(freqBuf)) > NUM_ZERO) {
159 THERMAL_HILOGI(COMP_HDI, "Set freq to %{public}d", freq);
160 ret = HDF_SUCCESS;
161 } else {
162 THERMAL_HILOGE(COMP_HDI, "failed to set freq");
163 ret = HDF_FAILURE;
164 }
165 return ret;
166 }
167
ExecuteChargerRequest(uint32_t current,const std::string & path)168 int32_t ThermalDeviceMitigation::ExecuteChargerRequest(uint32_t current, const std::string &path)
169 {
170 int32_t ret = HDF_FAILURE;
171 char currentBuf[MAX_PATH] = {0};
172 char nodeBuf[MAX_BUF_PATH] = {0};
173 if (access(path.c_str(), 0) != NUM_ZERO) {
174 return ret;
175 }
176
177 std::lock_guard<std::mutex> lock(mutex_);
178 ret = snprintf_s(nodeBuf, MAX_BUF_PATH, sizeof(nodeBuf) - 1, "%s", path.c_str());
179 if (ret < EOK) {
180 return ret;
181 }
182 ret = snprintf_s(currentBuf, MAX_PATH, sizeof(currentBuf) - 1, "%d%s", current, "\n");
183 if (ret < EOK) {
184 return ret;
185 }
186 if (WriteSysfsFile(nodeBuf, currentBuf, strlen(currentBuf)) > NUM_ZERO) {
187 THERMAL_HILOGI(COMP_HDI, "Set current to %{public}d", current);
188 ret = HDF_SUCCESS;
189 } else {
190 THERMAL_HILOGE(COMP_HDI, "failed to set current");
191 ret = HDF_FAILURE;
192 }
193 return ret;
194 }
195
BatteryCurrentRequest(uint32_t current)196 int32_t ThermalDeviceMitigation::BatteryCurrentRequest(uint32_t current)
197 {
198 int32_t ret = HDF_FAILURE;
199 char currentBuf[MAX_PATH] = {0};
200 char nodeBuf[MAX_BUF_PATH] = {0};
201
202 std::lock_guard<std::mutex> lock(mutex_);
203 ret = snprintf_s(nodeBuf, MAX_BUF_PATH, sizeof(nodeBuf) - 1, "%s", SIM_BATTERY_CURRENT_PATH.c_str());
204 if (ret < EOK) {
205 return ret;
206 }
207 ret = snprintf_s(currentBuf, MAX_PATH, sizeof(currentBuf) - 1, "%d", current);
208 if (ret < EOK) {
209 return ret;
210 }
211 if (WriteSysfsFile(nodeBuf, currentBuf, strlen(currentBuf)) > NUM_ZERO) {
212 THERMAL_HILOGI(COMP_HDI, "Set current to %{public}d", current);
213 ret = HDF_SUCCESS;
214 } else {
215 THERMAL_HILOGE(COMP_HDI, "failed to set current");
216 ret = HDF_FAILURE;
217 }
218 return ret;
219 }
220
BatteryVoltageRequest(uint32_t voltage)221 int32_t ThermalDeviceMitigation::BatteryVoltageRequest(uint32_t voltage)
222 {
223 int32_t ret = HDF_FAILURE;
224 char voltageBuf[MAX_PATH] = {0};
225 char voltageNode[MAX_BUF_PATH] = {0};
226
227 std::lock_guard<std::mutex> lock(mutex_);
228 ret = snprintf_s(voltageNode, MAX_BUF_PATH, sizeof(voltageNode) - 1, "%s", BATTERY_VOLTAGE_PATH.c_str());
229 if (ret < EOK) {
230 return ret;
231 }
232 ret = snprintf_s(voltageBuf, MAX_PATH, sizeof(voltageBuf) - 1, "%d", voltage);
233 if (ret < EOK) {
234 return ret;
235 }
236 if (WriteSysfsFile(voltageNode, voltageBuf, strlen(voltageBuf)) > NUM_ZERO) {
237 THERMAL_HILOGI(COMP_HDI, "Set current to %{public}d", voltage);
238 ret = HDF_SUCCESS;
239 } else {
240 THERMAL_HILOGE(COMP_HDI, "failed to set current");
241 ret = HDF_FAILURE;
242 }
243 return ret;
244 }
245 } // V1_0
246 } // Thermal
247 } // HDI
248 } // OHOS
249