1 // SPDX-License-Identifier: GPL-2.0 2 #include <unistd.h> 3 #include <stdio.h> 4 #include <errno.h> 5 #include <stdlib.h> 6 #include <limits.h> 7 #include <string.h> 8 #include <ctype.h> 9 #include <getopt.h> 10 11 #include <cpufreq.h> 12 #include <cpuidle.h> 13 14 #include "helpers/helpers.h" 15 16 static struct option info_opts[] = { 17 {"disable", required_argument, NULL, 'd'}, 18 {"enable", required_argument, NULL, 'e'}, 19 {"disable-by-latency", required_argument, NULL, 'D'}, 20 {"enable-all", no_argument, NULL, 'E'}, 21 { }, 22 }; 23 24 25 int cmd_idle_set(int argc, char **argv) 26 { 27 extern char *optarg; 28 extern int optind, opterr, optopt; 29 int ret = 0, cont = 1, param = 0, disabled; 30 unsigned long long latency = 0, state_latency; 31 unsigned int cpu = 0, idlestate = 0, idlestates = 0; 32 char *endptr; 33 34 do { 35 ret = getopt_long(argc, argv, "d:e:ED:", info_opts, NULL); 36 if (ret == -1) 37 break; 38 switch (ret) { 39 case '?': 40 param = '?'; 41 cont = 0; 42 break; 43 case 'd': 44 if (param) { 45 param = -1; 46 cont = 0; 47 break; 48 } 49 param = ret; 50 idlestate = atoi(optarg); 51 break; 52 case 'e': 53 if (param) { 54 param = -1; 55 cont = 0; 56 break; 57 } 58 param = ret; 59 idlestate = atoi(optarg); 60 break; 61 case 'D': 62 if (param) { 63 param = -1; 64 cont = 0; 65 break; 66 } 67 param = ret; 68 latency = strtoull(optarg, &endptr, 10); 69 if (*endptr != '\0') { 70 printf(_("Bad latency value: %s\n"), optarg); 71 exit(EXIT_FAILURE); 72 } 73 break; 74 case 'E': 75 if (param) { 76 param = -1; 77 cont = 0; 78 break; 79 } 80 param = ret; 81 break; 82 case -1: 83 cont = 0; 84 break; 85 } 86 } while (cont); 87 88 switch (param) { 89 case -1: 90 printf(_("You can't specify more than one " 91 "output-specific argument\n")); 92 exit(EXIT_FAILURE); 93 case '?': 94 printf(_("invalid or unknown argument\n")); 95 exit(EXIT_FAILURE); 96 } 97 98 /* Default is: set all CPUs */ 99 if (bitmask_isallclear(cpus_chosen)) 100 bitmask_setall(cpus_chosen); 101 102 for (cpu = bitmask_first(cpus_chosen); 103 cpu <= bitmask_last(cpus_chosen); cpu++) { 104 105 if (!bitmask_isbitset(cpus_chosen, cpu)) 106 continue; 107 108 if (cpupower_is_cpu_online(cpu) != 1) 109 continue; 110 111 idlestates = cpuidle_state_count(cpu); 112 if (idlestates <= 0) 113 continue; 114 115 switch (param) { 116 case 'd': 117 ret = cpuidle_state_disable(cpu, idlestate, 1); 118 if (ret == 0) 119 printf(_("Idlestate %u disabled on CPU %u\n"), idlestate, cpu); 120 else if (ret == -1) 121 printf(_("Idlestate %u not available on CPU %u\n"), 122 idlestate, cpu); 123 else if (ret == -2) 124 printf(_("Idlestate disabling not supported by kernel\n")); 125 else 126 printf(_("Idlestate %u not disabled on CPU %u\n"), 127 idlestate, cpu); 128 break; 129 case 'e': 130 ret = cpuidle_state_disable(cpu, idlestate, 0); 131 if (ret == 0) 132 printf(_("Idlestate %u enabled on CPU %u\n"), idlestate, cpu); 133 else if (ret == -1) 134 printf(_("Idlestate %u not available on CPU %u\n"), 135 idlestate, cpu); 136 else if (ret == -2) 137 printf(_("Idlestate enabling not supported by kernel\n")); 138 else 139 printf(_("Idlestate %u not enabled on CPU %u\n"), 140 idlestate, cpu); 141 break; 142 case 'D': 143 for (idlestate = 0; idlestate < idlestates; idlestate++) { 144 disabled = cpuidle_is_state_disabled 145 (cpu, idlestate); 146 state_latency = cpuidle_state_latency 147 (cpu, idlestate); 148 if (disabled == 1) { 149 if (latency > state_latency){ 150 ret = cpuidle_state_disable 151 (cpu, idlestate, 0); 152 if (ret == 0) 153 printf(_("Idlestate %u enabled on CPU %u\n"), idlestate, cpu); 154 } 155 continue; 156 } 157 if (latency <= state_latency){ 158 ret = cpuidle_state_disable 159 (cpu, idlestate, 1); 160 if (ret == 0) 161 printf(_("Idlestate %u disabled on CPU %u\n"), idlestate, cpu); 162 } 163 } 164 break; 165 case 'E': 166 for (idlestate = 0; idlestate < idlestates; idlestate++) { 167 disabled = cpuidle_is_state_disabled 168 (cpu, idlestate); 169 if (disabled == 1) { 170 ret = cpuidle_state_disable 171 (cpu, idlestate, 0); 172 if (ret == 0) 173 printf(_("Idlestate %u enabled on CPU %u\n"), idlestate, cpu); 174 } 175 } 176 break; 177 default: 178 /* Not reachable with proper args checking */ 179 printf(_("Invalid or unknown argument\n")); 180 exit(EXIT_FAILURE); 181 break; 182 } 183 } 184 return EXIT_SUCCESS; 185 } 186