xref: /dpdk/lib/power/power_common.c (revision 99a2dd955fba6e4cc23b77d590a033650ced9c45)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2020 Intel Corporation
3  */
4 
5 #include <limits.h>
6 #include <stdio.h>
7 #include <string.h>
8 
9 #include "power_common.h"
10 
11 #define POWER_SYSFILE_SCALING_DRIVER   \
12 		"/sys/devices/system/cpu/cpu%u/cpufreq/scaling_driver"
13 
14 int
15 cpufreq_check_scaling_driver(const char *driver_name)
16 {
17 	unsigned int lcore_id = 0; /* always check core 0 */
18 	char fullpath[PATH_MAX];
19 	char readbuf[PATH_MAX];
20 	size_t end_idx;
21 	char *s;
22 	FILE *f;
23 
24 	/*
25 	 * Check if scaling driver matches what we expect.
26 	 */
27 	snprintf(fullpath, sizeof(fullpath), POWER_SYSFILE_SCALING_DRIVER,
28 			lcore_id);
29 	f = fopen(fullpath, "r");
30 
31 	/* if there's no driver at all, bail out */
32 	if (f == NULL)
33 		return 0;
34 
35 	s = fgets(readbuf, sizeof(readbuf), f);
36 	/* don't need it any more */
37 	fclose(f);
38 
39 	/* if we can't read it, consider unsupported */
40 	if (s == NULL)
41 		return 0;
42 
43 	/* when read from sysfs, driver name has an extra newline at the end */
44 	end_idx = strnlen(readbuf, sizeof(readbuf));
45 	if (end_idx > 0 && readbuf[end_idx - 1] == '\n') {
46 		end_idx--;
47 		readbuf[end_idx] = '\0';
48 	}
49 
50 	/* does the driver name match? */
51 	if (strncmp(readbuf, driver_name, sizeof(readbuf)) != 0)
52 		return 0;
53 
54 	/*
55 	 * We might have a situation where the driver is supported, but we don't
56 	 * have permissions to do frequency scaling. This error should not be
57 	 * handled here, so consider the system to support scaling for now.
58 	 */
59 	return 1;
60 }
61