summaryrefslogtreecommitdiff
path: root/tools/power/cpupower/utils/cpuidle-set.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/power/cpupower/utils/cpuidle-set.c')
-rw-r--r--tools/power/cpupower/utils/cpuidle-set.c99
1 files changed, 84 insertions, 15 deletions
diff --git a/tools/power/cpupower/utils/cpuidle-set.c b/tools/power/cpupower/utils/cpuidle-set.c
index c78141c5dfac..a551d1d4ac51 100644
--- a/tools/power/cpupower/utils/cpuidle-set.c
+++ b/tools/power/cpupower/utils/cpuidle-set.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
@@ -5,17 +6,19 @@
#include <limits.h>
#include <string.h>
#include <ctype.h>
-
#include <getopt.h>
-#include "cpufreq.h"
+#include <cpufreq.h>
+#include <cpuidle.h>
+
#include "helpers/helpers.h"
-#include "helpers/sysfs.h"
static struct option info_opts[] = {
- { .name = "disable", .has_arg = required_argument, .flag = NULL, .val = 'd'},
- { .name = "enable", .has_arg = required_argument, .flag = NULL, .val = 'e'},
- { },
+ {"disable", required_argument, NULL, 'd'},
+ {"enable", required_argument, NULL, 'e'},
+ {"disable-by-latency", required_argument, NULL, 'D'},
+ {"enable-all", no_argument, NULL, 'E'},
+ { },
};
@@ -23,11 +26,13 @@ int cmd_idle_set(int argc, char **argv)
{
extern char *optarg;
extern int optind, opterr, optopt;
- int ret = 0, cont = 1, param = 0, idlestate = 0;
- unsigned int cpu = 0;
+ int ret = 0, cont = 1, param = 0, disabled;
+ unsigned long long latency = 0, state_latency;
+ unsigned int cpu = 0, idlestate = 0, idlestates = 0;
+ char *endptr;
do {
- ret = getopt_long(argc, argv, "d:e:", info_opts, NULL);
+ ret = getopt_long(argc, argv, "d:e:ED:", info_opts, NULL);
if (ret == -1)
break;
switch (ret) {
@@ -36,22 +41,41 @@ int cmd_idle_set(int argc, char **argv)
cont = 0;
break;
case 'd':
+ case 'e':
if (param) {
param = -1;
cont = 0;
break;
}
param = ret;
- idlestate = atoi(optarg);
+ strtol(optarg, &endptr, 10);
+ if (*endptr != '\0') {
+ printf(_("Bad value: %s, Integer expected\n"), optarg);
+ exit(EXIT_FAILURE);
+ } else {
+ idlestate = atoi(optarg);
+ }
break;
- case 'e':
+ case 'D':
+ if (param) {
+ param = -1;
+ cont = 0;
+ break;
+ }
+ param = ret;
+ latency = strtoull(optarg, &endptr, 10);
+ if (*endptr != '\0') {
+ printf(_("Bad latency value: %s\n"), optarg);
+ exit(EXIT_FAILURE);
+ }
+ break;
+ case 'E':
if (param) {
param = -1;
cont = 0;
break;
}
param = ret;
- idlestate = atoi(optarg);
break;
case -1:
cont = 0;
@@ -69,6 +93,8 @@ int cmd_idle_set(int argc, char **argv)
exit(EXIT_FAILURE);
}
+ get_cpustate();
+
/* Default is: set all CPUs */
if (bitmask_isallclear(cpus_chosen))
bitmask_setall(cpus_chosen);
@@ -79,10 +105,16 @@ int cmd_idle_set(int argc, char **argv)
if (!bitmask_isbitset(cpus_chosen, cpu))
continue;
- switch (param) {
+ if (cpupower_is_cpu_online(cpu) != 1)
+ continue;
+ idlestates = cpuidle_state_count(cpu);
+ if (idlestates <= 0)
+ continue;
+
+ switch (param) {
case 'd':
- ret = sysfs_idlestate_disable(cpu, idlestate, 1);
+ ret = cpuidle_state_disable(cpu, idlestate, 1);
if (ret == 0)
printf(_("Idlestate %u disabled on CPU %u\n"), idlestate, cpu);
else if (ret == -1)
@@ -95,7 +127,7 @@ int cmd_idle_set(int argc, char **argv)
idlestate, cpu);
break;
case 'e':
- ret = sysfs_idlestate_disable(cpu, idlestate, 0);
+ ret = cpuidle_state_disable(cpu, idlestate, 0);
if (ret == 0)
printf(_("Idlestate %u enabled on CPU %u\n"), idlestate, cpu);
else if (ret == -1)
@@ -107,6 +139,41 @@ int cmd_idle_set(int argc, char **argv)
printf(_("Idlestate %u not enabled on CPU %u\n"),
idlestate, cpu);
break;
+ case 'D':
+ for (idlestate = 0; idlestate < idlestates; idlestate++) {
+ disabled = cpuidle_is_state_disabled
+ (cpu, idlestate);
+ state_latency = cpuidle_state_latency
+ (cpu, idlestate);
+ if (disabled == 1) {
+ if (latency > state_latency){
+ ret = cpuidle_state_disable
+ (cpu, idlestate, 0);
+ if (ret == 0)
+ printf(_("Idlestate %u enabled on CPU %u\n"), idlestate, cpu);
+ }
+ continue;
+ }
+ if (latency <= state_latency){
+ ret = cpuidle_state_disable
+ (cpu, idlestate, 1);
+ if (ret == 0)
+ printf(_("Idlestate %u disabled on CPU %u\n"), idlestate, cpu);
+ }
+ }
+ break;
+ case 'E':
+ for (idlestate = 0; idlestate < idlestates; idlestate++) {
+ disabled = cpuidle_is_state_disabled
+ (cpu, idlestate);
+ if (disabled == 1) {
+ ret = cpuidle_state_disable
+ (cpu, idlestate, 0);
+ if (ret == 0)
+ printf(_("Idlestate %u enabled on CPU %u\n"), idlestate, cpu);
+ }
+ }
+ break;
default:
/* Not reachable with proper args checking */
printf(_("Invalid or unknown argument\n"));
@@ -114,5 +181,7 @@ int cmd_idle_set(int argc, char **argv)
break;
}
}
+
+ print_offline_cpus();
return EXIT_SUCCESS;
}