• 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 <mutex>
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/cooling/cpu/freq";
39 const std::string GPU_FREQ_PATH = "/data/cooling/gpu/freq";
40 const std::string BATTERY_CHARGER_CURRENT_PATH = "/data/cooling/charger/current";
41 const std::string SIM_BATTERY_CURRENT_PATH = "/data/cooling/battery/current";
42 const std::string BATTERY_VOLTAGE_PATH = "/data/cooling/battery/voltage";
43 std::mutex mutex_;
44 const std::string ACTUAL_CPU_FREQ_PATH = "/sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq";
45 const std::string ACTUAL_BATTERY_CURRENT_PATH = "/sys/class/power_supply/battery/input_current_limited";
46 const int32_t NUM_ZERO = 0;
47 }
WriteSysfsFd(int32_t fd,std::string buf,size_t bytesSize)48 int32_t ThermalDeviceMitigation::WriteSysfsFd(int32_t fd, std::string buf, size_t bytesSize)
49 {
50     ssize_t pos = 0;
51     ssize_t recever = 0;
52     do {
53         recever = write(fd, buf.c_str() + (size_t) pos, bytesSize - (size_t)pos);
54         if (recever < NUM_ZERO) {
55             return recever;
56         }
57         pos += recever;
58     } while ((ssize_t)bytesSize > pos);
59 
60     return (int32_t)bytesSize;
61 }
62 
OpenSysfsFile(std::string filePath,int32_t flags)63 int32_t ThermalDeviceMitigation::OpenSysfsFile(std::string filePath, int32_t flags)
64 {
65     int32_t ret;
66 
67     if (filePath.empty()) {
68         return HDF_ERR_INVALID_PARAM;
69     }
70 
71     ret = open(filePath.c_str(), flags);
72     if (ret < NUM_ZERO) {
73         THERMAL_HILOGE(COMP_HDI, "failed to open file %{public}s", filePath.c_str());
74         return ret;
75     }
76     return ret;
77 }
78 
WriteSysfsFile(std::string filePath,std::string buf,size_t bytesSize)79 int32_t ThermalDeviceMitigation::WriteSysfsFile(std::string filePath, std::string buf, size_t bytesSize)
80 {
81     int32_t fd = OpenSysfsFile(filePath.c_str(), O_RDWR);
82     if (fd < NUM_ZERO) {
83         THERMAL_HILOGE(COMP_HDI, "failed to open %{public}s", filePath.c_str());
84         return HDF_ERR_IO;
85     }
86     int32_t ret = WriteSysfsFd(fd, buf.c_str(), bytesSize);
87     close(fd);
88     return ret;
89 }
90 
SetFlag(bool flag)91 int32_t ThermalDeviceMitigation::SetFlag(bool flag)
92 {
93     flag_ = flag;
94     return HDF_SUCCESS;
95 }
96 
ExecuteCpuRequest(uint32_t freq,const std::string & path)97 int32_t ThermalDeviceMitigation::ExecuteCpuRequest(uint32_t freq, const std::string &path)
98 {
99     int32_t ret = HDF_FAILURE;
100     char freqBuf[MAX_PATH] = {0};
101     char nodeBuf[MAX_BUF_PATH] = {0};
102     if (access(path.c_str(), 0) != NUM_ZERO) {
103         return ret;
104     }
105     std::lock_guard<std::mutex> lock(mutex_);
106     if (snprintf_s(nodeBuf, PATH_MAX, sizeof(nodeBuf) - 1, "%s", path.c_str()) < NUM_ZERO) {
107         return ret;
108     }
109     if (snprintf_s(freqBuf, PATH_MAX, sizeof(freqBuf) - 1, "%d", freq) < NUM_ZERO) {
110         return ret;
111     }
112     if (WriteSysfsFile(nodeBuf, freqBuf, strlen(freqBuf)) > NUM_ZERO) {
113         THERMAL_HILOGI(COMP_HDI, "Set freq to %{public}d", freq);
114         ret = HDF_SUCCESS;
115     } else {
116         THERMAL_HILOGE(COMP_HDI, "failed to set freq");
117         ret = HDF_FAILURE;
118     }
119     return ret;
120 }
121 
CpuRequest(uint32_t freq)122 int32_t ThermalDeviceMitigation::CpuRequest(uint32_t freq)
123 {
124     int32_t ret = ExecuteCpuRequest(freq, ACTUAL_CPU_FREQ_PATH);
125     if (ret != HDF_SUCCESS) {
126         THERMAL_HILOGE(COMP_HDI, "failed to really set freq");
127     }
128     ret = ExecuteCpuRequest(freq, SIM_CPU_FREQ_PATH);
129     if (ret != HDF_SUCCESS) {
130         return HDF_FAILURE;
131     }
132     return HDF_SUCCESS;
133 }
134 
ChargerRequest(uint32_t current)135 int32_t ThermalDeviceMitigation::ChargerRequest(uint32_t current)
136 {
137     int32_t ret = ExecuteChargerRequest(current, ACTUAL_BATTERY_CURRENT_PATH);
138     if (ret != HDF_SUCCESS) {
139         THERMAL_HILOGE(COMP_HDI, "failed to really set current");
140     }
141     ret = ExecuteChargerRequest(current, SIM_BATTERY_CURRENT_PATH);
142     if (ret != HDF_SUCCESS) {
143         return HDF_FAILURE;
144     }
145     return HDF_SUCCESS;
146 }
147 
GpuRequest(uint32_t freq)148 int32_t ThermalDeviceMitigation::GpuRequest(uint32_t freq)
149 {
150     int32_t ret = HDF_FAILURE;
151     char freqBuf[MAX_PATH] = {0};
152     char nodeBuf[MAX_BUF_PATH] = {0};
153 
154     std::lock_guard<std::mutex> lock(mutex_);
155     ret = snprintf_s(nodeBuf, PATH_MAX, sizeof(nodeBuf) - 1, "%s", GPU_FREQ_PATH.c_str());
156     if (ret < NUM_ZERO) {
157         return ret;
158     }
159     ret = snprintf_s(freqBuf, PATH_MAX, sizeof(freqBuf) - 1, "%d", freq);
160     if (ret < NUM_ZERO) {
161         return ret;
162     }
163     if (WriteSysfsFile(nodeBuf, freqBuf, strlen(freqBuf)) > NUM_ZERO) {
164         THERMAL_HILOGI(COMP_HDI, "Set freq to %{public}d", freq);
165         ret = HDF_SUCCESS;
166     } else {
167         THERMAL_HILOGE(COMP_HDI, "failed to set freq");
168         ret = HDF_FAILURE;
169     }
170     return ret;
171 }
172 
ExecuteChargerRequest(uint32_t current,const std::string & path)173 int32_t ThermalDeviceMitigation::ExecuteChargerRequest(uint32_t current, const std::string &path)
174 {
175     int32_t ret = HDF_FAILURE;
176     char currentBuf[MAX_PATH] = {0};
177     char nodeBuf[MAX_BUF_PATH] = {0};
178     static uint32_t previous;
179     if (access(path.c_str(), 0) != NUM_ZERO) {
180         return ret;
181     }
182 
183     std::lock_guard<std::mutex> lock(mutex_);
184     ret = snprintf_s(nodeBuf, PATH_MAX, sizeof(nodeBuf) - 1, "%s", path.c_str());
185     if (ret < NUM_ZERO) {
186         return ret;
187     }
188     ret = snprintf_s(currentBuf, PATH_MAX, sizeof(currentBuf) - 1, "%d%s", current, "\n");
189     if (ret < NUM_ZERO) {
190         return ret;
191     }
192     if (WriteSysfsFile(nodeBuf, currentBuf, strlen(currentBuf)) > NUM_ZERO) {
193         THERMAL_HILOGI(COMP_HDI, "Set current to %{public}d", current);
194         previous = current;
195         ret = HDF_SUCCESS;
196     } else {
197         THERMAL_HILOGE(COMP_HDI, "failed to set current");
198         ret = HDF_FAILURE;
199     }
200     return ret;
201 }
202 
BatteryCurrentRequest(uint32_t current)203 int32_t ThermalDeviceMitigation::BatteryCurrentRequest(uint32_t current)
204 {
205     int32_t ret = HDF_FAILURE;
206     char currentBuf[MAX_PATH] = {0};
207     char nodeBuf[MAX_BUF_PATH] = {0};
208 
209     std::lock_guard<std::mutex> lock(mutex_);
210     ret = snprintf_s(nodeBuf, PATH_MAX, sizeof(nodeBuf) - 1, "%s", SIM_BATTERY_CURRENT_PATH.c_str());
211     if (ret < NUM_ZERO) {
212         return ret;
213     }
214     ret = snprintf_s(currentBuf, PATH_MAX, sizeof(currentBuf) - 1, "%d", current);
215     if (ret < NUM_ZERO) {
216         return ret;
217     }
218     if (WriteSysfsFile(nodeBuf, currentBuf, strlen(currentBuf)) > NUM_ZERO) {
219         THERMAL_HILOGI(COMP_HDI, "Set current to %{public}d", current);
220         ret = HDF_SUCCESS;
221     } else {
222         THERMAL_HILOGE(COMP_HDI, "failed to set current");
223         ret = HDF_FAILURE;
224     }
225     return ret;
226 }
227 
BatteryVoltageRequest(uint32_t voltage)228 int32_t ThermalDeviceMitigation::BatteryVoltageRequest(uint32_t voltage)
229 {
230     int32_t ret = HDF_FAILURE;
231     char voltageBuf[MAX_PATH] = {0};
232     char voltageNode[MAX_BUF_PATH] = {0};
233 
234     std::lock_guard<std::mutex> lock(mutex_);
235     ret = snprintf_s(voltageNode, PATH_MAX, sizeof(voltageNode) - 1, "%s", BATTERY_VOLTAGE_PATH.c_str());
236     if (ret < NUM_ZERO) {
237         return ret;
238     }
239     ret = snprintf_s(voltageBuf, PATH_MAX, sizeof(voltageBuf) - 1, "%d", voltage);
240     if (ret < NUM_ZERO) {
241         return ret;
242     }
243     if (WriteSysfsFile(voltageNode, voltageBuf, strlen(voltageBuf)) > NUM_ZERO) {
244         THERMAL_HILOGI(COMP_HDI, "Set current to %{public}d", voltage);
245         ret = HDF_SUCCESS;
246     } else {
247         THERMAL_HILOGE(COMP_HDI, "failed to set current");
248         ret = HDF_FAILURE;
249     }
250     return ret;
251 }
252 } // V1_0
253 } // Thermal
254 } // HDI
255 } // OHOS