blob: 9a76c19bf023f801d843c45a9118f187e3c2da72 [file] [log] [blame]
Amit Arora728e0c92010-09-14 12:06:09 +05301/*******************************************************************************
Amit Kucheriac0e17fc2011-01-17 09:35:52 +02002 * Copyright (C) 2010, Linaro Limited.
Amit Arora728e0c92010-09-14 12:06:09 +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
16#include "powerdebug.h"
Amit Aroraed3e5652010-10-27 12:02:53 +053017#include "clocks.h"
Amit Arora24ed7d12010-09-14 12:12:58 +053018
Amit Arora24ed7d12010-09-14 12:12:58 +053019static char clk_dir_path[PATH_MAX];
Amit Arora24ed7d12010-09-14 12:12:58 +053020static char clk_name[NAME_MAX];
Amit Aroraac4e8652010-11-09 11:16:53 +053021static int bold[MAX_LINES];
Amit Arora24ed7d12010-09-14 12:12:58 +053022
Amit Arora04f97742010-11-16 11:28:57 +053023int init_clock_details(void)
Amit Arora24ed7d12010-09-14 12:12:58 +053024{
Amit Arora6e774cd2010-10-28 11:31:24 +053025 char *path = debugfs_locate_mpoint();
26 struct stat buf;
Amit Aroraed3e5652010-10-27 12:02:53 +053027
Amit Arora6e774cd2010-10-28 11:31:24 +053028 if (path)
29 strcpy(clk_dir_path, path);
30 else {
Amit Arora81350772010-11-16 14:56:26 +053031 if (!dump) {
32 create_selectedwindow();
33 sprintf(clock_lines[0], "Unable to locate debugfs "
Amit Kucheriaa0adae42011-01-12 10:54:23 -060034 "mount point. Mount debugfs "
35 "and try again..\n");
Amit Arora81350772010-11-16 14:56:26 +053036 print_one_clock(0, clock_lines[0], 1, 0);
37 old_clock_line_no = 1;
38 return(1);
39 } else {
40 fprintf(stderr, "powerdebug: Unable to locate debugfs "
Amit Kucheriaa0adae42011-01-12 10:54:23 -060041 "mount point. Mount debugfs and try "
42 "again..\n");
Amit Arora81350772010-11-16 14:56:26 +053043 exit(1);
44 }
Amit Arora6e774cd2010-10-28 11:31:24 +053045 }
46 sprintf(clk_dir_path, "%s/clock", clk_dir_path);
Amit Arora59429a42010-11-16 11:30:20 +053047 //strcpy(clk_dir_path, "/debug/clock"); // Hardcoded for testing..
Amit Arora6e774cd2010-10-28 11:31:24 +053048 if (stat(clk_dir_path, &buf)) {
Amit Arora81350772010-11-16 14:56:26 +053049 if (!dump) {
50 create_selectedwindow();
51 sprintf(clock_lines[0], "Unable to find clock tree"
52 " information at %s.\n", clk_dir_path);
53 print_one_clock(0, clock_lines[0], 1, 0);
54 old_clock_line_no = 1;
55 return(1);
56 } else {
57 fprintf(stderr, "powerdebug: Unable to find clock tree"
58 " information at %s.\n", clk_dir_path);
59 exit(1);
60 }
Amit Arora6e774cd2010-10-28 11:31:24 +053061 }
62 strcpy(clk_name, "");
Amit Arora04f97742010-11-16 11:28:57 +053063 return(0);
Amit Arora24ed7d12010-09-14 12:12:58 +053064}
Amit Arora728e0c92010-09-14 12:06:09 +053065
66int get_int_from(char *file)
67{
Amit Arora6e774cd2010-10-28 11:31:24 +053068 FILE *filep;
69 char result[NAME_MAX];
70 int ret;
Amit Arora728e0c92010-09-14 12:06:09 +053071
Amit Arora6e774cd2010-10-28 11:31:24 +053072 filep = fopen(file, "r");
Amit Arora728e0c92010-09-14 12:06:09 +053073
Amit Arora6e774cd2010-10-28 11:31:24 +053074 if (!filep)
75 return -1; //TBD : What should we return on failure, here ?
Amit Arora728e0c92010-09-14 12:06:09 +053076
Amit Arora6e774cd2010-10-28 11:31:24 +053077 ret = fscanf(filep, "%s", result);
78 fclose(filep);
Amit Arora728e0c92010-09-14 12:06:09 +053079
Amit Arora6e774cd2010-10-28 11:31:24 +053080 return atoi(result);
Amit Arora728e0c92010-09-14 12:06:09 +053081}
82
Amit Arora3bd79162010-12-01 13:51:42 +053083void find_parents_for_clock(char *clkname, int complete)
84{
85 char name[256];
86
87 name[0] = '\0';
88 if (!complete) {
89 char str[256];
90
91 strcat(name, clkname);
92 sprintf(str, "Enter Clock Name : %s\n", name);
93 print_one_clock(2, str, 1, 0);
94 return;
95 }
96 sprintf(name, "Parents for \"%s\" Clock : \n", clkname);
97 print_one_clock(0, name, 1, 1);
98 dump_all_parents(clkname);
Amit Kucheriaa0adae42011-01-12 10:54:23 -060099}
Amit Arora3bd79162010-12-01 13:51:42 +0530100
Amit Arora24ed7d12010-09-14 12:12:58 +0530101int read_and_print_clock_info(int verbose, int hrow, int selected)
102{
Amit Arora3bd79162010-12-01 13:51:42 +0530103 print_one_clock(0, "Reading Clock Tree ...", 1, 1);
Amit Aroraa06a7302010-12-02 15:59:37 +0530104
105 if (!old_clock_line_no || selected == REFRESH_WINDOW) {
106 destroy_clocks_info();
Amit Aroraac4e8652010-11-09 11:16:53 +0530107 read_clock_info(clk_dir_path);
Amit Aroraa06a7302010-12-02 15:59:37 +0530108 }
Amit Arora29cb7572010-10-05 17:40:29 +0530109
Amit Arora031263a2010-11-09 11:12:41 +0530110 if (!clocks_info->num_children) {
111 fprintf(stderr, "powerdebug: No clocks found. Exiting..\n");
112 exit(1);
Amit Arora6e774cd2010-10-28 11:31:24 +0530113 }
Amit Arora728e0c92010-09-14 12:06:09 +0530114
Amit Aroraa06a7302010-12-02 15:59:37 +0530115 if (selected == CLOCK_SELECTED)
116 selected = 1;
117 else
118 selected = 0;
119
Amit Aroraac4e8652010-11-09 11:16:53 +0530120 print_clock_info(verbose, hrow, selected);
Amit Aroraac4e8652010-11-09 11:16:53 +0530121 hrow = (hrow < old_clock_line_no) ? hrow : old_clock_line_no - 1;
122
123 return hrow;
124}
125
Amit Arora3bc8c922010-11-16 11:27:38 +0530126int calc_delta_screen_size(int hrow)
127{
Amit Arora51d1b9c2010-11-30 13:55:15 +0530128 if (hrow >= (maxy - 3))
129 return hrow - (maxy - 4);
Amit Arora3bc8c922010-11-16 11:27:38 +0530130
131 return 0;
132}
133
Amit Aroraac4e8652010-11-09 11:16:53 +0530134void print_clock_info(int verbose, int hrow, int selected)
135{
Amit Arora3bc8c922010-11-16 11:27:38 +0530136 int i, count = 0, delta;
Amit Aroraac4e8652010-11-09 11:16:53 +0530137
138 (void)verbose;
139
140 print_clock_header();
Amit Arora728e0c92010-09-14 12:06:09 +0530141
Amit Arora031263a2010-11-09 11:12:41 +0530142 for (i = 0; i < clocks_info->num_children; i++)
Amit Aroraac4e8652010-11-09 11:16:53 +0530143 add_clock_details_recur(clocks_info->children[i],
144 hrow, selected);
Amit Arora031263a2010-11-09 11:12:41 +0530145
Amit Arora3bc8c922010-11-16 11:27:38 +0530146 delta = calc_delta_screen_size(hrow);
147
148 while (clock_lines[count + delta] &&
Amit Kucheriaa0adae42011-01-12 10:54:23 -0600149 strcmp(clock_lines[count + delta], "")) {
Amit Arora3bc8c922010-11-16 11:27:38 +0530150 if (count < delta) {
151 count++;
152 continue;
153 }
154 print_one_clock(count - delta, clock_lines[count + delta],
155 bold[count + delta], (hrow == (count + delta)));
Amit Arora031263a2010-11-09 11:12:41 +0530156 count++;
157 }
158
Amit Aroraac4e8652010-11-09 11:16:53 +0530159 old_clock_line_no = clock_line_no;
Amit Arora031263a2010-11-09 11:12:41 +0530160 clock_line_no = 0;
Amit Arora031263a2010-11-09 11:12:41 +0530161}
162
Amit Aroraac4e8652010-11-09 11:16:53 +0530163void prepare_name_str(char *namestr, struct clock_info *clock)
164{
165 int i;
166
167 strcpy(namestr, "");
168 if (clock->level > 1)
169 for (i = 0; i < (clock->level - 1); i++)
170 strcat(namestr, " ");
171 strcat(namestr, clock->name);
172}
173
174void add_clock_details_recur(struct clock_info *clock, int hrow, int selected)
Amit Arora031263a2010-11-09 11:12:41 +0530175{
176 int i;
177 char *unit = " Hz";
178 char rate_str[64];
Amit Aroraac4e8652010-11-09 11:16:53 +0530179 char name_str[256];
Amit Arora031263a2010-11-09 11:12:41 +0530180 double drate = (double)clock->rate;
181
182 if (drate > 1000 && drate < 1000000) {
183 unit = "KHz";
184 drate /= 1000;
185 }
186 if (drate > 1000000) {
187 unit = "MHz";
188 drate /= 1000000;
189 }
190 if (clock->usecount)
191 bold[clock_line_no] = 1;
192 else
193 bold[clock_line_no] = 0;
194
195 sprintf(rate_str, "%.2f %s", drate, unit);
Amit Aroraac4e8652010-11-09 11:16:53 +0530196 prepare_name_str(name_str, clock);
197 sprintf(clock_lines[clock_line_no++], "%-55s %-4d %-12s %-12d %-12d",
198 name_str, clock->flags, rate_str, clock->usecount,
199 clock->num_children);
200
201 if (selected && (hrow == (clock_line_no - 1))) {
202 if (clock->expanded)
203 collapse_all_subclocks(clock);
204 else
205 clock->expanded = 1;
206 selected = 0;
207 }
Amit Arora031263a2010-11-09 11:12:41 +0530208
209 if (clock->expanded && clock->num_children)
210 for (i = 0; i < clock->num_children; i++)
Amit Aroraac4e8652010-11-09 11:16:53 +0530211 add_clock_details_recur(clock->children[i],
212 hrow, selected);
Amit Arora031263a2010-11-09 11:12:41 +0530213 strcpy(clock_lines[clock_line_no], "");
214}
215
Amit Aroraac4e8652010-11-09 11:16:53 +0530216void collapse_all_subclocks(struct clock_info *clock)
217{
218 int i;
219
220 clock->expanded = 0;
221 if (clock->num_children)
222 for (i = 0; i < clock->num_children; i++)
223 collapse_all_subclocks(clock->children[i]);
224}
225
Amit Arora031263a2010-11-09 11:12:41 +0530226void destroy_clocks_info(void)
227{
228 int i;
229
Amit Aroraa06a7302010-12-02 15:59:37 +0530230 if (!clocks_info)
231 return;
232
Amit Arora031263a2010-11-09 11:12:41 +0530233 if (clocks_info->num_children) {
234 for (i = (clocks_info->num_children - 1); i >= 0 ; i--) {
235 destroy_clocks_info_recur(clocks_info->children[i]);
236 if (!i) {
237 free(clocks_info->children);
238 clocks_info->children = NULL;
239 }
240 }
241 }
Amit Aroraa06a7302010-12-02 15:59:37 +0530242 clocks_info->num_children = 0;
Amit Arora031263a2010-11-09 11:12:41 +0530243 free(clocks_info);
244 clocks_info = NULL;
245}
246
247void destroy_clocks_info_recur(struct clock_info *clock)
248{
249 int i;
250
251 if (clock && clock->num_children) {
252 for (i = (clock->num_children - 1); i >= 0; i--) {
253 fflush(stdin);
254 destroy_clocks_info_recur(clock->children[i]);
255 if (!i) {
Amit Arora031263a2010-11-09 11:12:41 +0530256 free(clock->children);
257 clock->children = NULL;
258 clock->num_children = 0;
259 }
260 }
261 }
Amit Arora728e0c92010-09-14 12:06:09 +0530262}
Amit Arora0e512722010-10-01 12:24:16 +0530263
Amit Aroraf4fb8102010-11-30 13:55:50 +0530264void read_and_dump_clock_info_one(char *clk)
265{
Amit Arora3bd79162010-12-01 13:51:42 +0530266 printf("\nParents for \"%s\" Clock :\n\n", clk);
Amit Aroraf4fb8102010-11-30 13:55:50 +0530267 read_clock_info(clk_dir_path);
268 dump_all_parents(clk);
Amit Arora422c52f2010-12-02 16:22:29 +0530269 printf("\n\n");
Amit Aroraf4fb8102010-11-30 13:55:50 +0530270}
271
Amit Aroraac4e8652010-11-09 11:16:53 +0530272void read_and_dump_clock_info(int verbose)
Amit Arora0e512722010-10-01 12:24:16 +0530273{
Amit Arora6e774cd2010-10-28 11:31:24 +0530274 (void)verbose;
Amit Arora422c52f2010-12-02 16:22:29 +0530275 printf("\nClock Tree :\n");
Amit Arora6e774cd2010-10-28 11:31:24 +0530276 printf("**********\n");
277 read_clock_info(clk_dir_path);
Amit Aroraac4e8652010-11-09 11:16:53 +0530278 dump_clock_info(clocks_info, 1, 1);
Amit Arora422c52f2010-12-02 16:22:29 +0530279 printf("\n\n");
Amit Arora0e512722010-10-01 12:24:16 +0530280}
281
Amit Aroraeb6cba92010-10-25 16:03:21 +0530282void read_clock_info(char *clkpath)
Amit Arora0e512722010-10-01 12:24:16 +0530283{
Amit Arora6e774cd2010-10-28 11:31:24 +0530284 DIR *dir;
285 struct dirent *item;
286 char filename[NAME_MAX], clockname[NAME_MAX];
287 struct clock_info *child;
288 struct clock_info *cur;
Amit Arora0e512722010-10-01 12:24:16 +0530289
Amit Arora6e774cd2010-10-28 11:31:24 +0530290 dir = opendir(clkpath);
291 if (!dir)
292 return;
Amit Arora0e512722010-10-01 12:24:16 +0530293
Amit Arora6e774cd2010-10-28 11:31:24 +0530294 clocks_info = (struct clock_info *)malloc(sizeof(struct clock_info));
295 memset(clocks_info, 0, sizeof(clocks_info));
296 strcpy(clocks_info->name, "/");
Amit Aroraac4e8652010-11-09 11:16:53 +0530297 clocks_info->level = 0;
Amit Arora0e512722010-10-01 12:24:16 +0530298
Amit Arora6e774cd2010-10-28 11:31:24 +0530299 while ((item = readdir(dir))) {
300 /* skip hidden dirs except ".." */
301 if (item->d_name[0] == '.')
302 continue;
Amit Aroraeb6cba92010-10-25 16:03:21 +0530303
Amit Arora6e774cd2010-10-28 11:31:24 +0530304 strcpy(clockname, item->d_name);
305 sprintf(filename, "%s/%s", clkpath, item->d_name);
306 cur = (struct clock_info *)malloc(sizeof(struct clock_info));
Amit Aroraac4e8652010-11-09 11:16:53 +0530307 memset(cur, 0, sizeof(struct clock_info));
Amit Arora6e774cd2010-10-28 11:31:24 +0530308 strcpy(cur->name, clockname);
309 cur->parent = clocks_info;
Amit Arora031263a2010-11-09 11:12:41 +0530310 cur->num_children = 0;
311 cur->expanded = 0;
Amit Aroraac4e8652010-11-09 11:16:53 +0530312 cur->level = 1;
Amit Arora6e774cd2010-10-28 11:31:24 +0530313 insert_children(&clocks_info, cur);
314 child = read_clock_info_recur(filename, 2, cur);
315 }
316 closedir(dir);
Amit Aroraeb6cba92010-10-25 16:03:21 +0530317}
318
319struct clock_info *read_clock_info_recur(char *clkpath, int level,
Amit Kucheriaa0adae42011-01-12 10:54:23 -0600320 struct clock_info *parent)
Amit Aroraeb6cba92010-10-25 16:03:21 +0530321{
Amit Arora6e774cd2010-10-28 11:31:24 +0530322 int ret = 0;
323 DIR *dir;
324 char filename[PATH_MAX];
325 struct dirent *item;
326 struct clock_info *cur = NULL;
327 struct stat buf;
Amit Aroraeb6cba92010-10-25 16:03:21 +0530328
Amit Arora6e774cd2010-10-28 11:31:24 +0530329 dir = opendir(clkpath);
330 if (!dir)
331 return NULL;
Amit Aroraeb6cba92010-10-25 16:03:21 +0530332
Amit Arora6e774cd2010-10-28 11:31:24 +0530333 while ((item = readdir(dir))) {
334 struct clock_info *child;
335 /* skip hidden dirs except ".." */
336 if (item->d_name[0] == '.' )
337 continue;
Amit Arora0e512722010-10-01 12:24:16 +0530338
Amit Arora6e774cd2010-10-28 11:31:24 +0530339 sprintf(filename, "%s/%s", clkpath, item->d_name);
Amit Arora0e512722010-10-01 12:24:16 +0530340
Amit Arora6e774cd2010-10-28 11:31:24 +0530341 ret = stat(filename, &buf);
Amit Arora0e512722010-10-01 12:24:16 +0530342
Amit Arora6e774cd2010-10-28 11:31:24 +0530343 if (ret < 0) {
344 printf("Error doing a stat on %s\n", filename);
345 exit(1);
346 }
Amit Aroraeb6cba92010-10-25 16:03:21 +0530347
Amit Arora6e774cd2010-10-28 11:31:24 +0530348 if (S_ISREG(buf.st_mode)) {
349 if (!strcmp(item->d_name, "flags"))
350 parent->flags = get_int_from(filename);
351 if (!strcmp(item->d_name, "rate"))
352 parent->rate = get_int_from(filename);
353 if (!strcmp(item->d_name, "usecount"))
354 parent->usecount = get_int_from(filename);
355 continue;
356 }
Amit Aroraeb6cba92010-10-25 16:03:21 +0530357
Amit Arora6e774cd2010-10-28 11:31:24 +0530358 if (!S_ISDIR(buf.st_mode))
359 continue;
Amit Arora0e512722010-10-01 12:24:16 +0530360
Amit Arora6e774cd2010-10-28 11:31:24 +0530361 cur = (struct clock_info *)malloc(sizeof(struct clock_info));
362 memset(cur, 0, sizeof(cur));
363 strcpy(cur->name, item->d_name);
364 cur->children = NULL;
365 cur->parent = NULL;
366 cur->num_children = 0;
Amit Arora031263a2010-11-09 11:12:41 +0530367 cur->expanded = 0;
Amit Aroraac4e8652010-11-09 11:16:53 +0530368 cur->level = level;
Amit Arora6e774cd2010-10-28 11:31:24 +0530369 child = read_clock_info_recur(filename, level + 1, cur);
Amit Arora6e774cd2010-10-28 11:31:24 +0530370 insert_children(&parent, cur);
371 cur->parent = parent;
372 }
373 closedir(dir);
Amit Aroraeb6cba92010-10-25 16:03:21 +0530374
Amit Arora6e774cd2010-10-28 11:31:24 +0530375 return cur;
Amit Aroraeb6cba92010-10-25 16:03:21 +0530376}
377
378void insert_children(struct clock_info **parent, struct clock_info *clk)
379{
Amit Arora031263a2010-11-09 11:12:41 +0530380 if (!(*parent)->num_children || (*parent)->children == NULL) {
Amit Arora6e774cd2010-10-28 11:31:24 +0530381 (*parent)->children = (struct clock_info **)
Amit Kucheriaa0adae42011-01-12 10:54:23 -0600382 malloc(sizeof(struct clock_info *)*2);
Amit Arora6e774cd2010-10-28 11:31:24 +0530383 (*parent)->num_children = 0;
384 } else
385 (*parent)->children = (struct clock_info **)
Amit Kucheriaa0adae42011-01-12 10:54:23 -0600386 realloc((*parent)->children,
387 sizeof(struct clock_info *) *
388 ((*parent)->num_children + 2));
Amit Arora6e774cd2010-10-28 11:31:24 +0530389 if ((*parent)->num_children > 0)
390 (*parent)->children[(*parent)->num_children - 1]->last_child
Amit Kucheriaa0adae42011-01-12 10:54:23 -0600391 = 0;
Amit Arora6e774cd2010-10-28 11:31:24 +0530392 clk->last_child = 1;
393 (*parent)->children[(*parent)->num_children] = clk;
394 (*parent)->children[(*parent)->num_children + 1] = NULL;
395 (*parent)->num_children++;
Amit Aroraeb6cba92010-10-25 16:03:21 +0530396}
397
Amit Arora3bd79162010-12-01 13:51:42 +0530398void dump_parent(struct clock_info *clk, int line)
Amit Aroraf4fb8102010-11-30 13:55:50 +0530399{
400 char *unit = "Hz";
401 double drate;
Amit Arora3bd79162010-12-01 13:51:42 +0530402 static char spaces[64];
403 char str[256];
404 static int maxline;
405
406 if (maxline < line)
407 maxline = line;
Amit Kucheriaa0adae42011-01-12 10:54:23 -0600408
Amit Aroraf4fb8102010-11-30 13:55:50 +0530409 if (clk && clk->parent)
Amit Arora3bd79162010-12-01 13:51:42 +0530410 dump_parent(clk->parent, ++line);
Amit Aroraf4fb8102010-11-30 13:55:50 +0530411
412 drate = (double)clk->rate;
413 if (drate > 1000 && drate < 1000000) {
414 unit = "KHz";
415 drate /= 1000;
416 }
417 if (drate > 1000000) {
418 unit = "MHz";
419 drate /= 1000000;
420 }
421 if (clk == clocks_info) {
Amit Arora3bd79162010-12-01 13:51:42 +0530422 line++;
Amit Aroraf4fb8102010-11-30 13:55:50 +0530423 strcpy(spaces, "");
Amit Arora3bd79162010-12-01 13:51:42 +0530424 sprintf(str, "%s%s (flags:%d,usecount:%d,rate:%5.2f %s)\n",
425 spaces, clk->name, clk->flags, clk->usecount, drate,
426 unit);
Amit Aroraf4fb8102010-11-30 13:55:50 +0530427 } else {
428 if (!(clk->parent == clocks_info))
429 strcat(spaces, " ");
Amit Arora3bd79162010-12-01 13:51:42 +0530430 sprintf(str, "%s`- %s (flags:%d,usecount:%d,rate:%5.2f %s)\n",
431 spaces, clk->name, clk->flags, clk->usecount, drate,
432 unit);
Amit Aroraf4fb8102010-11-30 13:55:50 +0530433 }
Amit Arora3bd79162010-12-01 13:51:42 +0530434 if (dump)
435 //printf("line=%d:m%d:l%d %s", maxline - line + 2, maxline, line, str);
436 printf("%s", str);
437 else
438 print_one_clock(maxline - line + 2, str, 1, 0);
Amit Aroraf4fb8102010-11-30 13:55:50 +0530439}
440
441void dump_all_parents(char *clkarg)
442{
443 struct clock_info *clk;
444 char spaces[1024];
445
446 strcpy(spaces, "");
447
448 clk = find_clock(clocks_info, clkarg);
449
450 if (!clk)
451 printf("Clock NOT found!\n");
452 else {
453// while(clk && clk != clocks_info) {
454// printf("%s\n", clk->name);
455// strcat(spaces, " ");
456// clk = clk->parent;
457// printf("%s <-- ", spaces);
458// }
459// printf(" /\n");
Amit Arora3bd79162010-12-01 13:51:42 +0530460 dump_parent(clk, 1);
Amit Aroraf4fb8102010-11-30 13:55:50 +0530461 }
462}
463
464struct clock_info *find_clock(struct clock_info *clk, char *clkarg)
465{
466 int i;
467 struct clock_info *ret = clk;
468
469 if (!strcmp(clk->name, clkarg))
470 return ret;
471
472 if (clk->children) {
473 for (i = 0; i < clk->num_children; i++) {
474 if (!strcmp(clk->children[i]->name, clkarg))
475 return clk->children[i];
476 }
477 for (i = 0; i < clk->num_children; i++) {
478 ret = find_clock(clk->children[i], clkarg);
479 if (ret)
480 return ret;
481 }
482 }
483
484 return NULL;
485}
486
Amit Aroraeb6cba92010-10-25 16:03:21 +0530487
Amit Aroraac4e8652010-11-09 11:16:53 +0530488void dump_clock_info(struct clock_info *clk, int level, int bmp)
Amit Aroraeb6cba92010-10-25 16:03:21 +0530489{
Amit Arora6e774cd2010-10-28 11:31:24 +0530490 int i, j;
Amit Aroraeb6cba92010-10-25 16:03:21 +0530491
Amit Arora6e774cd2010-10-28 11:31:24 +0530492 if (!clk)
493 return;
Amit Aroraeb6cba92010-10-25 16:03:21 +0530494
Amit Arora6e774cd2010-10-28 11:31:24 +0530495 for (i = 1, j = 0; i < level; i++, j = (i - 1)) {
496 if (i == (level - 1)) {
497 if (clk->last_child)
498 printf("`-- ");
499 else
500 printf("|-- ");
501 } else {
502 if ((1<<j) & bmp)
503 printf("| ");
504 else
505 printf(" ");
506 }
507 }
Amit Arora031263a2010-11-09 11:12:41 +0530508
Amit Arora6e774cd2010-10-28 11:31:24 +0530509 if (clk == clocks_info)
510 printf("%s\n", clk->name);
511 else {
512 char *unit = "Hz";
513 double drate = (double)clk->rate;
Amit Kucheriaa0adae42011-01-12 10:54:23 -0600514
Amit Arora6e774cd2010-10-28 11:31:24 +0530515 if (drate > 1000 && drate < 1000000) {
516 unit = "KHz";
517 drate /= 1000;
518 }
519 if (drate > 1000000) {
520 unit = "MHz";
521 drate /= 1000000;
522 }
523 printf("%s (flags:%d,usecount:%d,rate:%5.2f %s)\n",
524 clk->name, clk->flags, clk->usecount, drate, unit);
Amit Arora6e774cd2010-10-28 11:31:24 +0530525 }
526 if (clk->children) {
527 int tbmp = bmp;
528 int xbmp = -1;
Amit Aroraeb6cba92010-10-25 16:03:21 +0530529
Amit Arora6e774cd2010-10-28 11:31:24 +0530530 if (clk->last_child) {
531 xbmp ^= 1 << (level - 2);
532
533 xbmp = tbmp & xbmp;
534 } else
535 xbmp = bmp;
536 for (i = 0; i < clk->num_children; i++) {
Amit Arora6e774cd2010-10-28 11:31:24 +0530537 tbmp = xbmp | (1 << level);
Amit Aroraac4e8652010-11-09 11:16:53 +0530538 dump_clock_info(clk->children[i], level + 1, tbmp);
Amit Arora6e774cd2010-10-28 11:31:24 +0530539 }
540 }
Amit Arora0e512722010-10-01 12:24:16 +0530541}
Amit Aroraed3e5652010-10-27 12:02:53 +0530542
543char *debugfs_locate_mpoint(void)
544{
545 int ret;
546 FILE *filep;
547 char **path;
548 char fsname[64];
549 struct statfs sfs;
550
551 path = likely_mpoints;
552 while (*path) {
Amit Arora6e774cd2010-10-28 11:31:24 +0530553 ret = statfs(*path, &sfs);
554 if (ret >= 0 && sfs.f_type == (long)DEBUGFS_MAGIC)
Amit Aroraed3e5652010-10-27 12:02:53 +0530555 return *path;
556 path++;
557 }
558
559 filep = fopen("/proc/mounts", "r");
560 if (filep == NULL) {
561 fprintf(stderr, "powerdebug: Error opening /proc/mounts.");
Amit Arora6e774cd2010-10-28 11:31:24 +0530562 exit(1);
563 }
Amit Aroraed3e5652010-10-27 12:02:53 +0530564
565 while (fscanf(filep, "%*s %s %s %*s %*d %*d\n",
Amit Kucheriaa0adae42011-01-12 10:54:23 -0600566 debugfs_mntpoint, fsname) == 2)
Amit Aroraed3e5652010-10-27 12:02:53 +0530567 if (!strcmp(fsname, "debugfs"))
568 break;
569 fclose(filep);
570
571 if (strcmp(fsname, "debugfs"))
572 return NULL;
573
574 return debugfs_mntpoint;
575}