Merge branch 'slab/urgent' into slab/next
[pandora-kernel.git] / tools / power / cpupower / utils / cpupower.c
1 /*
2  *  (C) 2010,2011       Thomas Renninger <trenn@suse.de>, Novell Inc.
3  *
4  *  Licensed under the terms of the GNU GPL License version 2.
5  *
6  *  Ideas taken over from the perf userspace tool (included in the Linus
7  *  kernel git repo): subcommand builtins and param parsing.
8  */
9
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <unistd.h>
14
15 #include "builtin.h"
16 #include "helpers/helpers.h"
17 #include "helpers/bitmask.h"
18
19 struct cmd_struct {
20         const char *cmd;
21         int (*main)(int, const char **);
22         void (*usage)(void);
23         int needs_root;
24 };
25
26 #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
27
28 int cmd_help(int argc, const char **argv);
29
30 /* Global cpu_info object available for all binaries
31  * Info only retrieved from CPU 0
32  *
33  * Values will be zero/unknown on non X86 archs
34  */
35 struct cpupower_cpu_info cpupower_cpu_info;
36 int run_as_root;
37 /* Affected cpus chosen by -c/--cpu param */
38 struct bitmask *cpus_chosen;
39
40 #ifdef DEBUG
41 int be_verbose;
42 #endif
43
44 static void print_help(void);
45
46 static struct cmd_struct commands[] = {
47         { "frequency-info",     cmd_freq_info,  freq_info_help, 0       },
48         { "frequency-set",      cmd_freq_set,   freq_set_help,  1       },
49         { "idle-info",          cmd_idle_info,  idle_info_help, 0       },
50         { "set",                cmd_set,        set_help,       1       },
51         { "info",               cmd_info,       info_help,      0       },
52         { "monitor",            cmd_monitor,    monitor_help,   0       },
53         { "help",               cmd_help,       print_help,     0       },
54         /*      { "bench",      cmd_bench,      NULL,           1       }, */
55 };
56
57 int cmd_help(int argc, const char **argv)
58 {
59         unsigned int i;
60
61         if (argc > 1) {
62                 for (i = 0; i < ARRAY_SIZE(commands); i++) {
63                         struct cmd_struct *p = commands + i;
64                         if (strcmp(p->cmd, argv[1]))
65                                 continue;
66                         if (p->usage) {
67                                 p->usage();
68                                 return EXIT_SUCCESS;
69                         }
70                 }
71         }
72         print_help();
73         if (argc == 1)
74                 return EXIT_SUCCESS; /* cpupower help */
75         return EXIT_FAILURE;
76 }
77
78 static void print_help(void)
79 {
80         unsigned int i;
81
82 #ifdef DEBUG
83         printf(_("cpupower [ -d ][ -c cpulist ] subcommand [ARGS]\n"));
84         printf(_("  -d, --debug      May increase output (stderr) on some subcommands\n"));
85 #else
86         printf(_("cpupower [ -c cpulist ] subcommand [ARGS]\n"));
87 #endif
88         printf(_("cpupower --version\n"));
89         printf(_("Supported subcommands are:\n"));
90         for (i = 0; i < ARRAY_SIZE(commands); i++)
91                 printf("\t%s\n", commands[i].cmd);
92         printf(_("\nSome subcommands can make use of the -c cpulist option.\n"));
93         printf(_("Look at the general cpupower manpage how to use it\n"));
94         printf(_("and read up the subcommand's manpage whether it is supported.\n"));
95         printf(_("\nUse cpupower help subcommand for getting help for above subcommands.\n"));
96 }
97
98 static void print_version(void)
99 {
100         printf(PACKAGE " " VERSION "\n");
101         printf(_("Report errors and bugs to %s, please.\n"), PACKAGE_BUGREPORT);
102 }
103
104 static void handle_options(int *argc, const char ***argv)
105 {
106         int ret, x, new_argc = 0;
107
108         if (*argc < 1)
109                 return;
110
111         for (x = 0;  x < *argc && ((*argv)[x])[0] == '-'; x++) {
112                 const char *param = (*argv)[x];
113                 if (!strcmp(param, "-h") || !strcmp(param, "--help")) {
114                         print_help();
115                         exit(EXIT_SUCCESS);
116                 } else if (!strcmp(param, "-c") || !strcmp(param, "--cpu")) {
117                         if (*argc < 2) {
118                                 print_help();
119                                 exit(EXIT_FAILURE);
120                         }
121                         if (!strcmp((*argv)[x+1], "all"))
122                                 bitmask_setall(cpus_chosen);
123                         else {
124                                 ret = bitmask_parselist(
125                                                 (*argv)[x+1], cpus_chosen);
126                                 if (ret < 0) {
127                                         fprintf(stderr, _("Error parsing cpu "
128                                                           "list\n"));
129                                         exit(EXIT_FAILURE);
130                                 }
131                         }
132                         x += 1;
133                         /* Cut out param: cpupower -c 1 info -> cpupower info */
134                         new_argc += 2;
135                         continue;
136                 } else if (!strcmp(param, "-v") ||
137                         !strcmp(param, "--version")) {
138                         print_version();
139                         exit(EXIT_SUCCESS);
140 #ifdef DEBUG
141                 } else if (!strcmp(param, "-d") || !strcmp(param, "--debug")) {
142                         be_verbose = 1;
143                         new_argc++;
144                         continue;
145 #endif
146                 } else {
147                         fprintf(stderr, "Unknown option: %s\n", param);
148                         print_help();
149                         exit(EXIT_FAILURE);
150                 }
151         }
152         *argc -= new_argc;
153         *argv += new_argc;
154 }
155
156 int main(int argc, const char *argv[])
157 {
158         const char *cmd;
159         unsigned int i, ret;
160
161         cpus_chosen = bitmask_alloc(sysconf(_SC_NPROCESSORS_CONF));
162
163         argc--;
164         argv += 1;
165
166         handle_options(&argc, &argv);
167
168         cmd = argv[0];
169
170         if (argc < 1) {
171                 print_help();
172                 return EXIT_FAILURE;
173         }
174
175         setlocale(LC_ALL, "");
176         textdomain(PACKAGE);
177
178         /* Turn "perf cmd --help" into "perf help cmd" */
179         if (argc > 1 && !strcmp(argv[1], "--help")) {
180                 argv[1] = argv[0];
181                 argv[0] = cmd = "help";
182         }
183
184         get_cpu_info(0, &cpupower_cpu_info);
185         run_as_root = !getuid();
186
187         for (i = 0; i < ARRAY_SIZE(commands); i++) {
188                 struct cmd_struct *p = commands + i;
189                 if (strcmp(p->cmd, cmd))
190                         continue;
191                 if (!run_as_root && p->needs_root) {
192                         fprintf(stderr, _("Subcommand %s needs root "
193                                           "privileges\n"), cmd);
194                         return EXIT_FAILURE;
195                 }
196                 ret = p->main(argc, argv);
197                 if (cpus_chosen)
198                         bitmask_free(cpus_chosen);
199                 return ret;
200         }
201         print_help();
202         return EXIT_FAILURE;
203 }