blob: 5ff675dfd06a805df4a6aa84b04a15b8d409652b [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 Lezcano2ef06e92011-05-24 15:27:49 +020018#include <math.h>
Daniel Lezcanocac52d92011-03-26 22:05:49 +010019#include "regulator.h"
Daniel Lezcano192c1d22011-03-26 22:06:14 +010020#include "display.h"
Daniel Lezcanof0e06652011-03-26 22:06:19 +010021#include "clocks.h"
Daniel Lezcano597892a2011-06-15 15:45:12 +020022#include "sensor.h"
Amit Arorae9e16b02010-08-03 10:15:20 +053023#include "powerdebug.h"
24
Amit Arora422c52f2010-12-02 16:22:29 +053025void usage(void)
Amit Arorae9e16b02010-08-03 10:15:20 +053026{
Amit Arora422c52f2010-12-02 16:22:29 +053027 printf("Usage: powerdebug [OPTIONS]\n");
28 printf("\n");
29 printf("powerdebug -d [ -r ] [ -s ] [ -c [ -p <clock-name> ] ] "
30 "[ -v ]\n");
31 printf("powerdebug [ -r | -s | -c ]\n");
Amit Arora17552782010-12-02 12:23:14 +053032 printf(" -r, --regulator Show regulator information\n");
33 printf(" -s, --sensor Show sensor information\n");
34 printf(" -c, --clock Show clock information\n");
Amit Arora422c52f2010-12-02 16:22:29 +053035 printf(" -p, --findparents Show all parents for a particular"
Amit Kucheriaa0adae42011-01-12 10:54:23 -060036 " clock\n");
Amit Arora17552782010-12-02 12:23:14 +053037 printf(" -t, --time Set ticktime in seconds (eg. 10.0)\n");
38 printf(" -d, --dump Dump information once (no refresh)\n");
Amit Arora422c52f2010-12-02 16:22:29 +053039 printf(" -v, --verbose Verbose mode (use with -r and/or"
Amit Kucheriaa0adae42011-01-12 10:54:23 -060040 " -s)\n");
Amit Arora17552782010-12-02 12:23:14 +053041 printf(" -V, --version Show Version\n");
42 printf(" -h, --help Help\n");
Amit Arorae9e16b02010-08-03 10:15:20 +053043}
44
Amit Arora17552782010-12-02 12:23:14 +053045void version()
Amit Arorae9e16b02010-08-03 10:15:20 +053046{
Amit Arora17552782010-12-02 12:23:14 +053047 printf("powerdebug version %s\n", VERSION);
Amit Arorae9e16b02010-08-03 10:15:20 +053048}
49
Daniel Lezcano316bcae2011-03-23 14:37:30 +010050/*
51 * Options:
52 * -r, --regulator : regulator
53 * -s, --sensor : sensors
54 * -c, --clock : clocks
55 * -p, --findparents : clockname whose parents have to be found
56 * -t, --time : ticktime
57 * -d, --dump : dump
58 * -v, --verbose : verbose
59 * -V, --version : version
60 * -h, --help : help
61 * no option / default : show usage!
62 */
63
64static struct option long_options[] = {
65 { "regulator", 0, 0, 'r' },
66 { "sensor", 0, 0, 's' },
67 { "clock", 0, 0, 'c' },
68 { "findparents", 1, 0, 'p' },
69 { "time", 1, 0, 't' },
70 { "dump", 0, 0, 'd' },
71 { "verbose", 0, 0, 'v' },
72 { "version", 0, 0, 'V' },
73 { "help", 0, 0, 'h' },
74 { 0, 0, 0, 0 }
75};
76
77struct powerdebug_options {
Daniel Lezcanoc5afe832011-03-23 14:37:36 +010078 bool verbose;
Daniel Lezcanoc5afe832011-03-23 14:37:36 +010079 bool regulators;
80 bool sensors;
81 bool clocks;
Daniel Lezcanoa70d9492011-03-23 14:37:40 +010082 bool dump;
Daniel Lezcanoc5afe832011-03-23 14:37:36 +010083 unsigned int ticktime;
Daniel Lezcano558a6d52011-03-23 14:37:41 +010084 int selectedwindow;
Daniel Lezcano6e0c9c82011-03-26 22:06:07 +010085 char *clkname;
Daniel Lezcano316bcae2011-03-23 14:37:30 +010086};
87
88int getoptions(int argc, char *argv[], struct powerdebug_options *options)
Amit Arorae9e16b02010-08-03 10:15:20 +053089{
Daniel Lezcano316bcae2011-03-23 14:37:30 +010090 int c;
Amit Arorae9e16b02010-08-03 10:15:20 +053091
Daniel Lezcano316bcae2011-03-23 14:37:30 +010092 memset(options, 0, sizeof(*options));
93 options->ticktime = 10;
Daniel Lezcano558a6d52011-03-23 14:37:41 +010094 options->selectedwindow = -1;
Amit Arorae9e16b02010-08-03 10:15:20 +053095
Amit Arorafefe8bf2010-08-05 13:31:20 +053096 while (1) {
97 int optindex = 0;
Amit Arorafefe8bf2010-08-05 13:31:20 +053098
Daniel Lezcano316bcae2011-03-23 14:37:30 +010099 c = getopt_long(argc, argv, "rscp:t:dvVh",
100 long_options, &optindex);
Amit Arorafefe8bf2010-08-05 13:31:20 +0530101 if (c == -1)
102 break;
103
104 switch (c) {
Amit Arora6e774cd2010-10-28 11:31:24 +0530105 case 'r':
Daniel Lezcanoc5afe832011-03-23 14:37:36 +0100106 options->regulators = true;
Daniel Lezcano558a6d52011-03-23 14:37:41 +0100107 options->selectedwindow = REGULATOR;
Amit Arora6e774cd2010-10-28 11:31:24 +0530108 break;
109 case 's':
Daniel Lezcanoc5afe832011-03-23 14:37:36 +0100110 options->sensors = true;
Daniel Lezcano558a6d52011-03-23 14:37:41 +0100111 options->selectedwindow = SENSOR;
Amit Arora6e774cd2010-10-28 11:31:24 +0530112 break;
113 case 'c':
Daniel Lezcanoc5afe832011-03-23 14:37:36 +0100114 options->clocks = true;
Daniel Lezcano558a6d52011-03-23 14:37:41 +0100115 options->selectedwindow = CLOCK;
Amit Arora6e774cd2010-10-28 11:31:24 +0530116 break;
Amit Aroraf4fb8102010-11-30 13:55:50 +0530117 case 'p':
Daniel Lezcano6e0c9c82011-03-26 22:06:07 +0100118 options->clkname = strdup(optarg);
119 if (!options->clkname) {
Daniel Lezcano9420fde2011-03-23 14:37:31 +0100120 fprintf(stderr, "failed to allocate memory");
121 return -1;
122 }
Amit Kucheriaeab558a2011-03-25 09:51:41 +0200123 options->dump = true; /* Assume -dc in case of -p */
124 options->clocks = true;
Amit Aroraf4fb8102010-11-30 13:55:50 +0530125 break;
Amit Arora6e774cd2010-10-28 11:31:24 +0530126 case 't':
Daniel Lezcano7f112da2011-03-23 14:37:32 +0100127 options->ticktime = atoi(optarg);
Amit Arora6e774cd2010-10-28 11:31:24 +0530128 break;
129 case 'd':
Daniel Lezcanoa70d9492011-03-23 14:37:40 +0100130 options->dump = true;
Amit Arora6e774cd2010-10-28 11:31:24 +0530131 break;
132 case 'v':
Daniel Lezcanoc5afe832011-03-23 14:37:36 +0100133 options->verbose = true;
Amit Arora6e774cd2010-10-28 11:31:24 +0530134 break;
135 case 'V':
136 version();
137 break;
Amit Arora6e774cd2010-10-28 11:31:24 +0530138 case '?':
Daniel Lezcano316bcae2011-03-23 14:37:30 +0100139 fprintf(stderr, "%s: Unknown option %c'.\n",
Amit Kucheriaa0adae42011-01-12 10:54:23 -0600140 argv[0], optopt);
Amit Arora6e774cd2010-10-28 11:31:24 +0530141 default:
Daniel Lezcano316bcae2011-03-23 14:37:30 +0100142 return -1;
Amit Arorafefe8bf2010-08-05 13:31:20 +0530143 }
Amit Arorae9e16b02010-08-03 10:15:20 +0530144 }
Amit Aroraa06a7302010-12-02 15:59:37 +0530145
Daniel Lezcano934fc092011-03-26 22:06:18 +0100146 /* No system specified to be dump, let's default to all */
147 if (!options->regulators && !options->clocks && !options->sensors)
148 options->regulators = options->clocks = options->sensors = true;
Amit Arorafefe8bf2010-08-05 13:31:20 +0530149
Daniel Lezcanoc9c14622011-03-26 22:06:10 +0100150 if (options->selectedwindow == -1)
Daniel Lezcano558a6d52011-03-23 14:37:41 +0100151 options->selectedwindow = CLOCK;
Amit Arorae9e16b02010-08-03 10:15:20 +0530152
Daniel Lezcano316bcae2011-03-23 14:37:30 +0100153 return 0;
154}
155
Daniel Lezcano2c3a9df2011-06-15 15:45:12 +0200156int keystroke_callback(bool *enter_hit, struct powerdebug_options *options)
Daniel Lezcano60a41022011-03-23 14:37:35 +0100157{
158 char keychar;
159 int keystroke = getch();
Daniel Lezcano60a41022011-03-23 14:37:35 +0100160
161 if (keystroke == EOF)
162 exit(0);
163
Daniel Lezcanod96731a2011-06-15 15:45:12 +0200164 if (keystroke == KEY_RIGHT || keystroke == '\t')
165 options->selectedwindow = display_next_panel();
Daniel Lezcano60a41022011-03-23 14:37:35 +0100166
Daniel Lezcanod96731a2011-06-15 15:45:12 +0200167 if (keystroke == KEY_LEFT || keystroke == KEY_BTAB)
168 options->selectedwindow = display_prev_panel();
Daniel Lezcano60a41022011-03-23 14:37:35 +0100169
Daniel Lezcano99bd0bc2011-06-15 15:45:12 +0200170 if (keystroke == KEY_DOWN)
Daniel Lezcanod96731a2011-06-15 15:45:12 +0200171 display_next_line();
Daniel Lezcano2e9df762011-06-15 15:45:12 +0200172
Daniel Lezcano99bd0bc2011-06-15 15:45:12 +0200173 if (keystroke == KEY_UP)
Daniel Lezcanod96731a2011-06-15 15:45:12 +0200174 display_prev_line();
Daniel Lezcano2e9df762011-06-15 15:45:12 +0200175
Daniel Lezcano60a41022011-03-23 14:37:35 +0100176 keychar = toupper(keystroke);
Daniel Lezcano60a41022011-03-23 14:37:35 +0100177
Daniel Lezcano3b42b5e2011-05-24 15:27:49 +0200178 if (keystroke == '\r')
Daniel Lezcanoc5afe832011-03-23 14:37:36 +0100179 *enter_hit = true;
Daniel Lezcano60a41022011-03-23 14:37:35 +0100180
Daniel Lezcano2c3a9df2011-06-15 15:45:12 +0200181 if (keychar == 'Q')
Daniel Lezcano60a41022011-03-23 14:37:35 +0100182 return 1;
Daniel Lezcano2c3a9df2011-06-15 15:45:12 +0200183
Daniel Lezcano60a41022011-03-23 14:37:35 +0100184 if (keychar == 'R') {
Daniel Lezcano2c3a9df2011-06-15 15:45:12 +0200185 /* TODO refresh window */
Daniel Lezcano60a41022011-03-23 14:37:35 +0100186 options->ticktime = 3;
Daniel Lezcano2c3a9df2011-06-15 15:45:12 +0200187 }
Daniel Lezcano60a41022011-03-23 14:37:35 +0100188
189 return 0;
190}
191
Daniel Lezcanob25be4a2011-06-15 15:45:12 +0200192int mainloop(struct powerdebug_options *options)
Daniel Lezcano316bcae2011-03-23 14:37:30 +0100193{
Daniel Lezcanoc5afe832011-03-23 14:37:36 +0100194 bool enter_hit = false;
Daniel Lezcano316bcae2011-03-23 14:37:30 +0100195
Amit Kucheriaa0adae42011-01-12 10:54:23 -0600196 while (1) {
Amit Arora47fd9182010-08-24 13:26:06 +0530197 int key = 0;
198 struct timeval tval;
199 fd_set readfds;
Amit Arorae9e16b02010-08-03 10:15:20 +0530200
Daniel Lezcanob25be4a2011-06-15 15:45:12 +0200201 if (options->selectedwindow == REGULATOR)
202 regulator_display();
Amit Arora47fd9182010-08-24 13:26:06 +0530203
Daniel Lezcanod96731a2011-06-15 15:45:12 +0200204 if (options->selectedwindow == SENSOR)
205 sensor_display();
206
Daniel Lezcano95b0dac2011-06-08 23:30:00 +0200207 if (options->selectedwindow == CLOCK) {
Daniel Lezcano99bd0bc2011-06-15 15:45:12 +0200208 if (enter_hit)
209 clock_toggle_expanded();
Daniel Lezcano934fc092011-03-26 22:06:18 +0100210
Daniel Lezcano99bd0bc2011-06-15 15:45:12 +0200211 clock_display();
212 enter_hit = false;
Amit Arora6e774cd2010-10-28 11:31:24 +0530213 }
Amit Arora47fd9182010-08-24 13:26:06 +0530214
Amit Arora47fd9182010-08-24 13:26:06 +0530215 FD_ZERO(&readfds);
216 FD_SET(0, &readfds);
Daniel Lezcano316bcae2011-03-23 14:37:30 +0100217 tval.tv_sec = options->ticktime;
218 tval.tv_usec = (options->ticktime - tval.tv_sec) * 1000000;
Amit Arora47fd9182010-08-24 13:26:06 +0530219
Daniel Lezcanoe8cf9b82011-06-08 23:30:01 +0200220 again:
Amit Arora47fd9182010-08-24 13:26:06 +0530221 key = select(1, &readfds, NULL, NULL, &tval);
Daniel Lezcano60a41022011-03-23 14:37:35 +0100222 if (!key)
223 continue;
Amit Arora47fd9182010-08-24 13:26:06 +0530224
Daniel Lezcanoe8cf9b82011-06-08 23:30:01 +0200225 if (key < 0) {
226 if (errno == EINTR)
227 goto again;
228 break;
229 }
230
Daniel Lezcano2c3a9df2011-06-15 15:45:12 +0200231 if (keystroke_callback(&enter_hit, options))
Daniel Lezcano60a41022011-03-23 14:37:35 +0100232 break;
Amit Arora97006e52010-10-28 11:56:08 +0530233
Amit Arorae9e16b02010-08-03 10:15:20 +0530234 }
Daniel Lezcano0051f4f2011-03-23 14:37:34 +0100235
236 return 0;
237}
238
Daniel Lezcanob25be4a2011-06-15 15:45:12 +0200239static int powerdebug_dump(struct powerdebug_options *options)
Daniel Lezcano21c04d42011-03-26 22:06:04 +0100240{
Daniel Lezcanob25be4a2011-06-15 15:45:12 +0200241 if (options->regulators)
242 regulator_dump();
Daniel Lezcanob5746712011-03-26 22:06:05 +0100243
Daniel Lezcanoc7891942011-06-08 23:30:00 +0200244 if (options->clocks)
Daniel Lezcano597892a2011-06-15 15:45:12 +0200245 clock_dump(options->clkname);
Daniel Lezcanob5746712011-03-26 22:06:05 +0100246
247 if (options->sensors)
Daniel Lezcano3d0aef42011-06-15 15:45:12 +0200248 sensor_dump();
Daniel Lezcanob5746712011-03-26 22:06:05 +0100249
Daniel Lezcano21c04d42011-03-26 22:06:04 +0100250 return 0;
251}
252
Daniel Lezcanob25be4a2011-06-15 15:45:12 +0200253static int powerdebug_display(struct powerdebug_options *options)
Daniel Lezcanoc08f1f22011-03-26 22:06:21 +0100254{
Daniel Lezcano7b3da502011-06-15 15:45:12 +0200255 if (display_init(options->selectedwindow)) {
Daniel Lezcanoc08f1f22011-03-26 22:06:21 +0100256 printf("failed to initialize display\n");
257 return -1;
258 }
259
Daniel Lezcanob25be4a2011-06-15 15:45:12 +0200260 if (mainloop(options))
Daniel Lezcanoc08f1f22011-03-26 22:06:21 +0100261 return -1;
262
263 return 0;
264}
265
Daniel Lezcano6e0c9c82011-03-26 22:06:07 +0100266static struct powerdebug_options *powerdebug_init(void)
267{
268 struct powerdebug_options *options;
269
270 options = malloc(sizeof(*options));
271 if (!options)
272 return NULL;
273
274 memset(options, 0, sizeof(*options));
275
276 return options;
277}
278
Daniel Lezcano0051f4f2011-03-23 14:37:34 +0100279int main(int argc, char **argv)
280{
281 struct powerdebug_options *options;
Daniel Lezcanob25be4a2011-06-15 15:45:12 +0200282 int ret;
Daniel Lezcano0051f4f2011-03-23 14:37:34 +0100283
Daniel Lezcano6e0c9c82011-03-26 22:06:07 +0100284 options = powerdebug_init();
Daniel Lezcano0051f4f2011-03-23 14:37:34 +0100285 if (!options) {
Daniel Lezcano6e0c9c82011-03-26 22:06:07 +0100286 fprintf(stderr, "not enough memory to allocate options\n");
Daniel Lezcano0051f4f2011-03-23 14:37:34 +0100287 return 1;
288 }
289
Daniel Lezcanoc08f1f22011-03-26 22:06:21 +0100290 if (getoptions(argc, argv, options)) {
291 usage();
292 return 1;
293 }
294
Daniel Lezcanob25be4a2011-06-15 15:45:12 +0200295 if (regulator_init()) {
Daniel Lezcano4aab2fe2011-03-26 22:05:53 +0100296 printf("not enough memory to allocate regulators info\n");
Daniel Lezcano6e48fa42011-03-26 22:06:23 +0100297 options->regulators = false;
Daniel Lezcano4aab2fe2011-03-26 22:05:53 +0100298 }
Daniel Lezcano0051f4f2011-03-23 14:37:34 +0100299
Daniel Lezcanof0e06652011-03-26 22:06:19 +0100300 if (clock_init()) {
301 printf("failed to initialize clock details (check debugfs)\n");
302 options->clocks = false;
303 }
304
Daniel Lezcano3d0aef42011-06-15 15:45:12 +0200305 if (sensor_init()) {
306 printf("failed to initialize sensors\n");
307 options->sensors = false;
308 }
309
Daniel Lezcanob25be4a2011-06-15 15:45:12 +0200310 ret = options->dump ? powerdebug_dump(options) :
311 powerdebug_display(options);
Daniel Lezcano21c04d42011-03-26 22:06:04 +0100312
Daniel Lezcanoc08f1f22011-03-26 22:06:21 +0100313 return ret < 0;
Amit Arorae9e16b02010-08-03 10:15:20 +0530314}