blob: 5d834c7bddf76573ac5a7605086bcf6334caf463 [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 Lezcano15627482011-06-15 15:45:12 +020018#include <string.h>
19#include <stdlib.h>
20#include <stdio.h>
21#include <errno.h>
22#include <ncurses.h>
Daniel Lezcanocac52d92011-03-26 22:05:49 +010023#include "regulator.h"
Daniel Lezcano192c1d22011-03-26 22:06:14 +010024#include "display.h"
Daniel Lezcanof0e06652011-03-26 22:06:19 +010025#include "clocks.h"
Daniel Lezcano597892a2011-06-15 15:45:12 +020026#include "sensor.h"
Amit Arorae9e16b02010-08-03 10:15:20 +053027#include "powerdebug.h"
28
Amit Arora422c52f2010-12-02 16:22:29 +053029void usage(void)
Amit Arorae9e16b02010-08-03 10:15:20 +053030{
Amit Arora422c52f2010-12-02 16:22:29 +053031 printf("Usage: powerdebug [OPTIONS]\n");
32 printf("\n");
33 printf("powerdebug -d [ -r ] [ -s ] [ -c [ -p <clock-name> ] ] "
34 "[ -v ]\n");
35 printf("powerdebug [ -r | -s | -c ]\n");
Amit Arora17552782010-12-02 12:23:14 +053036 printf(" -r, --regulator Show regulator information\n");
37 printf(" -s, --sensor Show sensor information\n");
38 printf(" -c, --clock Show clock information\n");
Amit Arora422c52f2010-12-02 16:22:29 +053039 printf(" -p, --findparents Show all parents for a particular"
Amit Kucheriaa0adae42011-01-12 10:54:23 -060040 " clock\n");
Amit Arora17552782010-12-02 12:23:14 +053041 printf(" -t, --time Set ticktime in seconds (eg. 10.0)\n");
42 printf(" -d, --dump Dump information once (no refresh)\n");
Amit Arora422c52f2010-12-02 16:22:29 +053043 printf(" -v, --verbose Verbose mode (use with -r and/or"
Amit Kucheriaa0adae42011-01-12 10:54:23 -060044 " -s)\n");
Amit Arora17552782010-12-02 12:23:14 +053045 printf(" -V, --version Show Version\n");
46 printf(" -h, --help Help\n");
Amit Arorae9e16b02010-08-03 10:15:20 +053047}
48
Amit Arora17552782010-12-02 12:23:14 +053049void version()
Amit Arorae9e16b02010-08-03 10:15:20 +053050{
Amit Arora17552782010-12-02 12:23:14 +053051 printf("powerdebug version %s\n", VERSION);
Amit Arorae9e16b02010-08-03 10:15:20 +053052}
53
Daniel Lezcano316bcae2011-03-23 14:37:30 +010054/*
55 * Options:
56 * -r, --regulator : regulator
57 * -s, --sensor : sensors
58 * -c, --clock : clocks
59 * -p, --findparents : clockname whose parents have to be found
60 * -t, --time : ticktime
61 * -d, --dump : dump
62 * -v, --verbose : verbose
63 * -V, --version : version
64 * -h, --help : help
65 * no option / default : show usage!
66 */
67
68static struct option long_options[] = {
69 { "regulator", 0, 0, 'r' },
70 { "sensor", 0, 0, 's' },
71 { "clock", 0, 0, 'c' },
72 { "findparents", 1, 0, 'p' },
73 { "time", 1, 0, 't' },
74 { "dump", 0, 0, 'd' },
75 { "verbose", 0, 0, 'v' },
76 { "version", 0, 0, 'V' },
77 { "help", 0, 0, 'h' },
78 { 0, 0, 0, 0 }
79};
80
81struct powerdebug_options {
Daniel Lezcanoc5afe832011-03-23 14:37:36 +010082 bool verbose;
Daniel Lezcanoc5afe832011-03-23 14:37:36 +010083 bool regulators;
84 bool sensors;
85 bool clocks;
Daniel Lezcanoa70d9492011-03-23 14:37:40 +010086 bool dump;
Daniel Lezcanoc5afe832011-03-23 14:37:36 +010087 unsigned int ticktime;
Daniel Lezcano558a6d52011-03-23 14:37:41 +010088 int selectedwindow;
Daniel Lezcano6e0c9c82011-03-26 22:06:07 +010089 char *clkname;
Daniel Lezcano316bcae2011-03-23 14:37:30 +010090};
91
92int getoptions(int argc, char *argv[], struct powerdebug_options *options)
Amit Arorae9e16b02010-08-03 10:15:20 +053093{
Daniel Lezcano316bcae2011-03-23 14:37:30 +010094 int c;
Amit Arorae9e16b02010-08-03 10:15:20 +053095
Daniel Lezcano316bcae2011-03-23 14:37:30 +010096 memset(options, 0, sizeof(*options));
97 options->ticktime = 10;
Daniel Lezcano558a6d52011-03-23 14:37:41 +010098 options->selectedwindow = -1;
Amit Arorae9e16b02010-08-03 10:15:20 +053099
Amit Arorafefe8bf2010-08-05 13:31:20 +0530100 while (1) {
101 int optindex = 0;
Amit Arorafefe8bf2010-08-05 13:31:20 +0530102
Daniel Lezcano316bcae2011-03-23 14:37:30 +0100103 c = getopt_long(argc, argv, "rscp:t:dvVh",
104 long_options, &optindex);
Amit Arorafefe8bf2010-08-05 13:31:20 +0530105 if (c == -1)
106 break;
107
108 switch (c) {
Amit Arora6e774cd2010-10-28 11:31:24 +0530109 case 'r':
Daniel Lezcanoc5afe832011-03-23 14:37:36 +0100110 options->regulators = true;
Daniel Lezcano558a6d52011-03-23 14:37:41 +0100111 options->selectedwindow = REGULATOR;
Amit Arora6e774cd2010-10-28 11:31:24 +0530112 break;
113 case 's':
Daniel Lezcanoc5afe832011-03-23 14:37:36 +0100114 options->sensors = true;
Daniel Lezcano558a6d52011-03-23 14:37:41 +0100115 options->selectedwindow = SENSOR;
Amit Arora6e774cd2010-10-28 11:31:24 +0530116 break;
117 case 'c':
Daniel Lezcanoc5afe832011-03-23 14:37:36 +0100118 options->clocks = true;
Daniel Lezcano558a6d52011-03-23 14:37:41 +0100119 options->selectedwindow = CLOCK;
Amit Arora6e774cd2010-10-28 11:31:24 +0530120 break;
Amit Aroraf4fb8102010-11-30 13:55:50 +0530121 case 'p':
Daniel Lezcano6e0c9c82011-03-26 22:06:07 +0100122 options->clkname = strdup(optarg);
123 if (!options->clkname) {
Daniel Lezcano9420fde2011-03-23 14:37:31 +0100124 fprintf(stderr, "failed to allocate memory");
125 return -1;
126 }
Amit Kucheriaeab558a2011-03-25 09:51:41 +0200127 options->dump = true; /* Assume -dc in case of -p */
128 options->clocks = true;
Amit Aroraf4fb8102010-11-30 13:55:50 +0530129 break;
Amit Arora6e774cd2010-10-28 11:31:24 +0530130 case 't':
Daniel Lezcano7f112da2011-03-23 14:37:32 +0100131 options->ticktime = atoi(optarg);
Amit Arora6e774cd2010-10-28 11:31:24 +0530132 break;
133 case 'd':
Daniel Lezcanoa70d9492011-03-23 14:37:40 +0100134 options->dump = true;
Amit Arora6e774cd2010-10-28 11:31:24 +0530135 break;
136 case 'v':
Daniel Lezcanoc5afe832011-03-23 14:37:36 +0100137 options->verbose = true;
Amit Arora6e774cd2010-10-28 11:31:24 +0530138 break;
139 case 'V':
140 version();
141 break;
Amit Arora6e774cd2010-10-28 11:31:24 +0530142 case '?':
Daniel Lezcano316bcae2011-03-23 14:37:30 +0100143 fprintf(stderr, "%s: Unknown option %c'.\n",
Amit Kucheriaa0adae42011-01-12 10:54:23 -0600144 argv[0], optopt);
Amit Arora6e774cd2010-10-28 11:31:24 +0530145 default:
Daniel Lezcano316bcae2011-03-23 14:37:30 +0100146 return -1;
Amit Arorafefe8bf2010-08-05 13:31:20 +0530147 }
Amit Arorae9e16b02010-08-03 10:15:20 +0530148 }
Amit Aroraa06a7302010-12-02 15:59:37 +0530149
Daniel Lezcano934fc092011-03-26 22:06:18 +0100150 /* No system specified to be dump, let's default to all */
151 if (!options->regulators && !options->clocks && !options->sensors)
152 options->regulators = options->clocks = options->sensors = true;
Amit Arorafefe8bf2010-08-05 13:31:20 +0530153
Daniel Lezcanoc9c14622011-03-26 22:06:10 +0100154 if (options->selectedwindow == -1)
Daniel Lezcano558a6d52011-03-23 14:37:41 +0100155 options->selectedwindow = CLOCK;
Amit Arorae9e16b02010-08-03 10:15:20 +0530156
Daniel Lezcano316bcae2011-03-23 14:37:30 +0100157 return 0;
158}
159
Daniel Lezcano271fd902011-06-15 15:45:12 +0200160int keystroke_callback(struct powerdebug_options *options)
Daniel Lezcano60a41022011-03-23 14:37:35 +0100161{
Daniel Lezcano60a41022011-03-23 14:37:35 +0100162 int keystroke = getch();
Daniel Lezcano60a41022011-03-23 14:37:35 +0100163
Daniel Lezcanoc44764a2011-06-15 15:45:12 +0200164 switch (keystroke) {
Daniel Lezcano60a41022011-03-23 14:37:35 +0100165
Daniel Lezcanoc44764a2011-06-15 15:45:12 +0200166 case KEY_RIGHT:
167 case '\t':
Daniel Lezcano271fd902011-06-15 15:45:12 +0200168 display_next_panel();
Daniel Lezcanoc44764a2011-06-15 15:45:12 +0200169 break;
Daniel Lezcano60a41022011-03-23 14:37:35 +0100170
Daniel Lezcanoc44764a2011-06-15 15:45:12 +0200171 case KEY_LEFT:
172 case KEY_BTAB:
Daniel Lezcano271fd902011-06-15 15:45:12 +0200173 display_prev_panel();
Daniel Lezcanoc44764a2011-06-15 15:45:12 +0200174 break;
Daniel Lezcano60a41022011-03-23 14:37:35 +0100175
Daniel Lezcanoc44764a2011-06-15 15:45:12 +0200176 case KEY_DOWN:
Daniel Lezcanod96731a2011-06-15 15:45:12 +0200177 display_next_line();
Daniel Lezcanoc44764a2011-06-15 15:45:12 +0200178 break;
Daniel Lezcano2e9df762011-06-15 15:45:12 +0200179
Daniel Lezcanoc44764a2011-06-15 15:45:12 +0200180 case KEY_UP:
Daniel Lezcanod96731a2011-06-15 15:45:12 +0200181 display_prev_line();
Daniel Lezcanoc44764a2011-06-15 15:45:12 +0200182 break;
Daniel Lezcano2e9df762011-06-15 15:45:12 +0200183
Daniel Lezcanoc44764a2011-06-15 15:45:12 +0200184 case '\r':
Daniel Lezcano271fd902011-06-15 15:45:12 +0200185 display_select();
Daniel Lezcanoc44764a2011-06-15 15:45:12 +0200186 break;
Daniel Lezcano60a41022011-03-23 14:37:35 +0100187
Daniel Lezcanoc44764a2011-06-15 15:45:12 +0200188 case EOF:
189 case 'q':
190 case 'Q':
Daniel Lezcano60a41022011-03-23 14:37:35 +0100191 return 1;
Daniel Lezcano2c3a9df2011-06-15 15:45:12 +0200192
Daniel Lezcanoc44764a2011-06-15 15:45:12 +0200193 case 'r':
194 case 'R':
Daniel Lezcano271fd902011-06-15 15:45:12 +0200195 display_refresh();
Daniel Lezcano60a41022011-03-23 14:37:35 +0100196 options->ticktime = 3;
Daniel Lezcanoc44764a2011-06-15 15:45:12 +0200197 break;
Daniel Lezcano2c3a9df2011-06-15 15:45:12 +0200198 }
Daniel Lezcano60a41022011-03-23 14:37:35 +0100199
200 return 0;
201}
202
Daniel Lezcanob25be4a2011-06-15 15:45:12 +0200203int mainloop(struct powerdebug_options *options)
Daniel Lezcano316bcae2011-03-23 14:37:30 +0100204{
Amit Kucheriaa0adae42011-01-12 10:54:23 -0600205 while (1) {
Daniel Lezcanoc44764a2011-06-15 15:45:12 +0200206 int ret;
Amit Arora47fd9182010-08-24 13:26:06 +0530207 struct timeval tval;
208 fd_set readfds;
Amit Arorae9e16b02010-08-03 10:15:20 +0530209
Daniel Lezcanoc44764a2011-06-15 15:45:12 +0200210 display_refresh();
211
Amit Arora47fd9182010-08-24 13:26:06 +0530212 FD_ZERO(&readfds);
213 FD_SET(0, &readfds);
Daniel Lezcano316bcae2011-03-23 14:37:30 +0100214 tval.tv_sec = options->ticktime;
215 tval.tv_usec = (options->ticktime - tval.tv_sec) * 1000000;
Amit Arora47fd9182010-08-24 13:26:06 +0530216
Daniel Lezcanoe8cf9b82011-06-08 23:30:01 +0200217 again:
Daniel Lezcanoc44764a2011-06-15 15:45:12 +0200218 ret = select(1, &readfds, NULL, NULL, &tval);
219 if (!ret)
Daniel Lezcano60a41022011-03-23 14:37:35 +0100220 continue;
Amit Arora47fd9182010-08-24 13:26:06 +0530221
Daniel Lezcanoc44764a2011-06-15 15:45:12 +0200222 if (ret < 0) {
Daniel Lezcanoe8cf9b82011-06-08 23:30:01 +0200223 if (errno == EINTR)
224 goto again;
225 break;
226 }
227
Daniel Lezcano271fd902011-06-15 15:45:12 +0200228 if (keystroke_callback(options))
Daniel Lezcano60a41022011-03-23 14:37:35 +0100229 break;
Amit Arorae9e16b02010-08-03 10:15:20 +0530230 }
Daniel Lezcano0051f4f2011-03-23 14:37:34 +0100231
232 return 0;
233}
234
Daniel Lezcanob25be4a2011-06-15 15:45:12 +0200235static int powerdebug_dump(struct powerdebug_options *options)
Daniel Lezcano21c04d42011-03-26 22:06:04 +0100236{
Daniel Lezcanob25be4a2011-06-15 15:45:12 +0200237 if (options->regulators)
238 regulator_dump();
Daniel Lezcanob5746712011-03-26 22:06:05 +0100239
Daniel Lezcanoc7891942011-06-08 23:30:00 +0200240 if (options->clocks)
Daniel Lezcano597892a2011-06-15 15:45:12 +0200241 clock_dump(options->clkname);
Daniel Lezcanob5746712011-03-26 22:06:05 +0100242
243 if (options->sensors)
Daniel Lezcano3d0aef42011-06-15 15:45:12 +0200244 sensor_dump();
Daniel Lezcanob5746712011-03-26 22:06:05 +0100245
Daniel Lezcano21c04d42011-03-26 22:06:04 +0100246 return 0;
247}
248
Daniel Lezcanob25be4a2011-06-15 15:45:12 +0200249static int powerdebug_display(struct powerdebug_options *options)
Daniel Lezcanoc08f1f22011-03-26 22:06:21 +0100250{
Daniel Lezcano7b3da502011-06-15 15:45:12 +0200251 if (display_init(options->selectedwindow)) {
Daniel Lezcanoc08f1f22011-03-26 22:06:21 +0100252 printf("failed to initialize display\n");
253 return -1;
254 }
255
Daniel Lezcano271fd902011-06-15 15:45:12 +0200256 if (display_refresh())
257 return -1;
258
Daniel Lezcanob25be4a2011-06-15 15:45:12 +0200259 if (mainloop(options))
Daniel Lezcanoc08f1f22011-03-26 22:06:21 +0100260 return -1;
261
262 return 0;
263}
264
Daniel Lezcano6e0c9c82011-03-26 22:06:07 +0100265static struct powerdebug_options *powerdebug_init(void)
266{
267 struct powerdebug_options *options;
268
269 options = malloc(sizeof(*options));
270 if (!options)
271 return NULL;
272
273 memset(options, 0, sizeof(*options));
274
275 return options;
276}
277
Daniel Lezcano0051f4f2011-03-23 14:37:34 +0100278int main(int argc, char **argv)
279{
280 struct powerdebug_options *options;
Daniel Lezcanob25be4a2011-06-15 15:45:12 +0200281 int ret;
Daniel Lezcano0051f4f2011-03-23 14:37:34 +0100282
Daniel Lezcano6e0c9c82011-03-26 22:06:07 +0100283 options = powerdebug_init();
Daniel Lezcano0051f4f2011-03-23 14:37:34 +0100284 if (!options) {
Daniel Lezcano6e0c9c82011-03-26 22:06:07 +0100285 fprintf(stderr, "not enough memory to allocate options\n");
Daniel Lezcano0051f4f2011-03-23 14:37:34 +0100286 return 1;
287 }
288
Daniel Lezcanoc08f1f22011-03-26 22:06:21 +0100289 if (getoptions(argc, argv, options)) {
290 usage();
291 return 1;
292 }
293
Daniel Lezcanob25be4a2011-06-15 15:45:12 +0200294 if (regulator_init()) {
Daniel Lezcano4aab2fe2011-03-26 22:05:53 +0100295 printf("not enough memory to allocate regulators info\n");
Daniel Lezcano6e48fa42011-03-26 22:06:23 +0100296 options->regulators = false;
Daniel Lezcano4aab2fe2011-03-26 22:05:53 +0100297 }
Daniel Lezcano0051f4f2011-03-23 14:37:34 +0100298
Daniel Lezcanof0e06652011-03-26 22:06:19 +0100299 if (clock_init()) {
300 printf("failed to initialize clock details (check debugfs)\n");
301 options->clocks = false;
302 }
303
Daniel Lezcano3d0aef42011-06-15 15:45:12 +0200304 if (sensor_init()) {
305 printf("failed to initialize sensors\n");
306 options->sensors = false;
307 }
308
Daniel Lezcanob25be4a2011-06-15 15:45:12 +0200309 ret = options->dump ? powerdebug_dump(options) :
310 powerdebug_display(options);
Daniel Lezcano21c04d42011-03-26 22:06:04 +0100311
Daniel Lezcanoc08f1f22011-03-26 22:06:21 +0100312 return ret < 0;
Amit Arorae9e16b02010-08-03 10:15:20 +0530313}