blob: ff7923538c968c105e383f40ce512aa52e24efb5 [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
Daniel Lezcano9dc3fb32011-03-26 22:06:08 +010016#include <stdio.h>
17#include <mntent.h>
18
Amit Arora728e0c92010-09-14 12:06:09 +053019#include "powerdebug.h"
Amit Aroraed3e5652010-10-27 12:02:53 +053020#include "clocks.h"
Amit Arora24ed7d12010-09-14 12:12:58 +053021
Amit Arora24ed7d12010-09-14 12:12:58 +053022static char clk_dir_path[PATH_MAX];
Amit Arora24ed7d12010-09-14 12:12:58 +053023static char clk_name[NAME_MAX];
Amit Aroraac4e8652010-11-09 11:16:53 +053024static int bold[MAX_LINES];
Amit Arora24ed7d12010-09-14 12:12:58 +053025
Daniel Lezcano9dc3fb32011-03-26 22:06:08 +010026static int locate_debugfs(char *clk_path)
27{
28 const char *mtab = "/proc/mounts";
29 struct mntent *mntent;
30 int ret = -1;
31 FILE *file = NULL;
32
33 file = setmntent(mtab, "r");
34 if (!file)
35 return -1;
36
37 while ((mntent = getmntent(file))) {
38
39 if (strcmp(mntent->mnt_type, "debugfs"))
40 continue;
41
42 strcpy(clk_path, mntent->mnt_dir);
43 ret = 0;
44 break;
45 }
46
47 fclose(file);
48 return ret;
49}
50
Daniel Lezcano558a6d52011-03-23 14:37:41 +010051int init_clock_details(bool dump, int selectedwindow)
Amit Arora24ed7d12010-09-14 12:12:58 +053052{
Amit Arora6e774cd2010-10-28 11:31:24 +053053 struct stat buf;
Amit Aroraed3e5652010-10-27 12:02:53 +053054
Daniel Lezcano9dc3fb32011-03-26 22:06:08 +010055 if (locate_debugfs(clk_dir_path)) {
Amit Arora81350772010-11-16 14:56:26 +053056 if (!dump) {
Daniel Lezcano558a6d52011-03-23 14:37:41 +010057 create_selectedwindow(selectedwindow);
Amit Arora81350772010-11-16 14:56:26 +053058 sprintf(clock_lines[0], "Unable to locate debugfs "
Amit Kucheriaa0adae42011-01-12 10:54:23 -060059 "mount point. Mount debugfs "
60 "and try again..\n");
Amit Arora81350772010-11-16 14:56:26 +053061 print_one_clock(0, clock_lines[0], 1, 0);
62 old_clock_line_no = 1;
63 return(1);
64 } else {
65 fprintf(stderr, "powerdebug: Unable to locate debugfs "
Amit Kucheriaa0adae42011-01-12 10:54:23 -060066 "mount point. Mount debugfs and try "
67 "again..\n");
Amit Arora81350772010-11-16 14:56:26 +053068 exit(1);
69 }
Amit Arora6e774cd2010-10-28 11:31:24 +053070 }
Daniel Lezcano9dc3fb32011-03-26 22:06:08 +010071
Amit Arora6e774cd2010-10-28 11:31:24 +053072 sprintf(clk_dir_path, "%s/clock", clk_dir_path);
Amit Arora59429a42010-11-16 11:30:20 +053073 //strcpy(clk_dir_path, "/debug/clock"); // Hardcoded for testing..
Amit Arora6e774cd2010-10-28 11:31:24 +053074 if (stat(clk_dir_path, &buf)) {
Amit Arora81350772010-11-16 14:56:26 +053075 if (!dump) {
Daniel Lezcano558a6d52011-03-23 14:37:41 +010076 create_selectedwindow(selectedwindow);
Amit Arora81350772010-11-16 14:56:26 +053077 sprintf(clock_lines[0], "Unable to find clock tree"
78 " information at %s.\n", clk_dir_path);
79 print_one_clock(0, clock_lines[0], 1, 0);
80 old_clock_line_no = 1;
81 return(1);
82 } else {
83 fprintf(stderr, "powerdebug: Unable to find clock tree"
84 " information at %s.\n", clk_dir_path);
85 exit(1);
86 }
Amit Arora6e774cd2010-10-28 11:31:24 +053087 }
88 strcpy(clk_name, "");
Amit Arora04f97742010-11-16 11:28:57 +053089 return(0);
Amit Arora24ed7d12010-09-14 12:12:58 +053090}
Amit Arora728e0c92010-09-14 12:06:09 +053091
92int get_int_from(char *file)
93{
Amit Arora6e774cd2010-10-28 11:31:24 +053094 FILE *filep;
95 char result[NAME_MAX];
96 int ret;
Amit Arora728e0c92010-09-14 12:06:09 +053097
Amit Arora6e774cd2010-10-28 11:31:24 +053098 filep = fopen(file, "r");
Amit Arora728e0c92010-09-14 12:06:09 +053099
Amit Arora6e774cd2010-10-28 11:31:24 +0530100 if (!filep)
101 return -1; //TBD : What should we return on failure, here ?
Amit Arora728e0c92010-09-14 12:06:09 +0530102
Amit Arora6e774cd2010-10-28 11:31:24 +0530103 ret = fscanf(filep, "%s", result);
104 fclose(filep);
Amit Arora728e0c92010-09-14 12:06:09 +0530105
Amit Arora6e774cd2010-10-28 11:31:24 +0530106 return atoi(result);
Amit Arora728e0c92010-09-14 12:06:09 +0530107}
108
Daniel Lezcanoc6718332011-03-23 14:37:39 +0100109static void dump_parent(struct clock_info *clk, int line, bool dump)
110{
111 char *unit = "Hz";
112 double drate;
113 static char spaces[64];
114 char str[256];
115 static int maxline;
116
117 if (maxline < line)
118 maxline = line;
119
120 if (clk && clk->parent)
121 dump_parent(clk->parent, ++line, dump);
122
123 drate = (double)clk->rate;
124 if (drate > 1000 && drate < 1000000) {
125 unit = "KHz";
126 drate /= 1000;
127 }
128 if (drate > 1000000) {
129 unit = "MHz";
130 drate /= 1000000;
131 }
132 if (clk == clocks_info) {
133 line++;
134 strcpy(spaces, "");
135 sprintf(str, "%s%s (flags:%d,usecount:%d,rate:%5.2f %s)\n",
136 spaces, clk->name, clk->flags, clk->usecount, drate,
137 unit);
138 } else {
139 if (!(clk->parent == clocks_info))
140 strcat(spaces, " ");
141 sprintf(str, "%s`- %s (flags:%d,usecount:%d,rate:%5.2f %s)\n",
142 spaces, clk->name, clk->flags, clk->usecount, drate,
143 unit);
144 }
145 if (dump)
146 //printf("line=%d:m%d:l%d %s", maxline - line + 2, maxline, line, str);
147 printf("%s", str);
148 else
149 print_one_clock(maxline - line + 2, str, 1, 0);
150}
151
152static void dump_all_parents(char *clkarg, bool dump)
153{
154 struct clock_info *clk;
155 char spaces[1024];
156
157 strcpy(spaces, "");
158
159 clk = find_clock(clocks_info, clkarg);
160
161 if (!clk)
162 printf("Clock NOT found!\n");
163 else {
164 /* while(clk && clk != clocks_info) { */
165 /* printf("%s\n", clk->name); */
166 /* strcat(spaces, " "); */
167 /* clk = clk->parent; */
168 /* printf("%s <-- ", spaces); */
169 /* } */
170 /* printf(" /\n"); */
171 dump_parent(clk, 1, dump);
172 }
173}
174
Daniel Lezcano897f7332011-03-26 22:06:06 +0100175void find_parents_for_clock(char *clkname, int complete)
Amit Arora3bd79162010-12-01 13:51:42 +0530176{
177 char name[256];
178
179 name[0] = '\0';
180 if (!complete) {
181 char str[256];
182
183 strcat(name, clkname);
184 sprintf(str, "Enter Clock Name : %s\n", name);
185 print_one_clock(2, str, 1, 0);
186 return;
187 }
188 sprintf(name, "Parents for \"%s\" Clock : \n", clkname);
189 print_one_clock(0, name, 1, 1);
Daniel Lezcano897f7332011-03-26 22:06:06 +0100190 dump_all_parents(clkname, false);
Amit Kucheriaa0adae42011-01-12 10:54:23 -0600191}
Amit Arora3bd79162010-12-01 13:51:42 +0530192
Amit Arora24ed7d12010-09-14 12:12:58 +0530193int read_and_print_clock_info(int verbose, int hrow, int selected)
194{
Amit Arora3bd79162010-12-01 13:51:42 +0530195 print_one_clock(0, "Reading Clock Tree ...", 1, 1);
Amit Aroraa06a7302010-12-02 15:59:37 +0530196
197 if (!old_clock_line_no || selected == REFRESH_WINDOW) {
198 destroy_clocks_info();
Amit Aroraac4e8652010-11-09 11:16:53 +0530199 read_clock_info(clk_dir_path);
Amit Aroraa06a7302010-12-02 15:59:37 +0530200 }
Amit Arora29cb7572010-10-05 17:40:29 +0530201
Amit Arora031263a2010-11-09 11:12:41 +0530202 if (!clocks_info->num_children) {
203 fprintf(stderr, "powerdebug: No clocks found. Exiting..\n");
204 exit(1);
Amit Arora6e774cd2010-10-28 11:31:24 +0530205 }
Amit Arora728e0c92010-09-14 12:06:09 +0530206
Amit Aroraa06a7302010-12-02 15:59:37 +0530207 if (selected == CLOCK_SELECTED)
208 selected = 1;
209 else
210 selected = 0;
211
Amit Aroraac4e8652010-11-09 11:16:53 +0530212 print_clock_info(verbose, hrow, selected);
Amit Aroraac4e8652010-11-09 11:16:53 +0530213 hrow = (hrow < old_clock_line_no) ? hrow : old_clock_line_no - 1;
214
215 return hrow;
216}
217
Amit Arora3bc8c922010-11-16 11:27:38 +0530218int calc_delta_screen_size(int hrow)
219{
Amit Arora51d1b9c2010-11-30 13:55:15 +0530220 if (hrow >= (maxy - 3))
221 return hrow - (maxy - 4);
Amit Arora3bc8c922010-11-16 11:27:38 +0530222
223 return 0;
224}
225
Amit Aroraac4e8652010-11-09 11:16:53 +0530226void print_clock_info(int verbose, int hrow, int selected)
227{
Amit Arora3bc8c922010-11-16 11:27:38 +0530228 int i, count = 0, delta;
Amit Aroraac4e8652010-11-09 11:16:53 +0530229
230 (void)verbose;
231
232 print_clock_header();
Amit Arora728e0c92010-09-14 12:06:09 +0530233
Amit Arora031263a2010-11-09 11:12:41 +0530234 for (i = 0; i < clocks_info->num_children; i++)
Amit Aroraac4e8652010-11-09 11:16:53 +0530235 add_clock_details_recur(clocks_info->children[i],
236 hrow, selected);
Amit Arora031263a2010-11-09 11:12:41 +0530237
Amit Arora3bc8c922010-11-16 11:27:38 +0530238 delta = calc_delta_screen_size(hrow);
239
240 while (clock_lines[count + delta] &&
Amit Kucheriaa0adae42011-01-12 10:54:23 -0600241 strcmp(clock_lines[count + delta], "")) {
Amit Arora3bc8c922010-11-16 11:27:38 +0530242 if (count < delta) {
243 count++;
244 continue;
245 }
246 print_one_clock(count - delta, clock_lines[count + delta],
247 bold[count + delta], (hrow == (count + delta)));
Amit Arora031263a2010-11-09 11:12:41 +0530248 count++;
249 }
250
Amit Aroraac4e8652010-11-09 11:16:53 +0530251 old_clock_line_no = clock_line_no;
Amit Arora031263a2010-11-09 11:12:41 +0530252 clock_line_no = 0;
Amit Arora031263a2010-11-09 11:12:41 +0530253}
254
Amit Aroraac4e8652010-11-09 11:16:53 +0530255void prepare_name_str(char *namestr, struct clock_info *clock)
256{
257 int i;
258
259 strcpy(namestr, "");
260 if (clock->level > 1)
261 for (i = 0; i < (clock->level - 1); i++)
262 strcat(namestr, " ");
263 strcat(namestr, clock->name);
264}
265
266void add_clock_details_recur(struct clock_info *clock, int hrow, int selected)
Amit Arora031263a2010-11-09 11:12:41 +0530267{
268 int i;
269 char *unit = " Hz";
270 char rate_str[64];
Amit Aroraac4e8652010-11-09 11:16:53 +0530271 char name_str[256];
Amit Arora031263a2010-11-09 11:12:41 +0530272 double drate = (double)clock->rate;
273
274 if (drate > 1000 && drate < 1000000) {
275 unit = "KHz";
276 drate /= 1000;
277 }
278 if (drate > 1000000) {
279 unit = "MHz";
280 drate /= 1000000;
281 }
282 if (clock->usecount)
283 bold[clock_line_no] = 1;
284 else
285 bold[clock_line_no] = 0;
286
287 sprintf(rate_str, "%.2f %s", drate, unit);
Amit Aroraac4e8652010-11-09 11:16:53 +0530288 prepare_name_str(name_str, clock);
289 sprintf(clock_lines[clock_line_no++], "%-55s %-4d %-12s %-12d %-12d",
290 name_str, clock->flags, rate_str, clock->usecount,
291 clock->num_children);
292
293 if (selected && (hrow == (clock_line_no - 1))) {
294 if (clock->expanded)
295 collapse_all_subclocks(clock);
296 else
297 clock->expanded = 1;
298 selected = 0;
299 }
Amit Arora031263a2010-11-09 11:12:41 +0530300
301 if (clock->expanded && clock->num_children)
302 for (i = 0; i < clock->num_children; i++)
Amit Aroraac4e8652010-11-09 11:16:53 +0530303 add_clock_details_recur(clock->children[i],
304 hrow, selected);
Amit Arora031263a2010-11-09 11:12:41 +0530305 strcpy(clock_lines[clock_line_no], "");
306}
307
Amit Aroraac4e8652010-11-09 11:16:53 +0530308void collapse_all_subclocks(struct clock_info *clock)
309{
310 int i;
311
312 clock->expanded = 0;
313 if (clock->num_children)
314 for (i = 0; i < clock->num_children; i++)
315 collapse_all_subclocks(clock->children[i]);
316}
317
Amit Arora031263a2010-11-09 11:12:41 +0530318void destroy_clocks_info(void)
319{
320 int i;
321
Amit Aroraa06a7302010-12-02 15:59:37 +0530322 if (!clocks_info)
323 return;
324
Amit Arora031263a2010-11-09 11:12:41 +0530325 if (clocks_info->num_children) {
326 for (i = (clocks_info->num_children - 1); i >= 0 ; i--) {
327 destroy_clocks_info_recur(clocks_info->children[i]);
328 if (!i) {
329 free(clocks_info->children);
330 clocks_info->children = NULL;
331 }
332 }
333 }
Amit Aroraa06a7302010-12-02 15:59:37 +0530334 clocks_info->num_children = 0;
Amit Arora031263a2010-11-09 11:12:41 +0530335 free(clocks_info);
336 clocks_info = NULL;
337}
338
339void destroy_clocks_info_recur(struct clock_info *clock)
340{
341 int i;
342
343 if (clock && clock->num_children) {
344 for (i = (clock->num_children - 1); i >= 0; i--) {
345 fflush(stdin);
346 destroy_clocks_info_recur(clock->children[i]);
347 if (!i) {
Amit Arora031263a2010-11-09 11:12:41 +0530348 free(clock->children);
349 clock->children = NULL;
350 clock->num_children = 0;
351 }
352 }
353 }
Amit Arora728e0c92010-09-14 12:06:09 +0530354}
Amit Arora0e512722010-10-01 12:24:16 +0530355
Daniel Lezcanoc6718332011-03-23 14:37:39 +0100356void read_and_dump_clock_info_one(char *clk, bool dump)
Amit Aroraf4fb8102010-11-30 13:55:50 +0530357{
Amit Arora3bd79162010-12-01 13:51:42 +0530358 printf("\nParents for \"%s\" Clock :\n\n", clk);
Amit Aroraf4fb8102010-11-30 13:55:50 +0530359 read_clock_info(clk_dir_path);
Daniel Lezcanoc6718332011-03-23 14:37:39 +0100360 dump_all_parents(clk, dump);
Amit Arora422c52f2010-12-02 16:22:29 +0530361 printf("\n\n");
Amit Aroraf4fb8102010-11-30 13:55:50 +0530362}
363
Amit Aroraac4e8652010-11-09 11:16:53 +0530364void read_and_dump_clock_info(int verbose)
Amit Arora0e512722010-10-01 12:24:16 +0530365{
Amit Arora6e774cd2010-10-28 11:31:24 +0530366 (void)verbose;
Amit Arora422c52f2010-12-02 16:22:29 +0530367 printf("\nClock Tree :\n");
Amit Arora6e774cd2010-10-28 11:31:24 +0530368 printf("**********\n");
369 read_clock_info(clk_dir_path);
Amit Aroraac4e8652010-11-09 11:16:53 +0530370 dump_clock_info(clocks_info, 1, 1);
Amit Arora422c52f2010-12-02 16:22:29 +0530371 printf("\n\n");
Amit Arora0e512722010-10-01 12:24:16 +0530372}
373
Amit Aroraeb6cba92010-10-25 16:03:21 +0530374void read_clock_info(char *clkpath)
Amit Arora0e512722010-10-01 12:24:16 +0530375{
Amit Arora6e774cd2010-10-28 11:31:24 +0530376 DIR *dir;
377 struct dirent *item;
378 char filename[NAME_MAX], clockname[NAME_MAX];
379 struct clock_info *child;
380 struct clock_info *cur;
Amit Arora0e512722010-10-01 12:24:16 +0530381
Amit Arora6e774cd2010-10-28 11:31:24 +0530382 dir = opendir(clkpath);
383 if (!dir)
384 return;
Amit Arora0e512722010-10-01 12:24:16 +0530385
Amit Arora6e774cd2010-10-28 11:31:24 +0530386 clocks_info = (struct clock_info *)malloc(sizeof(struct clock_info));
387 memset(clocks_info, 0, sizeof(clocks_info));
388 strcpy(clocks_info->name, "/");
Amit Aroraac4e8652010-11-09 11:16:53 +0530389 clocks_info->level = 0;
Amit Arora0e512722010-10-01 12:24:16 +0530390
Amit Arora6e774cd2010-10-28 11:31:24 +0530391 while ((item = readdir(dir))) {
392 /* skip hidden dirs except ".." */
393 if (item->d_name[0] == '.')
394 continue;
Amit Aroraeb6cba92010-10-25 16:03:21 +0530395
Amit Arora6e774cd2010-10-28 11:31:24 +0530396 strcpy(clockname, item->d_name);
397 sprintf(filename, "%s/%s", clkpath, item->d_name);
398 cur = (struct clock_info *)malloc(sizeof(struct clock_info));
Amit Aroraac4e8652010-11-09 11:16:53 +0530399 memset(cur, 0, sizeof(struct clock_info));
Amit Arora6e774cd2010-10-28 11:31:24 +0530400 strcpy(cur->name, clockname);
401 cur->parent = clocks_info;
Amit Arora031263a2010-11-09 11:12:41 +0530402 cur->num_children = 0;
403 cur->expanded = 0;
Amit Aroraac4e8652010-11-09 11:16:53 +0530404 cur->level = 1;
Amit Arora6e774cd2010-10-28 11:31:24 +0530405 insert_children(&clocks_info, cur);
406 child = read_clock_info_recur(filename, 2, cur);
407 }
408 closedir(dir);
Amit Aroraeb6cba92010-10-25 16:03:21 +0530409}
410
411struct clock_info *read_clock_info_recur(char *clkpath, int level,
Amit Kucheriaa0adae42011-01-12 10:54:23 -0600412 struct clock_info *parent)
Amit Aroraeb6cba92010-10-25 16:03:21 +0530413{
Amit Arora6e774cd2010-10-28 11:31:24 +0530414 int ret = 0;
415 DIR *dir;
416 char filename[PATH_MAX];
417 struct dirent *item;
418 struct clock_info *cur = NULL;
419 struct stat buf;
Amit Aroraeb6cba92010-10-25 16:03:21 +0530420
Amit Arora6e774cd2010-10-28 11:31:24 +0530421 dir = opendir(clkpath);
422 if (!dir)
423 return NULL;
Amit Aroraeb6cba92010-10-25 16:03:21 +0530424
Amit Arora6e774cd2010-10-28 11:31:24 +0530425 while ((item = readdir(dir))) {
426 struct clock_info *child;
427 /* skip hidden dirs except ".." */
428 if (item->d_name[0] == '.' )
429 continue;
Amit Arora0e512722010-10-01 12:24:16 +0530430
Amit Arora6e774cd2010-10-28 11:31:24 +0530431 sprintf(filename, "%s/%s", clkpath, item->d_name);
Amit Arora0e512722010-10-01 12:24:16 +0530432
Amit Arora6e774cd2010-10-28 11:31:24 +0530433 ret = stat(filename, &buf);
Amit Arora0e512722010-10-01 12:24:16 +0530434
Amit Arora6e774cd2010-10-28 11:31:24 +0530435 if (ret < 0) {
436 printf("Error doing a stat on %s\n", filename);
437 exit(1);
438 }
Amit Aroraeb6cba92010-10-25 16:03:21 +0530439
Amit Arora6e774cd2010-10-28 11:31:24 +0530440 if (S_ISREG(buf.st_mode)) {
441 if (!strcmp(item->d_name, "flags"))
442 parent->flags = get_int_from(filename);
443 if (!strcmp(item->d_name, "rate"))
444 parent->rate = get_int_from(filename);
445 if (!strcmp(item->d_name, "usecount"))
446 parent->usecount = get_int_from(filename);
447 continue;
448 }
Amit Aroraeb6cba92010-10-25 16:03:21 +0530449
Amit Arora6e774cd2010-10-28 11:31:24 +0530450 if (!S_ISDIR(buf.st_mode))
451 continue;
Amit Arora0e512722010-10-01 12:24:16 +0530452
Amit Arora6e774cd2010-10-28 11:31:24 +0530453 cur = (struct clock_info *)malloc(sizeof(struct clock_info));
454 memset(cur, 0, sizeof(cur));
455 strcpy(cur->name, item->d_name);
456 cur->children = NULL;
457 cur->parent = NULL;
458 cur->num_children = 0;
Amit Arora031263a2010-11-09 11:12:41 +0530459 cur->expanded = 0;
Amit Aroraac4e8652010-11-09 11:16:53 +0530460 cur->level = level;
Amit Arora6e774cd2010-10-28 11:31:24 +0530461 child = read_clock_info_recur(filename, level + 1, cur);
Amit Arora6e774cd2010-10-28 11:31:24 +0530462 insert_children(&parent, cur);
463 cur->parent = parent;
464 }
465 closedir(dir);
Amit Aroraeb6cba92010-10-25 16:03:21 +0530466
Amit Arora6e774cd2010-10-28 11:31:24 +0530467 return cur;
Amit Aroraeb6cba92010-10-25 16:03:21 +0530468}
469
470void insert_children(struct clock_info **parent, struct clock_info *clk)
471{
Amit Arora031263a2010-11-09 11:12:41 +0530472 if (!(*parent)->num_children || (*parent)->children == NULL) {
Amit Arora6e774cd2010-10-28 11:31:24 +0530473 (*parent)->children = (struct clock_info **)
Amit Kucheriaa0adae42011-01-12 10:54:23 -0600474 malloc(sizeof(struct clock_info *)*2);
Amit Arora6e774cd2010-10-28 11:31:24 +0530475 (*parent)->num_children = 0;
476 } else
477 (*parent)->children = (struct clock_info **)
Amit Kucheriaa0adae42011-01-12 10:54:23 -0600478 realloc((*parent)->children,
479 sizeof(struct clock_info *) *
480 ((*parent)->num_children + 2));
Amit Arora6e774cd2010-10-28 11:31:24 +0530481 if ((*parent)->num_children > 0)
482 (*parent)->children[(*parent)->num_children - 1]->last_child
Amit Kucheriaa0adae42011-01-12 10:54:23 -0600483 = 0;
Amit Arora6e774cd2010-10-28 11:31:24 +0530484 clk->last_child = 1;
485 (*parent)->children[(*parent)->num_children] = clk;
486 (*parent)->children[(*parent)->num_children + 1] = NULL;
487 (*parent)->num_children++;
Amit Aroraeb6cba92010-10-25 16:03:21 +0530488}
489
Amit Aroraf4fb8102010-11-30 13:55:50 +0530490struct clock_info *find_clock(struct clock_info *clk, char *clkarg)
491{
492 int i;
493 struct clock_info *ret = clk;
494
495 if (!strcmp(clk->name, clkarg))
496 return ret;
497
498 if (clk->children) {
499 for (i = 0; i < clk->num_children; i++) {
500 if (!strcmp(clk->children[i]->name, clkarg))
501 return clk->children[i];
502 }
503 for (i = 0; i < clk->num_children; i++) {
504 ret = find_clock(clk->children[i], clkarg);
505 if (ret)
506 return ret;
507 }
508 }
509
510 return NULL;
511}
512
Amit Aroraeb6cba92010-10-25 16:03:21 +0530513
Amit Aroraac4e8652010-11-09 11:16:53 +0530514void dump_clock_info(struct clock_info *clk, int level, int bmp)
Amit Aroraeb6cba92010-10-25 16:03:21 +0530515{
Amit Arora6e774cd2010-10-28 11:31:24 +0530516 int i, j;
Amit Aroraeb6cba92010-10-25 16:03:21 +0530517
Amit Arora6e774cd2010-10-28 11:31:24 +0530518 if (!clk)
519 return;
Amit Aroraeb6cba92010-10-25 16:03:21 +0530520
Amit Arora6e774cd2010-10-28 11:31:24 +0530521 for (i = 1, j = 0; i < level; i++, j = (i - 1)) {
522 if (i == (level - 1)) {
523 if (clk->last_child)
524 printf("`-- ");
525 else
526 printf("|-- ");
527 } else {
528 if ((1<<j) & bmp)
529 printf("| ");
530 else
531 printf(" ");
532 }
533 }
Amit Arora031263a2010-11-09 11:12:41 +0530534
Amit Arora6e774cd2010-10-28 11:31:24 +0530535 if (clk == clocks_info)
536 printf("%s\n", clk->name);
537 else {
538 char *unit = "Hz";
539 double drate = (double)clk->rate;
Amit Kucheriaa0adae42011-01-12 10:54:23 -0600540
Amit Arora6e774cd2010-10-28 11:31:24 +0530541 if (drate > 1000 && drate < 1000000) {
542 unit = "KHz";
543 drate /= 1000;
544 }
545 if (drate > 1000000) {
546 unit = "MHz";
547 drate /= 1000000;
548 }
549 printf("%s (flags:%d,usecount:%d,rate:%5.2f %s)\n",
550 clk->name, clk->flags, clk->usecount, drate, unit);
Amit Arora6e774cd2010-10-28 11:31:24 +0530551 }
552 if (clk->children) {
553 int tbmp = bmp;
554 int xbmp = -1;
Amit Aroraeb6cba92010-10-25 16:03:21 +0530555
Amit Arora6e774cd2010-10-28 11:31:24 +0530556 if (clk->last_child) {
557 xbmp ^= 1 << (level - 2);
558
559 xbmp = tbmp & xbmp;
560 } else
561 xbmp = bmp;
562 for (i = 0; i < clk->num_children; i++) {
Amit Arora6e774cd2010-10-28 11:31:24 +0530563 tbmp = xbmp | (1 << level);
Amit Aroraac4e8652010-11-09 11:16:53 +0530564 dump_clock_info(clk->children[i], level + 1, tbmp);
Amit Arora6e774cd2010-10-28 11:31:24 +0530565 }
566 }
Amit Arora0e512722010-10-01 12:24:16 +0530567}