blob: d337cc80a3a60845e8b99db545275d4c09622a34 [file] [log] [blame]
Amit Arora39f29542010-09-14 12:03:22 +05301/*******************************************************************************
Amit Kucheriac0e17fc2011-01-17 09:35:52 +02002 * Copyright (C) 2010, Linaro Limited.
Amit Arora39f29542010-09-14 12:03:22 +05303 *
4 * This file is part of PowerDebug.
5 *
6 * All rights reserved. This program and the accompanying materials
7 * are made available under the terms of the Eclipse Public License v1.0
8 * which accompanies this distribution, and is available at
9 * http://www.eclipse.org/legal/epl-v10.html
10 *
11 * Contributors:
12 * Amit Arora <amit.arora@linaro.org> (IBM Corporation)
13 * - initial API and implementation
14 *******************************************************************************/
15
Amit Arorae9e16b02010-08-03 10:15:20 +053016#include <getopt.h>
Daniel Lezcanoc5afe832011-03-23 14:37:36 +010017#include <stdbool.h>
Daniel Lezcanocac52d92011-03-26 22:05:49 +010018#include "regulator.h"
Amit Arorae9e16b02010-08-03 10:15:20 +053019#include "powerdebug.h"
20
Daniel Lezcano20be6782011-03-26 22:06:03 +010021static int highlighted_row;
Amit Arorae9e16b02010-08-03 10:15:20 +053022
Amit Arora422c52f2010-12-02 16:22:29 +053023void usage(void)
Amit Arorae9e16b02010-08-03 10:15:20 +053024{
Amit Arora422c52f2010-12-02 16:22:29 +053025 printf("Usage: powerdebug [OPTIONS]\n");
26 printf("\n");
27 printf("powerdebug -d [ -r ] [ -s ] [ -c [ -p <clock-name> ] ] "
28 "[ -v ]\n");
29 printf("powerdebug [ -r | -s | -c ]\n");
Amit Arora17552782010-12-02 12:23:14 +053030 printf(" -r, --regulator Show regulator information\n");
31 printf(" -s, --sensor Show sensor information\n");
32 printf(" -c, --clock Show clock information\n");
Amit Arora422c52f2010-12-02 16:22:29 +053033 printf(" -p, --findparents Show all parents for a particular"
Amit Kucheriaa0adae42011-01-12 10:54:23 -060034 " clock\n");
Amit Arora17552782010-12-02 12:23:14 +053035 printf(" -t, --time Set ticktime in seconds (eg. 10.0)\n");
36 printf(" -d, --dump Dump information once (no refresh)\n");
Amit Arora422c52f2010-12-02 16:22:29 +053037 printf(" -v, --verbose Verbose mode (use with -r and/or"
Amit Kucheriaa0adae42011-01-12 10:54:23 -060038 " -s)\n");
Amit Arora17552782010-12-02 12:23:14 +053039 printf(" -V, --version Show Version\n");
40 printf(" -h, --help Help\n");
Amit Arorae9e16b02010-08-03 10:15:20 +053041}
42
Amit Arora17552782010-12-02 12:23:14 +053043void version()
Amit Arorae9e16b02010-08-03 10:15:20 +053044{
Amit Arora17552782010-12-02 12:23:14 +053045 printf("powerdebug version %s\n", VERSION);
Amit Arorae9e16b02010-08-03 10:15:20 +053046}
47
Daniel Lezcano316bcae2011-03-23 14:37:30 +010048/*
49 * Options:
50 * -r, --regulator : regulator
51 * -s, --sensor : sensors
52 * -c, --clock : clocks
53 * -p, --findparents : clockname whose parents have to be found
54 * -t, --time : ticktime
55 * -d, --dump : dump
56 * -v, --verbose : verbose
57 * -V, --version : version
58 * -h, --help : help
59 * no option / default : show usage!
60 */
61
62static struct option long_options[] = {
63 { "regulator", 0, 0, 'r' },
64 { "sensor", 0, 0, 's' },
65 { "clock", 0, 0, 'c' },
66 { "findparents", 1, 0, 'p' },
67 { "time", 1, 0, 't' },
68 { "dump", 0, 0, 'd' },
69 { "verbose", 0, 0, 'v' },
70 { "version", 0, 0, 'V' },
71 { "help", 0, 0, 'h' },
72 { 0, 0, 0, 0 }
73};
74
75struct powerdebug_options {
Daniel Lezcanoc5afe832011-03-23 14:37:36 +010076 bool verbose;
Daniel Lezcanoc5afe832011-03-23 14:37:36 +010077 bool regulators;
78 bool sensors;
79 bool clocks;
Daniel Lezcanoa70d9492011-03-23 14:37:40 +010080 bool dump;
Daniel Lezcanoc5afe832011-03-23 14:37:36 +010081 unsigned int ticktime;
Daniel Lezcano558a6d52011-03-23 14:37:41 +010082 int selectedwindow;
Daniel Lezcano6e0c9c82011-03-26 22:06:07 +010083 char *clkname;
Daniel Lezcano316bcae2011-03-23 14:37:30 +010084};
85
86int getoptions(int argc, char *argv[], struct powerdebug_options *options)
Amit Arorae9e16b02010-08-03 10:15:20 +053087{
Daniel Lezcano316bcae2011-03-23 14:37:30 +010088 int c;
Amit Arorae9e16b02010-08-03 10:15:20 +053089
Daniel Lezcano316bcae2011-03-23 14:37:30 +010090 memset(options, 0, sizeof(*options));
91 options->ticktime = 10;
Daniel Lezcano558a6d52011-03-23 14:37:41 +010092 options->selectedwindow = -1;
Amit Arorae9e16b02010-08-03 10:15:20 +053093
Amit Arorafefe8bf2010-08-05 13:31:20 +053094 while (1) {
95 int optindex = 0;
Amit Arorafefe8bf2010-08-05 13:31:20 +053096
Daniel Lezcano316bcae2011-03-23 14:37:30 +010097 c = getopt_long(argc, argv, "rscp:t:dvVh",
98 long_options, &optindex);
Amit Arorafefe8bf2010-08-05 13:31:20 +053099 if (c == -1)
100 break;
101
102 switch (c) {
Amit Arora6e774cd2010-10-28 11:31:24 +0530103 case 'r':
Daniel Lezcanoc5afe832011-03-23 14:37:36 +0100104 options->regulators = true;
Daniel Lezcano558a6d52011-03-23 14:37:41 +0100105 options->selectedwindow = REGULATOR;
Amit Arora6e774cd2010-10-28 11:31:24 +0530106 break;
107 case 's':
Daniel Lezcanoc5afe832011-03-23 14:37:36 +0100108 options->sensors = true;
Daniel Lezcano558a6d52011-03-23 14:37:41 +0100109 options->selectedwindow = SENSOR;
Amit Arora6e774cd2010-10-28 11:31:24 +0530110 break;
111 case 'c':
Daniel Lezcanoc5afe832011-03-23 14:37:36 +0100112 options->clocks = true;
Daniel Lezcano558a6d52011-03-23 14:37:41 +0100113 options->selectedwindow = CLOCK;
Amit Arora6e774cd2010-10-28 11:31:24 +0530114 break;
Amit Aroraf4fb8102010-11-30 13:55:50 +0530115 case 'p':
Daniel Lezcano6e0c9c82011-03-26 22:06:07 +0100116 options->clkname = strdup(optarg);
117 if (!options->clkname) {
Daniel Lezcano9420fde2011-03-23 14:37:31 +0100118 fprintf(stderr, "failed to allocate memory");
119 return -1;
120 }
Amit Kucheriaeab558a2011-03-25 09:51:41 +0200121 options->dump = true; /* Assume -dc in case of -p */
122 options->clocks = true;
Amit Aroraf4fb8102010-11-30 13:55:50 +0530123 break;
Amit Arora6e774cd2010-10-28 11:31:24 +0530124 case 't':
Daniel Lezcano7f112da2011-03-23 14:37:32 +0100125 options->ticktime = atoi(optarg);
Amit Arora6e774cd2010-10-28 11:31:24 +0530126 break;
127 case 'd':
Daniel Lezcanoa70d9492011-03-23 14:37:40 +0100128 options->dump = true;
Amit Arora6e774cd2010-10-28 11:31:24 +0530129 break;
130 case 'v':
Daniel Lezcanoc5afe832011-03-23 14:37:36 +0100131 options->verbose = true;
Amit Arora6e774cd2010-10-28 11:31:24 +0530132 break;
133 case 'V':
134 version();
135 break;
Amit Arora6e774cd2010-10-28 11:31:24 +0530136 case '?':
Daniel Lezcano316bcae2011-03-23 14:37:30 +0100137 fprintf(stderr, "%s: Unknown option %c'.\n",
Amit Kucheriaa0adae42011-01-12 10:54:23 -0600138 argv[0], optopt);
Amit Arora6e774cd2010-10-28 11:31:24 +0530139 default:
Daniel Lezcano316bcae2011-03-23 14:37:30 +0100140 return -1;
Amit Arorafefe8bf2010-08-05 13:31:20 +0530141 }
Amit Arorae9e16b02010-08-03 10:15:20 +0530142 }
Amit Aroraa06a7302010-12-02 15:59:37 +0530143
Daniel Lezcanoc9c14622011-03-26 22:06:10 +0100144 if (options->dump) {
145
146 /* No system specified to be dump, let's default to all */
147 if (!options->regulators &&
148 !options->clocks &&
149 !options->sensors) {
150 options->regulators = options->clocks =
151 options->sensors = true;
152
153 return 0;
154 }
155
Amit Aroraa06a7302010-12-02 15:59:37 +0530156 }
Amit Arorafefe8bf2010-08-05 13:31:20 +0530157
Daniel Lezcanoc9c14622011-03-26 22:06:10 +0100158 if (options->selectedwindow == -1)
Daniel Lezcano558a6d52011-03-23 14:37:41 +0100159 options->selectedwindow = CLOCK;
Amit Arorae9e16b02010-08-03 10:15:20 +0530160
Daniel Lezcano316bcae2011-03-23 14:37:30 +0100161 return 0;
162}
163
Daniel Lezcanoc5afe832011-03-23 14:37:36 +0100164int keystroke_callback(bool *enter_hit, bool *findparent_ncurses,
165 char *clkname_str, bool *refreshwin,
Daniel Lezcano60a41022011-03-23 14:37:35 +0100166 struct powerdebug_options *options)
167{
168 char keychar;
169 int keystroke = getch();
Daniel Lezcano558a6d52011-03-23 14:37:41 +0100170 int oldselectedwin = options->selectedwindow;
Daniel Lezcano60a41022011-03-23 14:37:35 +0100171
172 if (keystroke == EOF)
173 exit(0);
174
175 if (keystroke == KEY_RIGHT || keystroke == 9)
Daniel Lezcano558a6d52011-03-23 14:37:41 +0100176 options->selectedwindow++;
Daniel Lezcano60a41022011-03-23 14:37:35 +0100177
178 if (keystroke == KEY_LEFT || keystroke == 353)
Daniel Lezcano558a6d52011-03-23 14:37:41 +0100179 options->selectedwindow--;
Daniel Lezcano60a41022011-03-23 14:37:35 +0100180
Daniel Lezcano558a6d52011-03-23 14:37:41 +0100181 if (options->selectedwindow >= TOTAL_FEATURE_WINS)
182 options->selectedwindow = 0;
Daniel Lezcano60a41022011-03-23 14:37:35 +0100183
Daniel Lezcano558a6d52011-03-23 14:37:41 +0100184 if (options->selectedwindow < 0)
185 options->selectedwindow = TOTAL_FEATURE_WINS - 1;
Daniel Lezcano60a41022011-03-23 14:37:35 +0100186
Daniel Lezcano558a6d52011-03-23 14:37:41 +0100187 if (options->selectedwindow == CLOCK) {
Daniel Lezcano60a41022011-03-23 14:37:35 +0100188 if (keystroke == KEY_DOWN)
189 highlighted_row++;
190 if (keystroke == KEY_UP && highlighted_row > 0)
191 highlighted_row--;
192 if (keystroke == 47)
Daniel Lezcanoc5afe832011-03-23 14:37:36 +0100193 *findparent_ncurses = true;
Daniel Lezcano60a41022011-03-23 14:37:35 +0100194
195 if ((keystroke == 27 || oldselectedwin !=
Daniel Lezcano558a6d52011-03-23 14:37:41 +0100196 options->selectedwindow) && *findparent_ncurses) {
Daniel Lezcanoc5afe832011-03-23 14:37:36 +0100197 *findparent_ncurses = false;
Daniel Lezcano60a41022011-03-23 14:37:35 +0100198 clkname_str[0] = '\0';
199 }
200
201 if (*findparent_ncurses && keystroke != 13) {
202 int len = strlen(clkname_str);
203 char str[2];
204
205 if (keystroke == 263) {
206 if (len > 0)
207 len--;
208
209 clkname_str[len] = '\0';
210 } else {
211 if (strlen(clkname_str) ||
212 keystroke != '/') {
213 str[0] = keystroke;
214 str[1] = '\0';
215 if (len < 63)
216 strcat(clkname_str,
217 str);
218 }
219 }
220 }
221 }
222
223 keychar = toupper(keystroke);
224//#define DEBUG
225#ifdef DEBUG
226 killall_windows(1); fini_curses();
227 printf("key entered %d:%c\n", keystroke, keychar);
228 exit(1);
229#endif
230
231 if (keystroke == 13)
Daniel Lezcanoc5afe832011-03-23 14:37:36 +0100232 *enter_hit = true;
Daniel Lezcano60a41022011-03-23 14:37:35 +0100233
234 if (keychar == 'Q' && !*findparent_ncurses)
235 return 1;
236 if (keychar == 'R') {
Daniel Lezcanoc5afe832011-03-23 14:37:36 +0100237 *refreshwin = true;
Daniel Lezcano60a41022011-03-23 14:37:35 +0100238 options->ticktime = 3;
239 } else
Daniel Lezcanoc5afe832011-03-23 14:37:36 +0100240 *refreshwin = false;
Daniel Lezcano60a41022011-03-23 14:37:35 +0100241
242 return 0;
243}
244
Daniel Lezcano08198262011-03-26 22:06:02 +0100245int mainloop(struct powerdebug_options *options,
246 struct regulator_info *reg_info, int nr_reg)
Daniel Lezcano316bcae2011-03-23 14:37:30 +0100247{
Daniel Lezcanoc5afe832011-03-23 14:37:36 +0100248 bool findparent_ncurses = false;
249 bool refreshwin = false;
250 bool enter_hit = false;
Daniel Lezcano316bcae2011-03-23 14:37:30 +0100251 int firsttime[TOTAL_FEATURE_WINS];
Daniel Lezcano0051f4f2011-03-23 14:37:34 +0100252 int i;
Daniel Lezcano316bcae2011-03-23 14:37:30 +0100253 char clkname_str[64];
Daniel Lezcano316bcae2011-03-23 14:37:30 +0100254
255 for (i = 0; i < TOTAL_FEATURE_WINS; i++)
256 firsttime[i] = 1;
257
Amit Kucheriaa0adae42011-01-12 10:54:23 -0600258 while (1) {
Amit Arora47fd9182010-08-24 13:26:06 +0530259 int key = 0;
260 struct timeval tval;
261 fd_set readfds;
Amit Arorae9e16b02010-08-03 10:15:20 +0530262
Daniel Lezcanob5746712011-03-26 22:06:05 +0100263 if (firsttime[0])
264 init_curses();
265 create_windows(options->selectedwindow);
266 show_header(options->selectedwindow);
Amit Aroraac4e8652010-11-09 11:16:53 +0530267
Daniel Lezcano558a6d52011-03-23 14:37:41 +0100268 if (options->regulators || options->selectedwindow == REGULATOR) {
Daniel Lezcano08198262011-03-26 22:06:02 +0100269 regulator_read_info(reg_info, nr_reg);
Daniel Lezcanob5746712011-03-26 22:06:05 +0100270 create_selectedwindow(options->selectedwindow);
271 show_regulator_info(reg_info, nr_reg,
272 options->verbose);
Amit Arora47fd9182010-08-24 13:26:06 +0530273 }
274
Daniel Lezcano558a6d52011-03-23 14:37:41 +0100275 if (options->clocks || options->selectedwindow == CLOCK) {
Amit Arora04f97742010-11-16 11:28:57 +0530276 int ret = 0;
Amit Arora6e774cd2010-10-28 11:31:24 +0530277 if (firsttime[CLOCK]) {
Daniel Lezcano558a6d52011-03-23 14:37:41 +0100278 ret = init_clock_details(options->dump,
279 options->selectedwindow);
Amit Arora04f97742010-11-16 11:28:57 +0530280 if (!ret)
281 firsttime[CLOCK] = 0;
Amit Arora3bd79162010-12-01 13:51:42 +0530282 strcpy(clkname_str, "");
Amit Arora6e774cd2010-10-28 11:31:24 +0530283 }
Daniel Lezcanob5746712011-03-26 22:06:05 +0100284 if (!ret) {
Amit Arora6e774cd2010-10-28 11:31:24 +0530285 int hrow;
Amit Arora0e512722010-10-01 12:24:16 +0530286
Daniel Lezcano558a6d52011-03-23 14:37:41 +0100287 create_selectedwindow(options->selectedwindow);
Amit Arora3bd79162010-12-01 13:51:42 +0530288 if (!findparent_ncurses) {
Amit Aroraa06a7302010-12-02 15:59:37 +0530289 int command = 0;
290
291 if (enter_hit)
292 command = CLOCK_SELECTED;
293 if (refreshwin)
294 command = REFRESH_WINDOW;
Amit Arora3bd79162010-12-01 13:51:42 +0530295 hrow = read_and_print_clock_info(
Daniel Lezcano316bcae2011-03-23 14:37:30 +0100296 options->verbose,
Amit Kucheriaa0adae42011-01-12 10:54:23 -0600297 highlighted_row,
298 command);
Amit Arora3bd79162010-12-01 13:51:42 +0530299 highlighted_row = hrow;
Daniel Lezcanoc5afe832011-03-23 14:37:36 +0100300 enter_hit = false;
Amit Arora3bd79162010-12-01 13:51:42 +0530301 } else
302 find_parents_for_clock(clkname_str,
Daniel Lezcano897f7332011-03-26 22:06:06 +0100303 enter_hit);
Amit Arora04f97742010-11-16 11:28:57 +0530304 }
Amit Arora6e774cd2010-10-28 11:31:24 +0530305 }
Amit Arora47fd9182010-08-24 13:26:06 +0530306
Daniel Lezcano558a6d52011-03-23 14:37:41 +0100307 if (options->sensors || options->selectedwindow == SENSOR) {
Daniel Lezcanob5746712011-03-26 22:06:05 +0100308 create_selectedwindow(options->selectedwindow);
309 print_sensor_header();
Amit Arora47fd9182010-08-24 13:26:06 +0530310 }
311
Amit Arora47fd9182010-08-24 13:26:06 +0530312 FD_ZERO(&readfds);
313 FD_SET(0, &readfds);
Daniel Lezcano316bcae2011-03-23 14:37:30 +0100314 tval.tv_sec = options->ticktime;
315 tval.tv_usec = (options->ticktime - tval.tv_sec) * 1000000;
Amit Arora47fd9182010-08-24 13:26:06 +0530316
317 key = select(1, &readfds, NULL, NULL, &tval);
Daniel Lezcano60a41022011-03-23 14:37:35 +0100318 if (!key)
319 continue;
Amit Arora47fd9182010-08-24 13:26:06 +0530320
Daniel Lezcano60a41022011-03-23 14:37:35 +0100321 if (keystroke_callback(&enter_hit, &findparent_ncurses,
322 clkname_str, &refreshwin, options))
323 break;
Amit Arora97006e52010-10-28 11:56:08 +0530324
Amit Arorae9e16b02010-08-03 10:15:20 +0530325 }
Daniel Lezcano0051f4f2011-03-23 14:37:34 +0100326
327 return 0;
328}
329
Daniel Lezcano21c04d42011-03-26 22:06:04 +0100330static int powerdebug_dump(struct powerdebug_options *options,
331 struct regulator_info *reg_info, int nr_reg)
332{
Daniel Lezcanob5746712011-03-26 22:06:05 +0100333 if (options->regulators) {
334 regulator_read_info(reg_info, nr_reg);
335 regulator_print_info(reg_info, nr_reg, options->verbose);
336 }
337
338 if (options->clocks) {
339 init_clock_details(options->dump, options->selectedwindow);
340
Daniel Lezcano6e0c9c82011-03-26 22:06:07 +0100341 if (options->clkname)
342 read_and_dump_clock_info_one(options->clkname,
Daniel Lezcanob5746712011-03-26 22:06:05 +0100343 options->dump);
344 else
345 read_and_dump_clock_info(options->verbose);
346 }
347
348 if (options->sensors)
349 read_and_print_sensor_info(options->verbose);
350
Daniel Lezcano21c04d42011-03-26 22:06:04 +0100351 return 0;
352}
353
Daniel Lezcano6e0c9c82011-03-26 22:06:07 +0100354static struct powerdebug_options *powerdebug_init(void)
355{
356 struct powerdebug_options *options;
357
358 options = malloc(sizeof(*options));
359 if (!options)
360 return NULL;
361
362 memset(options, 0, sizeof(*options));
363
364 return options;
365}
366
Daniel Lezcano0051f4f2011-03-23 14:37:34 +0100367int main(int argc, char **argv)
368{
369 struct powerdebug_options *options;
Daniel Lezcano08198262011-03-26 22:06:02 +0100370 struct regulator_info *regulators_info;
371 int numregulators;
Daniel Lezcano0051f4f2011-03-23 14:37:34 +0100372
Daniel Lezcano6e0c9c82011-03-26 22:06:07 +0100373 options = powerdebug_init();
Daniel Lezcano0051f4f2011-03-23 14:37:34 +0100374 if (!options) {
Daniel Lezcano6e0c9c82011-03-26 22:06:07 +0100375 fprintf(stderr, "not enough memory to allocate options\n");
Daniel Lezcano0051f4f2011-03-23 14:37:34 +0100376 return 1;
377 }
378
Daniel Lezcano4aab2fe2011-03-26 22:05:53 +0100379 regulators_info = regulator_init(&numregulators);
380 if (!regulators_info) {
381 printf("not enough memory to allocate regulators info\n");
Daniel Lezcano0051f4f2011-03-23 14:37:34 +0100382 return 1;
Daniel Lezcano4aab2fe2011-03-26 22:05:53 +0100383 }
Daniel Lezcano0051f4f2011-03-23 14:37:34 +0100384
Daniel Lezcano6e0c9c82011-03-26 22:06:07 +0100385 if (getoptions(argc, argv, options)) {
386 usage();
387 return 1;
388 }
389
Daniel Lezcano21c04d42011-03-26 22:06:04 +0100390 /* we just dump the informations */
391 if (options->dump) {
392 if (powerdebug_dump(options, regulators_info, numregulators))
393 return 1;
394 return 0;
395 }
396
Daniel Lezcano08198262011-03-26 22:06:02 +0100397 if (mainloop(options, regulators_info, numregulators))
Daniel Lezcano0051f4f2011-03-23 14:37:34 +0100398 return 1;
399
400 return 0;
Amit Arorae9e16b02010-08-03 10:15:20 +0530401}