4 #include <pass/hal-log.h>
9 #include "../shared/sysfs.h"
12 #define HAL_VERSION MAKE_2B_CODE_4(VER_MAJOR,VER_MINOR,VER_REVISION,VER_RELEASE)
13 #define DEV_VERSION_CPU MAKE_2B_CODE_2(1,0)
15 #define CPUFREQ_PATH_PREFIX "/sys/devices/system/cpu/"
16 #define CPUFREQ_CURR_GOVERNOR_PATH_SUFFIX "/cpufreq/scaling_governor"
17 #define CPUFREQ_AVAIL_GOVERNOR_PATH_SUFFIX "/cpufreq/scaling_available_governors"
20 * The cpuinfo_cur_freq indicates the actual operating CPU freqeuncy
21 * and scaling_cur_freq is the CPU frequency set by the CPUFREQ policy.
23 #define CPUFREQ_CURR_FREQ_PATH_SUFFIX "/cpufreq/cpuinfo_cur_freq"
24 #define CPUFREQ_MIN_FREQ_PATH_SUFFIX "/cpufreq/scaling_min_freq"
25 #define CPUFREQ_MAX_FREQ_PATH_SUFFIX "/cpufreq/scaling_max_freq"
26 #define CPUFREQ_UP_THRESHOLD_PATH_SUFFIX "/cpufreq/ondemand/up_threshold"
28 #define LOADTABLE_PATH_PREFIX "/sys/kernel/debug/cpufreq/"
29 #define LOADTABLE_PATH_SUFFIX "/load_table"
31 #define CPU_ONLINE_PATH_PREFIX "/sys/devices/system/cpu/cpu"
32 #define CPU_ONLINE_PATH_SUFFIX "/online"
33 #define CPU_ONLINE_STATE_ON 1
34 #define CPU_ONLINE_STATE_OFF 0
36 #define TMU_PATH_PREFIX "/sys/class/thermal/thermal_zone"
37 #define TMU_TEMP_PATH_SUFFIX "/temp"
38 #define TMU_POLICY_PATH_SUFFIX "/policy"
40 #define TM2_CPU_MIN_NUM 0
41 #define TM2_CPU_MAX_NUM 7
43 #define TM2_CPU_LITTLE_RESNAME "cpu0"
44 #define TM2_CPU_BIG_RESNAME "cpu4"
45 #define TM2_CPU_LITTLE_THERMAL_ZONE_NUM 3
46 #define TM2_CPU_BIG_THERMAL_ZONE_NUM 0
49 static int tm2_dvfs_get_curr_governor(char *res_name, char *governor)
54 if ((!res_name) || (!governor))
57 snprintf(path, PATH_MAX, "%s%s%s",
60 CPUFREQ_CURR_GOVERNOR_PATH_SUFFIX);
62 ret = sysfs_read_str(path, governor, BUFF_MAX);
69 static int tm2_dvfs_set_curr_governor(char *res_name, char *governor)
74 if ((!res_name) || (!governor))
77 snprintf(path, PATH_MAX, "%s%s%s",
80 CPUFREQ_CURR_GOVERNOR_PATH_SUFFIX);
82 ret = sysfs_write_str(path, governor);
89 static int tm2_dvfs_get_curr_freq(char *res_name)
97 snprintf(path, PATH_MAX, "%s%s%s",
100 CPUFREQ_CURR_FREQ_PATH_SUFFIX);
102 ret = sysfs_read_int(path, &freq);
109 static int tm2_dvfs_get_min_freq(char *res_name)
117 snprintf(path, PATH_MAX, "%s%s%s",
120 CPUFREQ_MIN_FREQ_PATH_SUFFIX);
122 ret = sysfs_read_int(path, &freq);
129 static int tm2_dvfs_set_min_freq(char *res_name, int freq)
134 if ((!res_name) || (freq < 0))
137 snprintf(path, PATH_MAX, "%s%s%s",
140 CPUFREQ_MIN_FREQ_PATH_SUFFIX);
142 ret = sysfs_write_int(path, freq);
149 static int tm2_dvfs_get_max_freq(char *res_name)
157 snprintf(path, PATH_MAX, "%s%s%s",
160 CPUFREQ_MAX_FREQ_PATH_SUFFIX);
162 ret = sysfs_read_int(path, &freq);
169 static int tm2_dvfs_set_max_freq(char *res_name, int freq)
174 if ((!res_name) || (freq < 0))
177 snprintf(path, PATH_MAX, "%s%s%s",
180 CPUFREQ_MAX_FREQ_PATH_SUFFIX);
182 ret = sysfs_write_int(path, freq);
188 static int tm2_dvfs_get_up_threshold(char *res_name)
196 snprintf(path, PATH_MAX, "%s%s%s",
199 CPUFREQ_UP_THRESHOLD_PATH_SUFFIX);
201 ret = sysfs_read_int(path, &val);
208 static int tm2_dvfs_set_up_threshold(char *res_name, int up_threshold)
213 if ((!res_name) || (up_threshold < 0))
216 snprintf(path, PATH_MAX, "%s%s%s",
219 CPUFREQ_UP_THRESHOLD_PATH_SUFFIX);
221 ret = sysfs_write_int(path, up_threshold);
228 static int tm2_dvfs_get_load_table(char *res_name, void *pass_cpu_load_table)
233 static struct pass_resource_dvfs_ops tm2_cpu_dvfs_ops = {
234 .get_curr_governor = tm2_dvfs_get_curr_governor,
235 .set_curr_governor = tm2_dvfs_set_curr_governor,
236 .get_avail_governor = NULL,
237 .get_curr_freq = tm2_dvfs_get_curr_freq,
238 .get_min_freq = tm2_dvfs_get_min_freq,
239 .set_min_freq = tm2_dvfs_set_min_freq,
240 .get_max_freq = tm2_dvfs_get_max_freq,
241 .set_max_freq = tm2_dvfs_set_max_freq,
242 .get_up_threshold = tm2_dvfs_get_up_threshold,
243 .set_up_threshold = tm2_dvfs_set_up_threshold,
244 .get_load_table = tm2_dvfs_get_load_table,
247 static int tm2_hotplug_get_online_state(char *res_name, int cpu)
254 if ((cpu < TM2_CPU_MIN_NUM) || (cpu > TM2_CPU_MAX_NUM))
257 snprintf(path, PATH_MAX, "%s%d%s",
258 CPU_ONLINE_PATH_PREFIX,
260 CPU_ONLINE_PATH_SUFFIX);
262 ret = sysfs_read_int(path, &online);
269 static int tm2_hotplug_set_online_state(char *res_name, int cpu, int on)
277 if ((cpu < TM2_CPU_MIN_NUM) || (cpu > TM2_CPU_MAX_NUM))
279 if ((on != CPU_ONLINE_STATE_ON) && (on != CPU_ONLINE_STATE_OFF))
282 /* TODO: Can we turn off CPU0? */
284 snprintf(path, PATH_MAX, "%s%d%s",
285 CPU_ONLINE_PATH_PREFIX,
287 CPU_ONLINE_PATH_SUFFIX);
289 ret = sysfs_write_int(path, on);
296 static struct pass_resource_hotplug_ops tm2_cpu_hotplus_ops = {
297 .get_online_state = tm2_hotplug_get_online_state,
298 .set_online_state = tm2_hotplug_set_online_state,
301 static int tm2_tmu_get_temp(char *res_name)
310 if (!strcmp(res_name, TM2_CPU_LITTLE_RESNAME))
311 tz_num = TM2_CPU_LITTLE_THERMAL_ZONE_NUM;
312 else if (!strcmp(res_name, TM2_CPU_BIG_RESNAME))
313 tz_num = TM2_CPU_BIG_THERMAL_ZONE_NUM;
317 snprintf(path, PATH_MAX, "%s%d%s",
320 TMU_TEMP_PATH_SUFFIX);
322 ret = sysfs_read_int(path, &temp);
329 static int tm2_tmu_get_policy(char *res_name, char *policy)
334 if ((!res_name) || (!policy))
337 if (!strcmp(res_name, TM2_CPU_LITTLE_RESNAME))
338 tz_num = TM2_CPU_LITTLE_THERMAL_ZONE_NUM;
339 else if (!strcmp(res_name, TM2_CPU_BIG_RESNAME))
340 tz_num = TM2_CPU_BIG_THERMAL_ZONE_NUM;
344 snprintf(path, PATH_MAX, "%s%d%s",
347 TMU_POLICY_PATH_SUFFIX);
349 ret = sysfs_read_str(path, policy, BUFF_MAX);
356 static struct pass_resource_tmu_ops tm2_cpu_tmu_ops = {
357 .get_temp = tm2_tmu_get_temp,
358 .get_policy = tm2_tmu_get_policy,
361 static int tm2_cpu_open(struct pass_resource_info *info,
362 struct pass_resource_common **common)
364 struct pass_resource_cpu *cpu_res;
369 /* TODO: Possibility of a memory leak */
370 cpu_res = calloc(1, sizeof(struct pass_resource_cpu));
374 cpu_res->common.info = info;
375 cpu_res->dvfs = tm2_cpu_dvfs_ops;
376 cpu_res->hotplug = tm2_cpu_hotplus_ops;
377 cpu_res->tmu = tm2_cpu_tmu_ops;
379 *common = (struct pass_resource_common *) cpu_res;
384 static int tm2_cpu_close(struct pass_resource_common *common)
394 HAL_MODULE_STRUCTURE = {
395 .magic = HAL_INFO_TAG,
396 .hal_version = HAL_VERSION,
397 .device_version = DEV_VERSION_CPU,
398 .id = PASS_RESOURCE_CPU_ID,
399 .name = PASS_RESOURCE_CPU_NAME,
400 .author = "Wook Song <wook16.song@samsung.com>",
401 .open = tm2_cpu_open,
402 .close = tm2_cpu_close,