blob: b778dd52485363c51342999ee536b3a5666fcc49 [file] [log] [blame]
Amit Arora728e0c92010-09-14 12:06:09 +05301/*******************************************************************************
2 * Copyright (C) 2010, Linaro
3 * Copyright (C) 2010, IBM Corporation
4 *
5 * This file is part of PowerDebug.
6 *
7 * All rights reserved. This program and the accompanying materials
8 * are made available under the terms of the Eclipse Public License v1.0
9 * which accompanies this distribution, and is available at
10 * http://www.eclipse.org/legal/epl-v10.html
11 *
12 * Contributors:
13 * Amit Arora <amit.arora@linaro.org> (IBM Corporation)
14 * - initial API and implementation
15 *******************************************************************************/
16
17#include "powerdebug.h"
Amit Aroraed3e5652010-10-27 12:02:53 +053018#include "clocks.h"
Amit Arora24ed7d12010-09-14 12:12:58 +053019
Amit Arora24ed7d12010-09-14 12:12:58 +053020static char clk_dir_path[PATH_MAX];
Amit Arora24ed7d12010-09-14 12:12:58 +053021static char clk_name[NAME_MAX];
Amit Aroraac4e8652010-11-09 11:16:53 +053022static int bold[MAX_LINES];
Amit Arora24ed7d12010-09-14 12:12:58 +053023
Amit Arora04f97742010-11-16 11:28:57 +053024int init_clock_details(void)
Amit Arora24ed7d12010-09-14 12:12:58 +053025{
Amit Arora6e774cd2010-10-28 11:31:24 +053026 char *path = debugfs_locate_mpoint();
27 struct stat buf;
Amit Aroraed3e5652010-10-27 12:02:53 +053028
Amit Arora6e774cd2010-10-28 11:31:24 +053029 if (path)
30 strcpy(clk_dir_path, path);
31 else {
Amit Arora81350772010-11-16 14:56:26 +053032 if (!dump) {
33 create_selectedwindow();
34 sprintf(clock_lines[0], "Unable to locate debugfs "
Amit Kucheriaa0adae42011-01-12 10:54:23 -060035 "mount point. Mount debugfs "
36 "and try again..\n");
Amit Arora81350772010-11-16 14:56:26 +053037 print_one_clock(0, clock_lines[0], 1, 0);
38 old_clock_line_no = 1;
39 return(1);
40 } else {
41 fprintf(stderr, "powerdebug: Unable to locate debugfs "
Amit Kucheriaa0adae42011-01-12 10:54:23 -060042 "mount point. Mount debugfs and try "
43 "again..\n");
Amit Arora81350772010-11-16 14:56:26 +053044 exit(1);
45 }
Amit Arora6e774cd2010-10-28 11:31:24 +053046 }
47 sprintf(clk_dir_path, "%s/clock", clk_dir_path);
Amit Arora59429a42010-11-16 11:30:20 +053048 //strcpy(clk_dir_path, "/debug/clock"); // Hardcoded for testing..
Amit Arora6e774cd2010-10-28 11:31:24 +053049 if (stat(clk_dir_path, &buf)) {
Amit Arora81350772010-11-16 14:56:26 +053050 if (!dump) {
51 create_selectedwindow();
52 sprintf(clock_lines[0], "Unable to find clock tree"
53 " information at %s.\n", clk_dir_path);
54 print_one_clock(0, clock_lines[0], 1, 0);
55 old_clock_line_no = 1;
56 return(1);
57 } else {
58 fprintf(stderr, "powerdebug: Unable to find clock tree"
59 " information at %s.\n", clk_dir_path);
60 exit(1);
61 }
Amit Arora6e774cd2010-10-28 11:31:24 +053062 }
63 strcpy(clk_name, "");
Amit Arora04f97742010-11-16 11:28:57 +053064 return(0);
Amit Arora24ed7d12010-09-14 12:12:58 +053065}
Amit Arora728e0c92010-09-14 12:06:09 +053066
67int get_int_from(char *file)
68{
Amit Arora6e774cd2010-10-28 11:31:24 +053069 FILE *filep;
70 char result[NAME_MAX];
71 int ret;
Amit Arora728e0c92010-09-14 12:06:09 +053072
Amit Arora6e774cd2010-10-28 11:31:24 +053073 filep = fopen(file, "r");
Amit Arora728e0c92010-09-14 12:06:09 +053074
Amit Arora6e774cd2010-10-28 11:31:24 +053075 if (!filep)
76 return -1; //TBD : What should we return on failure, here ?
Amit Arora728e0c92010-09-14 12:06:09 +053077
Amit Arora6e774cd2010-10-28 11:31:24 +053078 ret = fscanf(filep, "%s", result);
79 fclose(filep);
Amit Arora728e0c92010-09-14 12:06:09 +053080
Amit Arora6e774cd2010-10-28 11:31:24 +053081 return atoi(result);
Amit Arora728e0c92010-09-14 12:06:09 +053082}
83
Amit Arora3bd79162010-12-01 13:51:42 +053084void find_parents_for_clock(char *clkname, int complete)
85{
86 char name[256];
87
88 name[0] = '\0';
89 if (!complete) {
90 char str[256];
91
92 strcat(name, clkname);
93 sprintf(str, "Enter Clock Name : %s\n", name);
94 print_one_clock(2, str, 1, 0);
95 return;
96 }
97 sprintf(name, "Parents for \"%s\" Clock : \n", clkname);
98 print_one_clock(0, name, 1, 1);
99 dump_all_parents(clkname);
Amit Kucheriaa0adae42011-01-12 10:54:23 -0600100}
Amit Arora3bd79162010-12-01 13:51:42 +0530101
Amit Arora24ed7d12010-09-14 12:12:58 +0530102int read_and_print_clock_info(int verbose, int hrow, int selected)
103{
Amit Arora3bd79162010-12-01 13:51:42 +0530104 print_one_clock(0, "Reading Clock Tree ...", 1, 1);
Amit Aroraa06a7302010-12-02 15:59:37 +0530105
106 if (!old_clock_line_no || selected == REFRESH_WINDOW) {
107 destroy_clocks_info();
Amit Aroraac4e8652010-11-09 11:16:53 +0530108 read_clock_info(clk_dir_path);
Amit Aroraa06a7302010-12-02 15:59:37 +0530109 }
Amit Arora29cb7572010-10-05 17:40:29 +0530110
Amit Arora031263a2010-11-09 11:12:41 +0530111 if (!clocks_info->num_children) {
112 fprintf(stderr, "powerdebug: No clocks found. Exiting..\n");
113 exit(1);
Amit Arora6e774cd2010-10-28 11:31:24 +0530114 }
Amit Arora728e0c92010-09-14 12:06:09 +0530115
Amit Aroraa06a7302010-12-02 15:59:37 +0530116 if (selected == CLOCK_SELECTED)
117 selected = 1;
118 else
119 selected = 0;
120
Amit Aroraac4e8652010-11-09 11:16:53 +0530121 print_clock_info(verbose, hrow, selected);
Amit Aroraac4e8652010-11-09 11:16:53 +0530122 hrow = (hrow < old_clock_line_no) ? hrow : old_clock_line_no - 1;
123
124 return hrow;
125}
126
Amit Arora3bc8c922010-11-16 11:27:38 +0530127int calc_delta_screen_size(int hrow)
128{
Amit Arora51d1b9c2010-11-30 13:55:15 +0530129 if (hrow >= (maxy - 3))
130 return hrow - (maxy - 4);
Amit Arora3bc8c922010-11-16 11:27:38 +0530131
132 return 0;
133}
134
Amit Aroraac4e8652010-11-09 11:16:53 +0530135void print_clock_info(int verbose, int hrow, int selected)
136{
Amit Arora3bc8c922010-11-16 11:27:38 +0530137 int i, count = 0, delta;
Amit Aroraac4e8652010-11-09 11:16:53 +0530138
139 (void)verbose;
140
141 print_clock_header();
Amit Arora728e0c92010-09-14 12:06:09 +0530142
Amit Arora031263a2010-11-09 11:12:41 +0530143 for (i = 0; i < clocks_info->num_children; i++)
Amit Aroraac4e8652010-11-09 11:16:53 +0530144 add_clock_details_recur(clocks_info->children[i],
145 hrow, selected);
Amit Arora031263a2010-11-09 11:12:41 +0530146
Amit Arora3bc8c922010-11-16 11:27:38 +0530147 delta = calc_delta_screen_size(hrow);
148
149 while (clock_lines[count + delta] &&
Amit Kucheriaa0adae42011-01-12 10:54:23 -0600150 strcmp(clock_lines[count + delta], "")) {
Amit Arora3bc8c922010-11-16 11:27:38 +0530151 if (count < delta) {
152 count++;
153 continue;
154 }
155 print_one_clock(count - delta, clock_lines[count + delta],
156 bold[count + delta], (hrow == (count + delta)));
Amit Arora031263a2010-11-09 11:12:41 +0530157 count++;
158 }
159
Amit Aroraac4e8652010-11-09 11:16:53 +0530160 old_clock_line_no = clock_line_no;
Amit Arora031263a2010-11-09 11:12:41 +0530161 clock_line_no = 0;
Amit Arora031263a2010-11-09 11:12:41 +0530162}
163
Amit Aroraac4e8652010-11-09 11:16:53 +0530164void prepare_name_str(char *namestr, struct clock_info *clock)
165{
166 int i;
167
168 strcpy(namestr, "");
169 if (clock->level > 1)
170 for (i = 0; i < (clock->level - 1); i++)
171 strcat(namestr, " ");
172 strcat(namestr, clock->name);
173}
174
175void add_clock_details_recur(struct clock_info *clock, int hrow, int selected)
Amit Arora031263a2010-11-09 11:12:41 +0530176{
177 int i;
178 char *unit = " Hz";
179 char rate_str[64];
Amit Aroraac4e8652010-11-09 11:16:53 +0530180 char name_str[256];
Amit Arora031263a2010-11-09 11:12:41 +0530181 double drate = (double)clock->rate;
182
183 if (drate > 1000 && drate < 1000000) {
184 unit = "KHz";
185 drate /= 1000;
186 }
187 if (drate > 1000000) {
188 unit = "MHz";
189 drate /= 1000000;
190 }
191 if (clock->usecount)
192 bold[clock_line_no] = 1;
193 else
194 bold[clock_line_no] = 0;
195
196 sprintf(rate_str, "%.2f %s", drate, unit);
Amit Aroraac4e8652010-11-09 11:16:53 +0530197 prepare_name_str(name_str, clock);
198 sprintf(clock_lines[clock_line_no++], "%-55s %-4d %-12s %-12d %-12d",
199 name_str, clock->flags, rate_str, clock->usecount,
200 clock->num_children);
201
202 if (selected && (hrow == (clock_line_no - 1))) {
203 if (clock->expanded)
204 collapse_all_subclocks(clock);
205 else
206 clock->expanded = 1;
207 selected = 0;
208 }
Amit Arora031263a2010-11-09 11:12:41 +0530209
210 if (clock->expanded && clock->num_children)
211 for (i = 0; i < clock->num_children; i++)
Amit Aroraac4e8652010-11-09 11:16:53 +0530212 add_clock_details_recur(clock->children[i],
213 hrow, selected);
Amit Arora031263a2010-11-09 11:12:41 +0530214 strcpy(clock_lines[clock_line_no], "");
215}
216
Amit Aroraac4e8652010-11-09 11:16:53 +0530217void collapse_all_subclocks(struct clock_info *clock)
218{
219 int i;
220
221 clock->expanded = 0;
222 if (clock->num_children)
223 for (i = 0; i < clock->num_children; i++)
224 collapse_all_subclocks(clock->children[i]);
225}
226
Amit Arora031263a2010-11-09 11:12:41 +0530227void destroy_clocks_info(void)
228{
229 int i;
230
Amit Aroraa06a7302010-12-02 15:59:37 +0530231 if (!clocks_info)
232 return;
233
Amit Arora031263a2010-11-09 11:12:41 +0530234 if (clocks_info->num_children) {
235 for (i = (clocks_info->num_children - 1); i >= 0 ; i--) {
236 destroy_clocks_info_recur(clocks_info->children[i]);
237 if (!i) {
238 free(clocks_info->children);
239 clocks_info->children = NULL;
240 }
241 }
242 }
Amit Aroraa06a7302010-12-02 15:59:37 +0530243 clocks_info->num_children = 0;
Amit Arora031263a2010-11-09 11:12:41 +0530244 free(clocks_info);
245 clocks_info = NULL;
246}
247
248void destroy_clocks_info_recur(struct clock_info *clock)
249{
250 int i;
251
252 if (clock && clock->num_children) {
253 for (i = (clock->num_children - 1); i >= 0; i--) {
254 fflush(stdin);
255 destroy_clocks_info_recur(clock->children[i]);
256 if (!i) {
Amit Arora031263a2010-11-09 11:12:41 +0530257 free(clock->children);
258 clock->children = NULL;
259 clock->num_children = 0;
260 }
261 }
262 }
Amit Arora728e0c92010-09-14 12:06:09 +0530263}
Amit Arora0e512722010-10-01 12:24:16 +0530264
Amit Aroraf4fb8102010-11-30 13:55:50 +0530265void read_and_dump_clock_info_one(char *clk)
266{
Amit Arora3bd79162010-12-01 13:51:42 +0530267 printf("\nParents for \"%s\" Clock :\n\n", clk);
Amit Aroraf4fb8102010-11-30 13:55:50 +0530268 read_clock_info(clk_dir_path);
269 dump_all_parents(clk);
Amit Arora422c52f2010-12-02 16:22:29 +0530270 printf("\n\n");
Amit Aroraf4fb8102010-11-30 13:55:50 +0530271}
272
Amit Aroraac4e8652010-11-09 11:16:53 +0530273void read_and_dump_clock_info(int verbose)
Amit Arora0e512722010-10-01 12:24:16 +0530274{
Amit Arora6e774cd2010-10-28 11:31:24 +0530275 (void)verbose;
Amit Arora422c52f2010-12-02 16:22:29 +0530276 printf("\nClock Tree :\n");
Amit Arora6e774cd2010-10-28 11:31:24 +0530277 printf("**********\n");
278 read_clock_info(clk_dir_path);
Amit Aroraac4e8652010-11-09 11:16:53 +0530279 dump_clock_info(clocks_info, 1, 1);
Amit Arora422c52f2010-12-02 16:22:29 +0530280 printf("\n\n");
Amit Arora0e512722010-10-01 12:24:16 +0530281}
282
Amit Aroraeb6cba92010-10-25 16:03:21 +0530283void read_clock_info(char *clkpath)
Amit Arora0e512722010-10-01 12:24:16 +0530284{
Amit Arora6e774cd2010-10-28 11:31:24 +0530285 DIR *dir;
286 struct dirent *item;
287 char filename[NAME_MAX], clockname[NAME_MAX];
288 struct clock_info *child;
289 struct clock_info *cur;
Amit Arora0e512722010-10-01 12:24:16 +0530290
Amit Arora6e774cd2010-10-28 11:31:24 +0530291 dir = opendir(clkpath);
292 if (!dir)
293 return;
Amit Arora0e512722010-10-01 12:24:16 +0530294
Amit Arora6e774cd2010-10-28 11:31:24 +0530295 clocks_info = (struct clock_info *)malloc(sizeof(struct clock_info));
296 memset(clocks_info, 0, sizeof(clocks_info));
297 strcpy(clocks_info->name, "/");
Amit Aroraac4e8652010-11-09 11:16:53 +0530298 clocks_info->level = 0;
Amit Arora0e512722010-10-01 12:24:16 +0530299
Amit Arora6e774cd2010-10-28 11:31:24 +0530300 while ((item = readdir(dir))) {
301 /* skip hidden dirs except ".." */
302 if (item->d_name[0] == '.')
303 continue;
Amit Aroraeb6cba92010-10-25 16:03:21 +0530304
Amit Arora6e774cd2010-10-28 11:31:24 +0530305 strcpy(clockname, item->d_name);
306 sprintf(filename, "%s/%s", clkpath, item->d_name);
307 cur = (struct clock_info *)malloc(sizeof(struct clock_info));
Amit Aroraac4e8652010-11-09 11:16:53 +0530308 memset(cur, 0, sizeof(struct clock_info));
Amit Arora6e774cd2010-10-28 11:31:24 +0530309 strcpy(cur->name, clockname);
310 cur->parent = clocks_info;
Amit Arora031263a2010-11-09 11:12:41 +0530311 cur->num_children = 0;
312 cur->expanded = 0;
Amit Aroraac4e8652010-11-09 11:16:53 +0530313 cur->level = 1;
Amit Arora6e774cd2010-10-28 11:31:24 +0530314 insert_children(&clocks_info, cur);
315 child = read_clock_info_recur(filename, 2, cur);
316 }
317 closedir(dir);
Amit Aroraeb6cba92010-10-25 16:03:21 +0530318}
319
320struct clock_info *read_clock_info_recur(char *clkpath, int level,
Amit Kucheriaa0adae42011-01-12 10:54:23 -0600321 struct clock_info *parent)
Amit Aroraeb6cba92010-10-25 16:03:21 +0530322{
Amit Arora6e774cd2010-10-28 11:31:24 +0530323 int ret = 0;
324 DIR *dir;
325 char filename[PATH_MAX];
326 struct dirent *item;
327 struct clock_info *cur = NULL;
328 struct stat buf;
Amit Aroraeb6cba92010-10-25 16:03:21 +0530329
Amit Arora6e774cd2010-10-28 11:31:24 +0530330 dir = opendir(clkpath);
331 if (!dir)
332 return NULL;
Amit Aroraeb6cba92010-10-25 16:03:21 +0530333
Amit Arora6e774cd2010-10-28 11:31:24 +0530334 while ((item = readdir(dir))) {
335 struct clock_info *child;
336 /* skip hidden dirs except ".." */
337 if (item->d_name[0] == '.' )
338 continue;
Amit Arora0e512722010-10-01 12:24:16 +0530339
Amit Arora6e774cd2010-10-28 11:31:24 +0530340 sprintf(filename, "%s/%s", clkpath, item->d_name);
Amit Arora0e512722010-10-01 12:24:16 +0530341
Amit Arora6e774cd2010-10-28 11:31:24 +0530342 ret = stat(filename, &buf);
Amit Arora0e512722010-10-01 12:24:16 +0530343
Amit Arora6e774cd2010-10-28 11:31:24 +0530344 if (ret < 0) {
345 printf("Error doing a stat on %s\n", filename);
346 exit(1);
347 }
Amit Aroraeb6cba92010-10-25 16:03:21 +0530348
Amit Arora6e774cd2010-10-28 11:31:24 +0530349 if (S_ISREG(buf.st_mode)) {
350 if (!strcmp(item->d_name, "flags"))
351 parent->flags = get_int_from(filename);
352 if (!strcmp(item->d_name, "rate"))
353 parent->rate = get_int_from(filename);
354 if (!strcmp(item->d_name, "usecount"))
355 parent->usecount = get_int_from(filename);
356 continue;
357 }
Amit Aroraeb6cba92010-10-25 16:03:21 +0530358
Amit Arora6e774cd2010-10-28 11:31:24 +0530359 if (!S_ISDIR(buf.st_mode))
360 continue;
Amit Arora0e512722010-10-01 12:24:16 +0530361
Amit Arora6e774cd2010-10-28 11:31:24 +0530362 cur = (struct clock_info *)malloc(sizeof(struct clock_info));
363 memset(cur, 0, sizeof(cur));
364 strcpy(cur->name, item->d_name);
365 cur->children = NULL;
366 cur->parent = NULL;
367 cur->num_children = 0;
Amit Arora031263a2010-11-09 11:12:41 +0530368 cur->expanded = 0;
Amit Aroraac4e8652010-11-09 11:16:53 +0530369 cur->level = level;
Amit Arora6e774cd2010-10-28 11:31:24 +0530370 child = read_clock_info_recur(filename, level + 1, cur);
Amit Arora6e774cd2010-10-28 11:31:24 +0530371 insert_children(&parent, cur);
372 cur->parent = parent;
373 }
374 closedir(dir);
Amit Aroraeb6cba92010-10-25 16:03:21 +0530375
Amit Arora6e774cd2010-10-28 11:31:24 +0530376 return cur;
Amit Aroraeb6cba92010-10-25 16:03:21 +0530377}
378
379void insert_children(struct clock_info **parent, struct clock_info *clk)
380{
Amit Arora031263a2010-11-09 11:12:41 +0530381 if (!(*parent)->num_children || (*parent)->children == NULL) {
Amit Arora6e774cd2010-10-28 11:31:24 +0530382 (*parent)->children = (struct clock_info **)
Amit Kucheriaa0adae42011-01-12 10:54:23 -0600383 malloc(sizeof(struct clock_info *)*2);
Amit Arora6e774cd2010-10-28 11:31:24 +0530384 (*parent)->num_children = 0;
385 } else
386 (*parent)->children = (struct clock_info **)
Amit Kucheriaa0adae42011-01-12 10:54:23 -0600387 realloc((*parent)->children,
388 sizeof(struct clock_info *) *
389 ((*parent)->num_children + 2));
Amit Arora6e774cd2010-10-28 11:31:24 +0530390 if ((*parent)->num_children > 0)
391 (*parent)->children[(*parent)->num_children - 1]->last_child
Amit Kucheriaa0adae42011-01-12 10:54:23 -0600392 = 0;
Amit Arora6e774cd2010-10-28 11:31:24 +0530393 clk->last_child = 1;
394 (*parent)->children[(*parent)->num_children] = clk;
395 (*parent)->children[(*parent)->num_children + 1] = NULL;
396 (*parent)->num_children++;
Amit Aroraeb6cba92010-10-25 16:03:21 +0530397}
398
Amit Arora3bd79162010-12-01 13:51:42 +0530399void dump_parent(struct clock_info *clk, int line)
Amit Aroraf4fb8102010-11-30 13:55:50 +0530400{
401 char *unit = "Hz";
402 double drate;
Amit Arora3bd79162010-12-01 13:51:42 +0530403 static char spaces[64];
404 char str[256];
405 static int maxline;
406
407 if (maxline < line)
408 maxline = line;
Amit Kucheriaa0adae42011-01-12 10:54:23 -0600409
Amit Aroraf4fb8102010-11-30 13:55:50 +0530410 if (clk && clk->parent)
Amit Arora3bd79162010-12-01 13:51:42 +0530411 dump_parent(clk->parent, ++line);
Amit Aroraf4fb8102010-11-30 13:55:50 +0530412
413 drate = (double)clk->rate;
414 if (drate > 1000 && drate < 1000000) {
415 unit = "KHz";
416 drate /= 1000;
417 }
418 if (drate > 1000000) {
419 unit = "MHz";
420 drate /= 1000000;
421 }
422 if (clk == clocks_info) {
Amit Arora3bd79162010-12-01 13:51:42 +0530423 line++;
Amit Aroraf4fb8102010-11-30 13:55:50 +0530424 strcpy(spaces, "");
Amit Arora3bd79162010-12-01 13:51:42 +0530425 sprintf(str, "%s%s (flags:%d,usecount:%d,rate:%5.2f %s)\n",
426 spaces, clk->name, clk->flags, clk->usecount, drate,
427 unit);
Amit Aroraf4fb8102010-11-30 13:55:50 +0530428 } else {
429 if (!(clk->parent == clocks_info))
430 strcat(spaces, " ");
Amit Arora3bd79162010-12-01 13:51:42 +0530431 sprintf(str, "%s`- %s (flags:%d,usecount:%d,rate:%5.2f %s)\n",
432 spaces, clk->name, clk->flags, clk->usecount, drate,
433 unit);
Amit Aroraf4fb8102010-11-30 13:55:50 +0530434 }
Amit Arora3bd79162010-12-01 13:51:42 +0530435 if (dump)
436 //printf("line=%d:m%d:l%d %s", maxline - line + 2, maxline, line, str);
437 printf("%s", str);
438 else
439 print_one_clock(maxline - line + 2, str, 1, 0);
Amit Aroraf4fb8102010-11-30 13:55:50 +0530440}
441
442void dump_all_parents(char *clkarg)
443{
444 struct clock_info *clk;
445 char spaces[1024];
446
447 strcpy(spaces, "");
448
449 clk = find_clock(clocks_info, clkarg);
450
451 if (!clk)
452 printf("Clock NOT found!\n");
453 else {
454// while(clk && clk != clocks_info) {
455// printf("%s\n", clk->name);
456// strcat(spaces, " ");
457// clk = clk->parent;
458// printf("%s <-- ", spaces);
459// }
460// printf(" /\n");
Amit Arora3bd79162010-12-01 13:51:42 +0530461 dump_parent(clk, 1);
Amit Aroraf4fb8102010-11-30 13:55:50 +0530462 }
463}
464
465struct clock_info *find_clock(struct clock_info *clk, char *clkarg)
466{
467 int i;
468 struct clock_info *ret = clk;
469
470 if (!strcmp(clk->name, clkarg))
471 return ret;
472
473 if (clk->children) {
474 for (i = 0; i < clk->num_children; i++) {
475 if (!strcmp(clk->children[i]->name, clkarg))
476 return clk->children[i];
477 }
478 for (i = 0; i < clk->num_children; i++) {
479 ret = find_clock(clk->children[i], clkarg);
480 if (ret)
481 return ret;
482 }
483 }
484
485 return NULL;
486}
487
Amit Aroraeb6cba92010-10-25 16:03:21 +0530488
Amit Aroraac4e8652010-11-09 11:16:53 +0530489void dump_clock_info(struct clock_info *clk, int level, int bmp)
Amit Aroraeb6cba92010-10-25 16:03:21 +0530490{
Amit Arora6e774cd2010-10-28 11:31:24 +0530491 int i, j;
Amit Aroraeb6cba92010-10-25 16:03:21 +0530492
Amit Arora6e774cd2010-10-28 11:31:24 +0530493 if (!clk)
494 return;
Amit Aroraeb6cba92010-10-25 16:03:21 +0530495
Amit Arora6e774cd2010-10-28 11:31:24 +0530496 for (i = 1, j = 0; i < level; i++, j = (i - 1)) {
497 if (i == (level - 1)) {
498 if (clk->last_child)
499 printf("`-- ");
500 else
501 printf("|-- ");
502 } else {
503 if ((1<<j) & bmp)
504 printf("| ");
505 else
506 printf(" ");
507 }
508 }
Amit Arora031263a2010-11-09 11:12:41 +0530509
Amit Arora6e774cd2010-10-28 11:31:24 +0530510 if (clk == clocks_info)
511 printf("%s\n", clk->name);
512 else {
513 char *unit = "Hz";
514 double drate = (double)clk->rate;
Amit Kucheriaa0adae42011-01-12 10:54:23 -0600515
Amit Arora6e774cd2010-10-28 11:31:24 +0530516 if (drate > 1000 && drate < 1000000) {
517 unit = "KHz";
518 drate /= 1000;
519 }
520 if (drate > 1000000) {
521 unit = "MHz";
522 drate /= 1000000;
523 }
524 printf("%s (flags:%d,usecount:%d,rate:%5.2f %s)\n",
525 clk->name, clk->flags, clk->usecount, drate, unit);
Amit Arora6e774cd2010-10-28 11:31:24 +0530526 }
527 if (clk->children) {
528 int tbmp = bmp;
529 int xbmp = -1;
Amit Aroraeb6cba92010-10-25 16:03:21 +0530530
Amit Arora6e774cd2010-10-28 11:31:24 +0530531 if (clk->last_child) {
532 xbmp ^= 1 << (level - 2);
533
534 xbmp = tbmp & xbmp;
535 } else
536 xbmp = bmp;
537 for (i = 0; i < clk->num_children; i++) {
Amit Arora6e774cd2010-10-28 11:31:24 +0530538 tbmp = xbmp | (1 << level);
Amit Aroraac4e8652010-11-09 11:16:53 +0530539 dump_clock_info(clk->children[i], level + 1, tbmp);
Amit Arora6e774cd2010-10-28 11:31:24 +0530540 }
541 }
Amit Arora0e512722010-10-01 12:24:16 +0530542}
Amit Aroraed3e5652010-10-27 12:02:53 +0530543
544char *debugfs_locate_mpoint(void)
545{
546 int ret;
547 FILE *filep;
548 char **path;
549 char fsname[64];
550 struct statfs sfs;
551
552 path = likely_mpoints;
553 while (*path) {
Amit Arora6e774cd2010-10-28 11:31:24 +0530554 ret = statfs(*path, &sfs);
555 if (ret >= 0 && sfs.f_type == (long)DEBUGFS_MAGIC)
Amit Aroraed3e5652010-10-27 12:02:53 +0530556 return *path;
557 path++;
558 }
559
560 filep = fopen("/proc/mounts", "r");
561 if (filep == NULL) {
562 fprintf(stderr, "powerdebug: Error opening /proc/mounts.");
Amit Arora6e774cd2010-10-28 11:31:24 +0530563 exit(1);
564 }
Amit Aroraed3e5652010-10-27 12:02:53 +0530565
566 while (fscanf(filep, "%*s %s %s %*s %*d %*d\n",
Amit Kucheriaa0adae42011-01-12 10:54:23 -0600567 debugfs_mntpoint, fsname) == 2)
Amit Aroraed3e5652010-10-27 12:02:53 +0530568 if (!strcmp(fsname, "debugfs"))
569 break;
570 fclose(filep);
571
572 if (strcmp(fsname, "debugfs"))
573 return NULL;
574
575 return debugfs_mntpoint;
576}