blob: 6dd4b8c8231d7da556dedc868dce987084056ac8 [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
Amit Arora728e0c92010-09-14 12:06:09 +053021int highlighted_row;
Amit Arorae9e16b02010-08-03 10:15:20 +053022
Daniel Lezcano691d5562011-03-26 22:05:57 +010023static struct regulator_info *regulators_info;
Daniel Lezcanoa9fff862011-03-26 22:06:01 +010024static int numregulators;
Daniel Lezcano691d5562011-03-26 22:05:57 +010025
Amit Arora422c52f2010-12-02 16:22:29 +053026void usage(void)
Amit Arorae9e16b02010-08-03 10:15:20 +053027{
Amit Arora422c52f2010-12-02 16:22:29 +053028 printf("Usage: powerdebug [OPTIONS]\n");
29 printf("\n");
30 printf("powerdebug -d [ -r ] [ -s ] [ -c [ -p <clock-name> ] ] "
31 "[ -v ]\n");
32 printf("powerdebug [ -r | -s | -c ]\n");
Amit Arora17552782010-12-02 12:23:14 +053033 printf(" -r, --regulator Show regulator information\n");
34 printf(" -s, --sensor Show sensor information\n");
35 printf(" -c, --clock Show clock information\n");
Amit Arora422c52f2010-12-02 16:22:29 +053036 printf(" -p, --findparents Show all parents for a particular"
Amit Kucheriaa0adae42011-01-12 10:54:23 -060037 " clock\n");
Amit Arora17552782010-12-02 12:23:14 +053038 printf(" -t, --time Set ticktime in seconds (eg. 10.0)\n");
39 printf(" -d, --dump Dump information once (no refresh)\n");
Amit Arora422c52f2010-12-02 16:22:29 +053040 printf(" -v, --verbose Verbose mode (use with -r and/or"
Amit Kucheriaa0adae42011-01-12 10:54:23 -060041 " -s)\n");
Amit Arora17552782010-12-02 12:23:14 +053042 printf(" -V, --version Show Version\n");
43 printf(" -h, --help Help\n");
Amit Arorae9e16b02010-08-03 10:15:20 +053044}
45
Amit Arora17552782010-12-02 12:23:14 +053046void version()
Amit Arorae9e16b02010-08-03 10:15:20 +053047{
Amit Arora17552782010-12-02 12:23:14 +053048 printf("powerdebug version %s\n", VERSION);
Amit Arorae9e16b02010-08-03 10:15:20 +053049}
50
Daniel Lezcano316bcae2011-03-23 14:37:30 +010051/*
52 * Options:
53 * -r, --regulator : regulator
54 * -s, --sensor : sensors
55 * -c, --clock : clocks
56 * -p, --findparents : clockname whose parents have to be found
57 * -t, --time : ticktime
58 * -d, --dump : dump
59 * -v, --verbose : verbose
60 * -V, --version : version
61 * -h, --help : help
62 * no option / default : show usage!
63 */
64
65static struct option long_options[] = {
66 { "regulator", 0, 0, 'r' },
67 { "sensor", 0, 0, 's' },
68 { "clock", 0, 0, 'c' },
69 { "findparents", 1, 0, 'p' },
70 { "time", 1, 0, 't' },
71 { "dump", 0, 0, 'd' },
72 { "verbose", 0, 0, 'v' },
73 { "version", 0, 0, 'V' },
74 { "help", 0, 0, 'h' },
75 { 0, 0, 0, 0 }
76};
77
78struct powerdebug_options {
Daniel Lezcanoc5afe832011-03-23 14:37:36 +010079 bool verbose;
80 bool findparent;
81 bool regulators;
82 bool sensors;
83 bool clocks;
Daniel Lezcanoa70d9492011-03-23 14:37:40 +010084 bool dump;
Daniel Lezcanoc5afe832011-03-23 14:37:36 +010085 unsigned int ticktime;
Daniel Lezcano558a6d52011-03-23 14:37:41 +010086 int selectedwindow;
Daniel Lezcano9420fde2011-03-23 14:37:31 +010087 char *clkarg;
Daniel Lezcano316bcae2011-03-23 14:37:30 +010088};
89
90int getoptions(int argc, char *argv[], struct powerdebug_options *options)
Amit Arorae9e16b02010-08-03 10:15:20 +053091{
Daniel Lezcano316bcae2011-03-23 14:37:30 +010092 int c;
Amit Arorae9e16b02010-08-03 10:15:20 +053093
Daniel Lezcano316bcae2011-03-23 14:37:30 +010094 memset(options, 0, sizeof(*options));
95 options->ticktime = 10;
Daniel Lezcano558a6d52011-03-23 14:37:41 +010096 options->selectedwindow = -1;
Amit Arorae9e16b02010-08-03 10:15:20 +053097
Amit Arorafefe8bf2010-08-05 13:31:20 +053098 while (1) {
99 int optindex = 0;
Amit Arorafefe8bf2010-08-05 13:31:20 +0530100
Daniel Lezcano316bcae2011-03-23 14:37:30 +0100101 c = getopt_long(argc, argv, "rscp:t:dvVh",
102 long_options, &optindex);
Amit Arorafefe8bf2010-08-05 13:31:20 +0530103 if (c == -1)
104 break;
105
106 switch (c) {
Amit Arora6e774cd2010-10-28 11:31:24 +0530107 case 'r':
Daniel Lezcanoc5afe832011-03-23 14:37:36 +0100108 options->regulators = true;
Daniel Lezcano558a6d52011-03-23 14:37:41 +0100109 options->selectedwindow = REGULATOR;
Amit Arora6e774cd2010-10-28 11:31:24 +0530110 break;
111 case 's':
Daniel Lezcanoc5afe832011-03-23 14:37:36 +0100112 options->sensors = true;
Daniel Lezcano558a6d52011-03-23 14:37:41 +0100113 options->selectedwindow = SENSOR;
Amit Arora6e774cd2010-10-28 11:31:24 +0530114 break;
115 case 'c':
Daniel Lezcanoc5afe832011-03-23 14:37:36 +0100116 options->clocks = true;
Daniel Lezcano558a6d52011-03-23 14:37:41 +0100117 options->selectedwindow = CLOCK;
Amit Arora6e774cd2010-10-28 11:31:24 +0530118 break;
Amit Aroraf4fb8102010-11-30 13:55:50 +0530119 case 'p':
Daniel Lezcanoc5afe832011-03-23 14:37:36 +0100120 options->findparent = true;
Daniel Lezcano9420fde2011-03-23 14:37:31 +0100121 options->clkarg = strdup(optarg);
122 if (!options->clkarg) {
123 fprintf(stderr, "failed to allocate memory");
124 return -1;
125 }
Amit Kucheriaeab558a2011-03-25 09:51:41 +0200126 options->dump = true; /* Assume -dc in case of -p */
127 options->clocks = true;
Amit Aroraf4fb8102010-11-30 13:55:50 +0530128 break;
Amit Arora6e774cd2010-10-28 11:31:24 +0530129 case 't':
Daniel Lezcano7f112da2011-03-23 14:37:32 +0100130 options->ticktime = atoi(optarg);
Amit Arora6e774cd2010-10-28 11:31:24 +0530131 break;
132 case 'd':
Daniel Lezcanoa70d9492011-03-23 14:37:40 +0100133 options->dump = true;
Amit Arora6e774cd2010-10-28 11:31:24 +0530134 break;
135 case 'v':
Daniel Lezcanoc5afe832011-03-23 14:37:36 +0100136 options->verbose = true;
Amit Arora6e774cd2010-10-28 11:31:24 +0530137 break;
138 case 'V':
139 version();
140 break;
Amit Arora6e774cd2010-10-28 11:31:24 +0530141 case '?':
Daniel Lezcano316bcae2011-03-23 14:37:30 +0100142 fprintf(stderr, "%s: Unknown option %c'.\n",
Amit Kucheriaa0adae42011-01-12 10:54:23 -0600143 argv[0], optopt);
Amit Arora6e774cd2010-10-28 11:31:24 +0530144 default:
Daniel Lezcano316bcae2011-03-23 14:37:30 +0100145 return -1;
Amit Arorafefe8bf2010-08-05 13:31:20 +0530146 }
Amit Arorae9e16b02010-08-03 10:15:20 +0530147 }
Amit Aroraa06a7302010-12-02 15:59:37 +0530148
Daniel Lezcanoa70d9492011-03-23 14:37:40 +0100149 if (options->dump && !(options->regulators ||
Daniel Lezcano316bcae2011-03-23 14:37:30 +0100150 options->clocks || options->sensors)) {
151 /* By Default lets show everything we have */
Daniel Lezcanoc5afe832011-03-23 14:37:36 +0100152 options->regulators = options->clocks = options->sensors = true;
Amit Aroraa06a7302010-12-02 15:59:37 +0530153 }
Amit Arorafefe8bf2010-08-05 13:31:20 +0530154
Daniel Lezcano558a6d52011-03-23 14:37:41 +0100155 if (!options->dump && options->selectedwindow == -1)
156 options->selectedwindow = CLOCK;
Amit Arorae9e16b02010-08-03 10:15:20 +0530157
Daniel Lezcano316bcae2011-03-23 14:37:30 +0100158 return 0;
159}
160
Daniel Lezcanoc5afe832011-03-23 14:37:36 +0100161int keystroke_callback(bool *enter_hit, bool *findparent_ncurses,
162 char *clkname_str, bool *refreshwin,
Daniel Lezcano60a41022011-03-23 14:37:35 +0100163 struct powerdebug_options *options)
164{
165 char keychar;
166 int keystroke = getch();
Daniel Lezcano558a6d52011-03-23 14:37:41 +0100167 int oldselectedwin = options->selectedwindow;
Daniel Lezcano60a41022011-03-23 14:37:35 +0100168
169 if (keystroke == EOF)
170 exit(0);
171
172 if (keystroke == KEY_RIGHT || keystroke == 9)
Daniel Lezcano558a6d52011-03-23 14:37:41 +0100173 options->selectedwindow++;
Daniel Lezcano60a41022011-03-23 14:37:35 +0100174
175 if (keystroke == KEY_LEFT || keystroke == 353)
Daniel Lezcano558a6d52011-03-23 14:37:41 +0100176 options->selectedwindow--;
Daniel Lezcano60a41022011-03-23 14:37:35 +0100177
Daniel Lezcano558a6d52011-03-23 14:37:41 +0100178 if (options->selectedwindow >= TOTAL_FEATURE_WINS)
179 options->selectedwindow = 0;
Daniel Lezcano60a41022011-03-23 14:37:35 +0100180
Daniel Lezcano558a6d52011-03-23 14:37:41 +0100181 if (options->selectedwindow < 0)
182 options->selectedwindow = TOTAL_FEATURE_WINS - 1;
Daniel Lezcano60a41022011-03-23 14:37:35 +0100183
Daniel Lezcano558a6d52011-03-23 14:37:41 +0100184 if (options->selectedwindow == CLOCK) {
Daniel Lezcano60a41022011-03-23 14:37:35 +0100185 if (keystroke == KEY_DOWN)
186 highlighted_row++;
187 if (keystroke == KEY_UP && highlighted_row > 0)
188 highlighted_row--;
189 if (keystroke == 47)
Daniel Lezcanoc5afe832011-03-23 14:37:36 +0100190 *findparent_ncurses = true;
Daniel Lezcano60a41022011-03-23 14:37:35 +0100191
192 if ((keystroke == 27 || oldselectedwin !=
Daniel Lezcano558a6d52011-03-23 14:37:41 +0100193 options->selectedwindow) && *findparent_ncurses) {
Daniel Lezcanoc5afe832011-03-23 14:37:36 +0100194 *findparent_ncurses = false;
Daniel Lezcano60a41022011-03-23 14:37:35 +0100195 clkname_str[0] = '\0';
196 }
197
198 if (*findparent_ncurses && keystroke != 13) {
199 int len = strlen(clkname_str);
200 char str[2];
201
202 if (keystroke == 263) {
203 if (len > 0)
204 len--;
205
206 clkname_str[len] = '\0';
207 } else {
208 if (strlen(clkname_str) ||
209 keystroke != '/') {
210 str[0] = keystroke;
211 str[1] = '\0';
212 if (len < 63)
213 strcat(clkname_str,
214 str);
215 }
216 }
217 }
218 }
219
220 keychar = toupper(keystroke);
221//#define DEBUG
222#ifdef DEBUG
223 killall_windows(1); fini_curses();
224 printf("key entered %d:%c\n", keystroke, keychar);
225 exit(1);
226#endif
227
228 if (keystroke == 13)
Daniel Lezcanoc5afe832011-03-23 14:37:36 +0100229 *enter_hit = true;
Daniel Lezcano60a41022011-03-23 14:37:35 +0100230
231 if (keychar == 'Q' && !*findparent_ncurses)
232 return 1;
233 if (keychar == 'R') {
Daniel Lezcanoc5afe832011-03-23 14:37:36 +0100234 *refreshwin = true;
Daniel Lezcano60a41022011-03-23 14:37:35 +0100235 options->ticktime = 3;
236 } else
Daniel Lezcanoc5afe832011-03-23 14:37:36 +0100237 *refreshwin = false;
Daniel Lezcano60a41022011-03-23 14:37:35 +0100238
239 return 0;
240}
241
Daniel Lezcano0051f4f2011-03-23 14:37:34 +0100242int mainloop(struct powerdebug_options *options)
Daniel Lezcano316bcae2011-03-23 14:37:30 +0100243{
Daniel Lezcanoc5afe832011-03-23 14:37:36 +0100244 bool findparent_ncurses = false;
245 bool refreshwin = false;
246 bool enter_hit = false;
Daniel Lezcano316bcae2011-03-23 14:37:30 +0100247 int firsttime[TOTAL_FEATURE_WINS];
Daniel Lezcano0051f4f2011-03-23 14:37:34 +0100248 int i;
Daniel Lezcano316bcae2011-03-23 14:37:30 +0100249 char clkname_str[64];
Daniel Lezcano316bcae2011-03-23 14:37:30 +0100250
251 for (i = 0; i < TOTAL_FEATURE_WINS; i++)
252 firsttime[i] = 1;
253
Amit Kucheriaa0adae42011-01-12 10:54:23 -0600254 while (1) {
Amit Arora47fd9182010-08-24 13:26:06 +0530255 int key = 0;
256 struct timeval tval;
257 fd_set readfds;
Amit Arorae9e16b02010-08-03 10:15:20 +0530258
Daniel Lezcanoa70d9492011-03-23 14:37:40 +0100259 if (!options->dump) {
Amit Kucheriaa0adae42011-01-12 10:54:23 -0600260 if (firsttime[0])
Amit Arora47fd9182010-08-24 13:26:06 +0530261 init_curses();
Daniel Lezcano558a6d52011-03-23 14:37:41 +0100262 create_windows(options->selectedwindow);
263 show_header(options->selectedwindow);
Amit Arora47fd9182010-08-24 13:26:06 +0530264 }
Amit Aroraac4e8652010-11-09 11:16:53 +0530265
Daniel Lezcano558a6d52011-03-23 14:37:41 +0100266 if (options->regulators || options->selectedwindow == REGULATOR) {
Daniel Lezcano408580e2011-03-26 22:05:59 +0100267 regulator_read_info(regulators_info, numregulators);
Daniel Lezcanoa70d9492011-03-23 14:37:40 +0100268 if (!options->dump) {
Daniel Lezcano558a6d52011-03-23 14:37:41 +0100269 create_selectedwindow(options->selectedwindow);
Daniel Lezcano833b63a2011-03-26 22:06:00 +0100270 show_regulator_info(regulators_info, numregulators,
271 options->verbose);
Amit Arora6e774cd2010-10-28 11:31:24 +0530272 }
Amit Arora47fd9182010-08-24 13:26:06 +0530273 else
Daniel Lezcanofac6aea2011-03-26 22:05:58 +0100274 regulator_print_info(regulators_info, numregulators,
275 options->verbose);
Amit Arora47fd9182010-08-24 13:26:06 +0530276 }
277
Daniel Lezcano558a6d52011-03-23 14:37:41 +0100278 if (options->clocks || options->selectedwindow == CLOCK) {
Amit Arora04f97742010-11-16 11:28:57 +0530279 int ret = 0;
Amit Arora6e774cd2010-10-28 11:31:24 +0530280 if (firsttime[CLOCK]) {
Daniel Lezcano558a6d52011-03-23 14:37:41 +0100281 ret = init_clock_details(options->dump,
282 options->selectedwindow);
Amit Arora04f97742010-11-16 11:28:57 +0530283 if (!ret)
284 firsttime[CLOCK] = 0;
Amit Arora3bd79162010-12-01 13:51:42 +0530285 strcpy(clkname_str, "");
Amit Arora6e774cd2010-10-28 11:31:24 +0530286 }
Daniel Lezcanoa70d9492011-03-23 14:37:40 +0100287 if (!ret && !options->dump) {
Amit Arora6e774cd2010-10-28 11:31:24 +0530288 int hrow;
Amit Arora0e512722010-10-01 12:24:16 +0530289
Daniel Lezcano558a6d52011-03-23 14:37:41 +0100290 create_selectedwindow(options->selectedwindow);
Amit Arora3bd79162010-12-01 13:51:42 +0530291 if (!findparent_ncurses) {
Amit Aroraa06a7302010-12-02 15:59:37 +0530292 int command = 0;
293
294 if (enter_hit)
295 command = CLOCK_SELECTED;
296 if (refreshwin)
297 command = REFRESH_WINDOW;
Amit Arora3bd79162010-12-01 13:51:42 +0530298 hrow = read_and_print_clock_info(
Daniel Lezcano316bcae2011-03-23 14:37:30 +0100299 options->verbose,
Amit Kucheriaa0adae42011-01-12 10:54:23 -0600300 highlighted_row,
301 command);
Amit Arora3bd79162010-12-01 13:51:42 +0530302 highlighted_row = hrow;
Daniel Lezcanoc5afe832011-03-23 14:37:36 +0100303 enter_hit = false;
Amit Arora3bd79162010-12-01 13:51:42 +0530304 } else
305 find_parents_for_clock(clkname_str,
Daniel Lezcanoa70d9492011-03-23 14:37:40 +0100306 enter_hit,
307 options->dump);
Amit Arora04f97742010-11-16 11:28:57 +0530308 }
Daniel Lezcanoa70d9492011-03-23 14:37:40 +0100309 if (!ret && options->dump) {
Daniel Lezcano316bcae2011-03-23 14:37:30 +0100310 if (options->findparent)
Daniel Lezcanoa70d9492011-03-23 14:37:40 +0100311 read_and_dump_clock_info_one(options->clkarg, options->dump);
Amit Aroraf4fb8102010-11-30 13:55:50 +0530312 else
Daniel Lezcano316bcae2011-03-23 14:37:30 +0100313 read_and_dump_clock_info(options->verbose);
Amit Aroraf4fb8102010-11-30 13:55:50 +0530314 }
Amit Arora6e774cd2010-10-28 11:31:24 +0530315 }
Amit Arora47fd9182010-08-24 13:26:06 +0530316
Daniel Lezcano558a6d52011-03-23 14:37:41 +0100317 if (options->sensors || options->selectedwindow == SENSOR) {
Daniel Lezcanoa70d9492011-03-23 14:37:40 +0100318 if (!options->dump) {
Daniel Lezcano558a6d52011-03-23 14:37:41 +0100319 create_selectedwindow(options->selectedwindow);
Amit Arora6e774cd2010-10-28 11:31:24 +0530320 print_sensor_header();
321 } else
Daniel Lezcano316bcae2011-03-23 14:37:30 +0100322 read_and_print_sensor_info(options->verbose);
Amit Arora47fd9182010-08-24 13:26:06 +0530323 }
324
Daniel Lezcanoa70d9492011-03-23 14:37:40 +0100325 if (options->dump)
Amit Arora47fd9182010-08-24 13:26:06 +0530326 break;
327
328 FD_ZERO(&readfds);
329 FD_SET(0, &readfds);
Daniel Lezcano316bcae2011-03-23 14:37:30 +0100330 tval.tv_sec = options->ticktime;
331 tval.tv_usec = (options->ticktime - tval.tv_sec) * 1000000;
Amit Arora47fd9182010-08-24 13:26:06 +0530332
333 key = select(1, &readfds, NULL, NULL, &tval);
Daniel Lezcano60a41022011-03-23 14:37:35 +0100334 if (!key)
335 continue;
Amit Arora47fd9182010-08-24 13:26:06 +0530336
Daniel Lezcano60a41022011-03-23 14:37:35 +0100337 if (keystroke_callback(&enter_hit, &findparent_ncurses,
338 clkname_str, &refreshwin, options))
339 break;
Amit Arora97006e52010-10-28 11:56:08 +0530340
Amit Arorae9e16b02010-08-03 10:15:20 +0530341 }
Daniel Lezcano0051f4f2011-03-23 14:37:34 +0100342
343 return 0;
344}
345
346int main(int argc, char **argv)
347{
348 struct powerdebug_options *options;
349
350 options = malloc(sizeof(*options));
351 if (!options) {
352 fprintf(stderr, "failed to allocated memory\n");
353 return -1;
354 }
355
356 if (getoptions(argc, argv, options)) {
357 usage();
358 return 1;
359 }
360
Daniel Lezcano4aab2fe2011-03-26 22:05:53 +0100361 regulators_info = regulator_init(&numregulators);
362 if (!regulators_info) {
363 printf("not enough memory to allocate regulators info\n");
Daniel Lezcano0051f4f2011-03-23 14:37:34 +0100364 return 1;
Daniel Lezcano4aab2fe2011-03-26 22:05:53 +0100365 }
Daniel Lezcano0051f4f2011-03-23 14:37:34 +0100366
367 if (mainloop(options))
368 return 1;
369
370 return 0;
Amit Arorae9e16b02010-08-03 10:15:20 +0530371}