162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci 362306a36Sopenharmony_ci#include <stdio.h> 462306a36Sopenharmony_ci#include <errno.h> 562306a36Sopenharmony_ci#include <stdlib.h> 662306a36Sopenharmony_ci#include <string.h> 762306a36Sopenharmony_ci#include <sys/types.h> 862306a36Sopenharmony_ci#include <sys/stat.h> 962306a36Sopenharmony_ci#include <fcntl.h> 1062306a36Sopenharmony_ci#include <unistd.h> 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci#include "cpupower_intern.h" 1362306a36Sopenharmony_ci#include "acpi_cppc.h" 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci/* ACPI CPPC sysfs access ***********************************************/ 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_cistatic int acpi_cppc_read_file(unsigned int cpu, const char *fname, 1862306a36Sopenharmony_ci char *buf, size_t buflen) 1962306a36Sopenharmony_ci{ 2062306a36Sopenharmony_ci char path[SYSFS_PATH_MAX]; 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci snprintf(path, sizeof(path), PATH_TO_CPU "cpu%u/acpi_cppc/%s", 2362306a36Sopenharmony_ci cpu, fname); 2462306a36Sopenharmony_ci return cpupower_read_sysfs(path, buf, buflen); 2562306a36Sopenharmony_ci} 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_cistatic const char * const acpi_cppc_value_files[] = { 2862306a36Sopenharmony_ci [HIGHEST_PERF] = "highest_perf", 2962306a36Sopenharmony_ci [LOWEST_PERF] = "lowest_perf", 3062306a36Sopenharmony_ci [NOMINAL_PERF] = "nominal_perf", 3162306a36Sopenharmony_ci [LOWEST_NONLINEAR_PERF] = "lowest_nonlinear_perf", 3262306a36Sopenharmony_ci [LOWEST_FREQ] = "lowest_freq", 3362306a36Sopenharmony_ci [NOMINAL_FREQ] = "nominal_freq", 3462306a36Sopenharmony_ci [REFERENCE_PERF] = "reference_perf", 3562306a36Sopenharmony_ci [WRAPAROUND_TIME] = "wraparound_time" 3662306a36Sopenharmony_ci}; 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_ciunsigned long acpi_cppc_get_data(unsigned int cpu, enum acpi_cppc_value which) 3962306a36Sopenharmony_ci{ 4062306a36Sopenharmony_ci unsigned long long value; 4162306a36Sopenharmony_ci unsigned int len; 4262306a36Sopenharmony_ci char linebuf[MAX_LINE_LEN]; 4362306a36Sopenharmony_ci char *endp; 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_ci if (which >= MAX_CPPC_VALUE_FILES) 4662306a36Sopenharmony_ci return 0; 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ci len = acpi_cppc_read_file(cpu, acpi_cppc_value_files[which], 4962306a36Sopenharmony_ci linebuf, sizeof(linebuf)); 5062306a36Sopenharmony_ci if (len == 0) 5162306a36Sopenharmony_ci return 0; 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ci value = strtoull(linebuf, &endp, 0); 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_ci if (endp == linebuf || errno == ERANGE) 5662306a36Sopenharmony_ci return 0; 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_ci return value; 5962306a36Sopenharmony_ci} 60