2 * Copyright 2012 Samsung Electronics Co., Ltd
4 * Licensed under the Flora License, Version 1.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.tizenopensource.org/license
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
20 #include "ss_device_plugin.h"
22 #include "include/ss_data.h"
24 #define DEFAULT_MAX_CPU_FREQ 12000000
25 #define DEFAULT_MIN_CPU_FREQ 1000000
27 static int max_cpu_freq_limit = -1;
28 static int min_cpu_freq_limit = -1;
29 static int cur_max_cpu_freq = INT_MIN;
30 static int cur_min_cpu_freq = INT_MAX;
32 static Eina_List *max_cpu_freq_list;
33 static Eina_List *min_cpu_freq_list;
35 struct cpu_freq_entry {
40 static void __set_freq_limit();
41 static int __is_entry_enble(int pid);
42 static int __remove_entry_from_max_cpu_freq_list(int pid);
43 static int __remove_entry_from_min_cpu_freq_list(int pid);
44 static int __add_entry_to_max_cpu_freq_list(int pid, int freq);
45 static int __add_entry_to_min_cpu_freq_list(int pid, int freq);
46 static int __write_max_cpu_freq(int freq);
47 static int __write_min_cpu_freq(int freq);
49 int set_max_frequency_action(int argc, char **argv)
56 r = __add_entry_to_max_cpu_freq_list(atoi(argv[0]), atoi(argv[1]));
58 PRT_TRACE_ERR("Add entry failed");
62 r = __write_max_cpu_freq(cur_max_cpu_freq);
64 PRT_TRACE_ERR("Write entry failed");
71 int set_min_frequency_action(int argc, char **argv)
78 r = __add_entry_to_min_cpu_freq_list(atoi(argv[0]), atoi(argv[1]));
80 PRT_TRACE_ERR("Add entry failed");
84 r = __write_min_cpu_freq(cur_min_cpu_freq);
86 PRT_TRACE_ERR("Write entry failed");
93 int release_max_frequency_action(int argc, char **argv)
99 r = __remove_entry_from_max_cpu_freq_list(atoi(argv[0]));
101 PRT_TRACE_ERR("Remove entry failed");
105 if (cur_max_cpu_freq == INT_MIN)
106 cur_max_cpu_freq = max_cpu_freq_limit;
108 r = __write_max_cpu_freq(cur_max_cpu_freq);
110 PRT_TRACE_ERR("Write freq failed");
117 int release_min_frequency_action(int argc, char **argv)
124 r = __remove_entry_from_min_cpu_freq_list(atoi(argv[0]));
126 PRT_TRACE_ERR("Remove entry failed");
130 if (cur_min_cpu_freq == INT_MAX)
131 cur_min_cpu_freq = min_cpu_freq_limit;
133 r = __write_min_cpu_freq(cur_min_cpu_freq);
135 PRT_TRACE_ERR("Write entry failed");
142 int ss_cpu_handler_init(void)
146 ss_action_entry_add_internal(PREDEF_SET_MAX_FREQUENCY, set_max_frequency_action, NULL, NULL);
147 ss_action_entry_add_internal(PREDEF_SET_MIN_FREQUENCY, set_min_frequency_action, NULL, NULL);
148 ss_action_entry_add_internal(PREDEF_RELEASE_MAX_FREQUENCY, release_max_frequency_action, NULL, NULL);
149 ss_action_entry_add_internal(PREDEF_RELEASE_MIN_FREQUENCY, release_min_frequency_action, NULL, NULL);
154 static void __set_freq_limit()
158 ret = plugin_intf->OEM_sys_get_cpufreq_cpuinfo_max_freq(&max_cpu_freq_limit);
160 PRT_TRACE_ERR("get cpufreq cpuinfo max readerror: %s", strerror(errno));
161 max_cpu_freq_limit = DEFAULT_MAX_CPU_FREQ;
164 ret = plugin_intf->OEM_sys_get_cpufreq_cpuinfo_min_freq(&min_cpu_freq_limit);
166 PRT_TRACE_ERR("get cpufreq cpuinfo min readerror: %s", strerror(errno));
167 min_cpu_freq_limit = DEFAULT_MIN_CPU_FREQ;
171 static int __is_entry_enable(int pid)
173 char pid_path[PATH_MAX];
175 snprintf(pid_path, PATH_MAX, "/proc/%d", pid);
176 if (access(pid_path, F_OK) < 0) {
183 static int __remove_entry_from_max_cpu_freq_list(int pid)
187 struct cpu_freq_entry *entry;
189 cur_max_cpu_freq = INT_MIN;
191 EINA_LIST_FOREACH_SAFE(max_cpu_freq_list, tmp, tmp_next, entry) {
193 if ((!__is_entry_enable(entry->pid)) || (entry->pid == pid)) {
194 max_cpu_freq_list = eina_list_remove(max_cpu_freq_list, entry);
199 if (entry->freq > cur_max_cpu_freq) {
200 cur_max_cpu_freq = entry->freq;
208 static int __remove_entry_from_min_cpu_freq_list(int pid)
212 struct cpu_freq_entry *entry;
214 cur_min_cpu_freq = INT_MAX;
216 EINA_LIST_FOREACH_SAFE(min_cpu_freq_list, tmp, tmp_next, entry) {
218 if ((!__is_entry_enable(entry->pid)) || (entry->pid == pid)) {
219 min_cpu_freq_list = eina_list_remove(min_cpu_freq_list, entry);
224 if (entry->freq < cur_min_cpu_freq) {
225 cur_min_cpu_freq = entry->freq;
234 static int __add_entry_to_max_cpu_freq_list(int pid, int freq)
237 struct cpu_freq_entry *entry;
239 r = __remove_entry_from_max_cpu_freq_list(pid);
241 PRT_TRACE_ERR("Remove duplicated entry failed");
244 if (freq > cur_max_cpu_freq) {
245 cur_max_cpu_freq = freq;
248 entry = malloc(sizeof(struct cpu_freq_entry));
250 PRT_TRACE_ERR("Malloc failed");
257 max_cpu_freq_list = eina_list_prepend(max_cpu_freq_list, entry);
258 if (!max_cpu_freq_list) {
259 PRT_TRACE_ERR("eina_list_prepend failed");
266 static int __add_entry_to_min_cpu_freq_list(int pid, int freq)
269 struct cpu_freq_entry *entry;
271 r = __remove_entry_from_min_cpu_freq_list(pid);
273 PRT_TRACE_ERR("Remove duplicated entry failed");
276 if (freq < cur_min_cpu_freq) {
277 cur_min_cpu_freq = freq;
280 entry = malloc(sizeof(struct cpu_freq_entry));
282 PRT_TRACE_ERR("Malloc failed");
289 min_cpu_freq_list = eina_list_prepend(min_cpu_freq_list, entry);
290 if (!min_cpu_freq_list) {
291 PRT_TRACE_ERR("eina_list_prepend failed");
298 static int __write_max_cpu_freq(int freq)
302 ret = plugin_intf->OEM_sys_set_cpufreq_scaling_max_freq(freq);
304 PRT_TRACE_ERR("set cpufreq max freq write error: %s", strerror(errno));
311 static int __write_min_cpu_freq(int freq)
315 ret = plugin_intf->OEM_sys_set_cpufreq_scaling_min_freq(freq);
317 PRT_TRACE_ERR("set cpufreq min freq write error: %s", strerror(errno));