#include "e_system.h" #if defined __OpenBSD__ // no local funcs #elif defined __FreeBSD__ // no local funcs #else static int sys_cpu_setall(const char *control, const char *value) { int num = 0; char buf[4096]; FILE *f; for (;;) { snprintf(buf, sizeof(buf), "/sys/devices/system/cpu/cpu%i/cpufreq/%s", num, control); f = fopen(buf, "w"); if (!f) return num; fprintf(f, "%s", value); fclose(f); num++; } return 0; } static int sys_cpufreq_set(const char *control, const char *value) { char buf[4096]; FILE *f; snprintf(buf, sizeof(buf), "/sys/devices/system/cpu/cpufreq/%s", control); f = fopen(buf, "w"); if (!f) { if (sys_cpu_setall(control, value) > 0) return 1; else return 0; } fprintf(f, "%s", value); fclose(f); return 1; } static int sys_cpu_pstate(int min, int max, int turbo) { FILE *f; f = fopen("/sys/devices/system/cpu/intel_pstate/min_perf_pct", "w"); if (!f) return 0; fprintf(f, "%i", min); fclose(f); f = fopen("/sys/devices/system/cpu/intel_pstate/max_perf_pct", "w"); if (!f) return 0; fprintf(f, "%i", max); fclose(f); f = fopen("/sys/devices/system/cpu/intel_pstate/no_turbo", "w"); if (!f) return 0; fprintf(f, "%i", turbo ? 0 : 1); fclose(f); return 1; } #endif static void _cb_cpufreq_freq(void *data EINA_UNUSED, const char *params) { // FREQ int f = atoi(params); if (f > 0) { #if defined __OpenBSD__ int mib[] = {CTL_HW, HW_SETPERF}; size_t len = sizeof(f); if (sysctl(mib, 2, NULL, 0, &f, len) == 0) { e_system_inout_command_send("cpufreq-freq", "ok"); return; } #elif defined __FreeBSD__ if (sysctlbyname("dev.cpu.0.freq", NULL, NULL, &f, sizeof(f)) == 0) { e_system_inout_command_send("cpufreq-freq", "ok"); return; } #else if (sys_cpu_setall("scaling_setspeed", params) > 0) { e_system_inout_command_send("cpufreq-freq", "ok"); return; } #endif } e_system_inout_command_send("cpufreq-freq", "err"); } static void _cb_cpufreq_governor(void *data EINA_UNUSED, const char *params EINA_UNUSED) { // NAME #if defined __OpenBSD__ e_system_inout_command_send("cpufreq-governor", "err"); #elif defined __FreeBSD__ e_system_inout_command_send("cpufreq-governor", "err"); #else if (sys_cpu_setall("scaling_governor", params) <= 0) { ERR("Unable to open governor interface for writing\n"); e_system_inout_command_send("cpufreq-governor", "err"); } if (!strcmp(params, "ondemand")) sys_cpufreq_set("ondemand/ignore_nice_load", "0"); else if (!strcmp(params, "conservative")) sys_cpufreq_set("conservative/ignore_nice_load", "0"); e_system_inout_command_send("cpufreq-governor", "ok"); #endif } static void _cb_cpufreq_pstate(void *data EINA_UNUSED, const char *params EINA_UNUSED) { // MIN_PERC MAX_PERC TURBO #if defined __OpenBSD__ e_system_inout_command_send("cpufreq-pstate", "err"); #elif defined __FreeBSD__ e_system_inout_command_send("cpufreq-pstate", "err"); #else int min = 0, max = 100, turbo = 1; if (sscanf(params, "%i %i %i", &min, &max, &turbo) == 3) { if (min < 0) min = 0; else if (min > 100) min = 100; if (max < 0) max = 0; else if (max > 100) max = 100; if (turbo < 0) turbo = 0; else if (turbo > 1) turbo = 1; if (sys_cpu_pstate(min, max, turbo) > 0) e_system_inout_command_send("cpufreq-pstate", "ok"); } e_system_inout_command_send("cpufreq-pstate", "err"); #endif } void e_system_cpufreq_init(void) { e_system_inout_command_register("cpufreq-freq", _cb_cpufreq_freq, NULL); e_system_inout_command_register("cpufreq-governor", _cb_cpufreq_governor, NULL); e_system_inout_command_register("cpufreq-pstate", _cb_cpufreq_pstate, NULL); } void e_system_cpufreq_shutdown(void) { // only shutdown things we really have to - no need to free mem etc. }