aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAmit Arora <amit.arora@linaro.org>2010-10-25 16:03:21 +0530
committerAmit Arora <amit.arora@linaro.org>2010-10-25 16:03:21 +0530
commiteb6cba934b52f6685394d04bd1937ab7309fc9e1 (patch)
tree489c4e17ec3187b06913c183a46ceb6ed4e7b36a
parent67b03314155db2dd264e48ade570dcc3e6fd6236 (diff)
Read/Dump clock tree in/from memory
-rw-r--r--clocks.c209
-rw-r--r--powerdebug.h10
2 files changed, 151 insertions, 68 deletions
diff --git a/clocks.c b/clocks.c
index cf1ead0..1635e9d 100644
--- a/clocks.c
+++ b/clocks.c
@@ -16,6 +16,7 @@
#include "powerdebug.h"
#include <errno.h>
+#include <sys/stat.h>
static int clk_tree_level = 1;
static char clk_dir_path[PATH_MAX];
@@ -174,104 +175,178 @@ int read_and_print_clock_one_level(int verbose, int hrow, int selected)
void dump_clock_info(int verbose)
{
+ (void)verbose;
printf("Clock Tree :\n");
printf("**********\n");
- printf("/\n");
- dump_clock_info_recur(verbose, clk_dir_path);
+ read_clock_info(clk_dir_path);
+ print_clock_info(clocks_info, 1, 1);
}
-void dump_clock_info_recur(int verbose, char *clkdirpath)
+void read_clock_info(char *clkpath)
{
- int usecount = 0, flags = 0, rate = 0;
- DIR *dir, *subdir;
- char filename[PATH_MAX], devpath[PATH_MAX];
- struct dirent *item, *subitem;
- char *clock, *clockp;
-
- sprintf(filename, "%s", clkdirpath);
+ DIR *dir;
+ struct dirent *item;
+ char filename[NAME_MAX], clockname[NAME_MAX];
+ struct clock_info *child;
+ struct clock_info *cur;
- dir = opendir(filename);
+ dir = opendir(clkpath);
if (!dir)
return;
- while ((item = readdir(dir))) {
- int cnt = 0;
+ clocks_info = (struct clock_info *)malloc(sizeof(struct clock_info));
+ memset(clocks_info, 0, sizeof(clocks_info));
+ strcpy(clocks_info->name, "/");
+ while ((item = readdir(dir))) {
/* skip hidden dirs except ".." */
- if (item->d_name[0] == '.' )
+ if (item->d_name[0] == '.')
continue;
- sprintf(devpath, "%s/%s", clkdirpath, item->d_name);
+ strcpy(clockname, item->d_name);
+ sprintf(filename, "%s/%s", clkpath, item->d_name);
+ cur = (struct clock_info *)malloc(sizeof(struct clock_info));
+ memset(cur, 0, sizeof(cur));
+ strcpy(cur->name, clockname);
+ cur->parent = clocks_info;
+ insert_children(&clocks_info, cur);
+ child = read_clock_info_recur(filename, 2, cur);
+ }
+ closedir(dir);
+}
- subdir = opendir(devpath);
+struct clock_info *read_clock_info_recur(char *clkpath, int level,
+ struct clock_info *parent)
+{
+ int ret = 0;
+ DIR *dir;
+ char filename[PATH_MAX];
+ struct dirent *item;
+ struct clock_info *cur = NULL;
+ struct stat buf;
+
+ dir = opendir(clkpath);
+ if (!dir)
+ return NULL;
- if (!subdir)
+ while ((item = readdir(dir))) {
+ struct clock_info *child;
+ /* skip hidden dirs except ".." */
+ if (item->d_name[0] == '.' )
continue;
- while ((subitem = readdir(subdir))) {
- if (subitem->d_name[0] == '.') /* skip hidden
-files */
- continue;
-
- sprintf(filename, "%s/%s", devpath, subitem->d_name);
+ sprintf(filename, "%s/%s", clkpath, item->d_name);
- if (!strcmp(subitem->d_name, "flags"))
- flags = get_int_from(filename);
+ ret = stat(filename, &buf);
- if (!strcmp(subitem->d_name, "rate"))
- rate = get_int_from(filename);
-
- if (!strcmp(subitem->d_name, "usecount"))
- usecount = get_int_from(filename);
+ if (ret < 0) {
+ printf("Error doing a stat on %s\n", filename);
+ exit(1);
}
- if (!usecount && !verbose)
+ if (S_ISREG(buf.st_mode))
+ {
+ if (!strcmp(item->d_name, "flags"))
+ parent->flags = get_int_from(filename);
+ if (!strcmp(item->d_name, "rate"))
+ parent->rate = get_int_from(filename);
+ if (!strcmp(item->d_name, "usecount"))
+ parent->usecount = get_int_from(filename);
continue;
+ }
-
- clockp = strrchr(devpath, '/');
- if (clockp)
- clockp++;
- else
+ if (!S_ISDIR(buf.st_mode))
continue;
- clock = strchr(devpath, '/');
- if (clock) {
- clock++;
- clock = strchr(clock, '/');
- if (clock)
- clock++;
- }
+ cur = (struct clock_info *)malloc(sizeof(struct clock_info));
+ memset(cur, 0, sizeof(cur));
+ strcpy(cur->name, item->d_name);
+ cur->children = NULL;
+ cur->parent = NULL;
+ cur->num_children = 0;
+ child = read_clock_info_recur(filename, level + 1, cur);
- while (clock) {
- clock = strchr(clock, '/');
- if (clock)
- clock++;
- else
- break;
- cnt ++;
- }
+ insert_children(&parent, cur);
+ cur->parent = parent;
+ }
+ closedir(dir);
+
+ return cur;
+}
+
+void insert_children(struct clock_info **parent, struct clock_info *clk)
+{
+ if (!(*parent)->children) {
+ (*parent)->children = (struct clock_info **)
+ malloc(sizeof(struct clock_info *)*2);
+ (*parent)->num_children = 0;
+ } else
+ (*parent)->children = (struct clock_info **)
+ realloc((*parent)->children,
+ sizeof(struct clock_info *) *
+ ((*parent)->num_children + 2));
+ if ((*parent)->num_children > 0)
+ (*parent)->children[(*parent)->num_children - 1]->last_child = 0;
+ clk->last_child = 1;
+ (*parent)->children[(*parent)->num_children] = clk;
+ (*parent)->children[(*parent)->num_children + 1] = NULL;
+ (*parent)->num_children++;
+}
- printf("|");
- if (cnt == 1) {
- cnt --;
- printf("-- ");
- } else
- printf(" ");
+void print_clock_info(struct clock_info *clk, int level, int bmp)
+{
+ int i, j;
+
+ if (!clk)
+ return;
- while (cnt) {
- if (cnt == 2)
- printf("|-");
- else if (cnt == 1)
- printf("- ");
+ for (i = 1, j = 0; i < level; i++, j = (i - 1)) {
+ if (i == (level - 1)) {
+ if (clk->last_child)
+ printf("`-- ");
else
+ printf("|-- ");
+ } else {
+ if ((1<<j) & bmp)
printf("| ");
- cnt --;
+ else
+ printf(" ");
}
-
- printf("%s <flags=0x%x:rate=%d:usecount=%d>\n",
- clockp, flags, rate, usecount);
- dump_clock_info_recur(verbose, devpath);
}
+ if (clk == clocks_info)
+ printf("%s\n", clk->name);
+ else {
+ char *unit = "Hz";
+ double drate = (double)clk->rate;
+
+ if (drate > 1000 && drate < 1000000) {
+ unit = "KHz";
+ drate /= 1000;
+ }
+ if (drate > 1000000) {
+ unit = "MHz";
+ drate /= 1000000;
+ }
+ printf("%s (flags:%d,usecount:%d,rate:%5.2f %s)\n",
+ clk->name, clk->flags, clk->usecount, drate, unit);
+ //printf("%s (flags:%d,usecount:%d,rate:%5.2f %s, bmp=0x%x)\n",
+ // clk->name, clk->flags, clk->usecount, drate, unit, bmp);
+ }
+ if (clk->children) {
+ int tbmp = bmp;
+ int xbmp = -1;
+
+ if (clk->last_child) {
+ xbmp ^= 1 << (level - 2 );
+
+ xbmp = tbmp & xbmp;
+ } else
+ xbmp = bmp;
+ for (i = 0; i<clk->num_children; i++) {
+ //if (clk->children[i]->last_child)
+ tbmp = xbmp | (1<<level);
+ print_clock_info(clk->children[i], level + 1, tbmp);
+ }
+ }
}
diff --git a/powerdebug.h b/powerdebug.h
index 6ce68cd..bb9f1c0 100644
--- a/powerdebug.h
+++ b/powerdebug.h
@@ -55,6 +55,10 @@ struct clock_info {
int flags;
int rate;
int usecount;
+ int num_children;
+ int last_child;
+ struct clock_info *parent;
+ struct clock_info **children;
} *clocks_info;
extern int numregulators;
@@ -65,7 +69,11 @@ extern void usage(char **argv);
extern void version(void);
extern void print_regulator_info(int verbose);
extern void dump_clock_info(int verbose);
-extern void dump_clock_info_recur(int verbose, char *clkdirpath);
+extern void read_clock_info(char *clkpath);
+extern struct clock_info *read_clock_info_recur(char *clkpath, int level, struct
+ clock_info *parent);
+extern void print_clock_info(struct clock_info *clk, int level, int bmp);
+extern void insert_children(struct clock_info **parent, struct clock_info *clk);
extern int read_and_print_clock_info(int verbose, int hrow, int selected);
extern int read_and_print_clock_one_level(int verbose, int hrow, int selected);
extern void get_sensor_info(char *path, char *name, char *sensor, int verbose);