• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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