Linux-libre 5.3.12-gnu
[librecmc/linux-libre.git] / tools / power / cpupower / utils / cpuidle-set.c
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 }