Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *  (C) 2004-2009  Dominik Brodowski <linux@dominikbrodowski.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *  (C) 2010       Thomas Renninger <trenn@suse.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <unistd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <stdio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <stdlib.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <getopt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <cpuidle.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include "helpers/sysfs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include "helpers/helpers.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include "helpers/bitmask.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #define LINE_LEN 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) static void cpuidle_cpu_output(unsigned int cpu, int verbose)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 	unsigned int idlestates, idlestate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 	char *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 	idlestates = cpuidle_state_count(cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 	if (idlestates == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 		printf(_("CPU %u: No idle states\n"), cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	printf(_("Number of idle states: %d\n"), idlestates);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	printf(_("Available idle states:"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 	for (idlestate = 0; idlestate < idlestates; idlestate++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 		tmp = cpuidle_state_name(cpu, idlestate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 		if (!tmp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 		printf(" %s", tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 		free(tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	printf("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	if (!verbose)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	for (idlestate = 0; idlestate < idlestates; idlestate++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 		int disabled = cpuidle_is_state_disabled(cpu, idlestate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 		/* Disabled interface not supported on older kernels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 		if (disabled < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 			disabled = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 		tmp = cpuidle_state_name(cpu, idlestate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 		if (!tmp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 		printf("%s%s:\n", tmp, (disabled) ? " (DISABLED) " : "");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 		free(tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 		tmp = cpuidle_state_desc(cpu, idlestate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 		if (!tmp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 		printf(_("Flags/Description: %s\n"), tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 		free(tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 		printf(_("Latency: %lu\n"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 		       cpuidle_state_latency(cpu, idlestate));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 		printf(_("Usage: %lu\n"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 		       cpuidle_state_usage(cpu, idlestate));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 		printf(_("Duration: %llu\n"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 		       cpuidle_state_time(cpu, idlestate));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) static void cpuidle_general_output(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	char *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	tmp = cpuidle_get_driver();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	if (!tmp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 		printf(_("Could not determine cpuidle driver\n"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	printf(_("CPUidle driver: %s\n"), tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	free(tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	tmp = cpuidle_get_governor();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	if (!tmp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 		printf(_("Could not determine cpuidle governor\n"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	printf(_("CPUidle governor: %s\n"), tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	free(tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) static void proc_cpuidle_cpu_output(unsigned int cpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	long max_allowed_cstate = 2000000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	unsigned int cstate, cstates;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	cstates = cpuidle_state_count(cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	if (cstates == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 		printf(_("CPU %u: No C-states info\n"), cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	printf(_("active state:            C0\n"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	printf(_("max_cstate:              C%u\n"), cstates-1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	printf(_("maximum allowed latency: %lu usec\n"), max_allowed_cstate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	printf(_("states:\t\n"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	for (cstate = 1; cstate < cstates; cstate++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 		printf(_("    C%d:                  "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 			 "type[C%d] "), cstate, cstate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 		printf(_("promotion[--] demotion[--] "));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 		printf(_("latency[%03lu] "),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 		       cpuidle_state_latency(cpu, cstate));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 		printf(_("usage[%08lu] "),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 		       cpuidle_state_usage(cpu, cstate));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 		printf(_("duration[%020Lu] \n"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 		       cpuidle_state_time(cpu, cstate));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) static struct option info_opts[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	{"silent", no_argument, NULL, 's'},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	{"proc", no_argument, NULL, 'o'},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	{ },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) static inline void cpuidle_exit(int fail)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	exit(EXIT_FAILURE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) int cmd_idle_info(int argc, char **argv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	extern char *optarg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	extern int optind, opterr, optopt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	int ret = 0, cont = 1, output_param = 0, verbose = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	unsigned int cpu = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 		ret = getopt_long(argc, argv, "os", info_opts, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 		if (ret == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 		switch (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 		case '?':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 			output_param = '?';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 			cont = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 		case 's':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 			verbose = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 		case -1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 			cont = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 		case 'o':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 			if (output_param) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 				output_param = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 				cont = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 			output_param = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	} while (cont);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	switch (output_param) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	case -1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 		printf(_("You can't specify more than one "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 			 "output-specific argument\n"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 		cpuidle_exit(EXIT_FAILURE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	case '?':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 		printf(_("invalid or unknown argument\n"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 		cpuidle_exit(EXIT_FAILURE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	/* Default is: show output of CPU 0 only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	if (bitmask_isallclear(cpus_chosen))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 		bitmask_setbit(cpus_chosen, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	if (output_param == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 		cpuidle_general_output();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	for (cpu = bitmask_first(cpus_chosen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	     cpu <= bitmask_last(cpus_chosen); cpu++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 		if (!bitmask_isbitset(cpus_chosen, cpu))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 		printf(_("analyzing CPU %d:\n"), cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 		if (sysfs_is_cpu_online(cpu) != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 			printf(_(" *is offline\n"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 			printf("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 		switch (output_param) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 		case 'o':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 			proc_cpuidle_cpu_output(cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 		case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 			printf("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 			cpuidle_cpu_output(cpu, verbose);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 		printf("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	return EXIT_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) }