aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Lezcano <daniel.lezcano@linaro.org>2011-06-15 15:45:12 +0200
committerDaniel Lezcano <daniel.lezcano@linaro.org>2011-06-15 15:45:12 +0200
commitb25be4af578c2daa55e38a81e7a2a2217edb23fd (patch)
treead5b57e556f82b3d59bf208e8c3c819b42fa0ddc
parentb3e6e818f30f61f2f80ecc19e4d37f9d9092e831 (diff)
Rewrite the regulator code based on the tree
Make the code consistent with the clocks and use the tree to build the regulators. Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
-rw-r--r--display.c50
-rw-r--r--powerdebug.c50
-rw-r--r--powerdebug.h4
-rw-r--r--regulator.c322
-rw-r--r--regulator.h29
5 files changed, 227 insertions, 228 deletions
diff --git a/display.c b/display.c
index 8712023..3795547 100644
--- a/display.c
+++ b/display.c
@@ -190,13 +190,8 @@ void show_header(int selectedwindow)
wrefresh(footer_win);
}
-
-void show_regulator_info(struct regulator_info *reg_info, int nr_reg, int verbose)
+void print_regulator_header(void)
{
- int i, count = 1;
-
- (void)verbose;
-
werase(regulator_win);
wattron(regulator_win, A_BOLD);
print(regulator_win, 0, 0, "Name");
@@ -208,6 +203,34 @@ void show_regulator_info(struct regulator_info *reg_info, int nr_reg, int verbos
print(regulator_win, 72, 0, "Min u-volts");
print(regulator_win, 84, 0, "Max u-volts");
wattroff(regulator_win, A_BOLD);
+ wrefresh(regulator_win);
+}
+
+void print_clock_header(void)
+{
+ werase(clock_labels);
+ wattron(clock_labels, A_BOLD);
+ print(clock_labels, 0, 0, "Name");
+ print(clock_labels, 56, 0, "Flags");
+ print(clock_labels, 75, 0, "Rate");
+ print(clock_labels, 88, 0, "Usecount");
+ print(clock_labels, 98, 0, "Children");
+ wattroff(clock_labels, A_BOLD);
+ wrefresh(clock_labels);
+}
+
+#if 0
+void show_regulator_info(struct regulator_info *reg_info, int nr_reg, int verbose)
+{
+ int i, count = 1;
+
+ print_regulator_header();
+
+ wrefresh(regulator_win);
+
+ return;
+
+ (void)verbose;
for (i = 0; i < nr_reg; i++) {
int col = 0;
@@ -248,20 +271,7 @@ void show_regulator_info(struct regulator_info *reg_info, int nr_reg, int verbos
}
wrefresh(regulator_win);
}
-
-
-void print_clock_header(void)
-{
- werase(clock_labels);
- wattron(clock_labels, A_BOLD);
- print(clock_labels, 0, 0, "Name");
- print(clock_labels, 56, 0, "Flags");
- print(clock_labels, 75, 0, "Rate");
- print(clock_labels, 88, 0, "Usecount");
- print(clock_labels, 98, 0, "Children");
- wattroff(clock_labels, A_BOLD);
- wrefresh(clock_labels);
-}
+#endif
void print_sensor_header(void)
{
diff --git a/powerdebug.c b/powerdebug.c
index 3a2edac..a303757 100644
--- a/powerdebug.c
+++ b/powerdebug.c
@@ -174,6 +174,21 @@ int keystroke_callback(bool *enter_hit, bool *findparent_ncurses,
options->selectedwindow = TOTAL_FEATURE_WINS - 1;
}
+#if 0 /* TODO */
+ if (options->selectedwindow == REGULATOR) {
+
+ if (keystroke == KEY_DOWN) {
+ display_next_line();
+ *cont = true;
+ }
+
+ if (keystroke == KEY_UP) {
+ display_prev_line();
+ *cont = true;
+ }
+
+ }
+#endif
if (options->selectedwindow == CLOCK) {
if (keystroke == KEY_DOWN) {
@@ -242,8 +257,7 @@ int keystroke_callback(bool *enter_hit, bool *findparent_ncurses,
return 0;
}
-int mainloop(struct powerdebug_options *options,
- struct regulator_info *reg_info, int nr_reg)
+int mainloop(struct powerdebug_options *options)
{
bool findparent_ncurses = false;
bool refreshwin = false;
@@ -264,11 +278,8 @@ int mainloop(struct powerdebug_options *options,
create_selectedwindow(options->selectedwindow);
}
- if (options->selectedwindow == REGULATOR) {
- regulator_read_info(reg_info, nr_reg);
- show_regulator_info(reg_info, nr_reg,
- options->verbose);
- }
+ if (options->selectedwindow == REGULATOR)
+ regulator_display();
if (options->selectedwindow == CLOCK) {
@@ -315,13 +326,10 @@ int mainloop(struct powerdebug_options *options,
return 0;
}
-static int powerdebug_dump(struct powerdebug_options *options,
- struct regulator_info *reg_info, int nr_reg)
+static int powerdebug_dump(struct powerdebug_options *options)
{
- if (options->regulators) {
- regulator_read_info(reg_info, nr_reg);
- regulator_print_info(reg_info, nr_reg, options->verbose);
- }
+ if (options->regulators)
+ regulator_dump();
if (options->clocks)
read_and_dump_clock_info(options->clkname);
@@ -332,15 +340,14 @@ static int powerdebug_dump(struct powerdebug_options *options,
return 0;
}
-static int powerdebug_display(struct powerdebug_options *options,
- struct regulator_info *reg_info, int nr_reg)
+static int powerdebug_display(struct powerdebug_options *options)
{
if (display_init()) {
printf("failed to initialize display\n");
return -1;
}
- if (mainloop(options, reg_info, nr_reg))
+ if (mainloop(options))
return -1;
return 0;
@@ -362,8 +369,7 @@ static struct powerdebug_options *powerdebug_init(void)
int main(int argc, char **argv)
{
struct powerdebug_options *options;
- struct regulator_info *regulators_info;
- int numregulators, ret;
+ int ret;
options = powerdebug_init();
if (!options) {
@@ -376,8 +382,7 @@ int main(int argc, char **argv)
return 1;
}
- regulators_info = regulator_init(&numregulators);
- if (!regulators_info) {
+ if (regulator_init()) {
printf("not enough memory to allocate regulators info\n");
options->regulators = false;
}
@@ -387,9 +392,8 @@ int main(int argc, char **argv)
options->clocks = false;
}
- ret = options->dump ?
- powerdebug_dump(options, regulators_info, numregulators) :
- powerdebug_display(options, regulators_info, numregulators);
+ ret = options->dump ? powerdebug_dump(options) :
+ powerdebug_display(options);
return ret < 0;
}
diff --git a/powerdebug.h b/powerdebug.h
index 8fd2775..ab1e6f0 100644
--- a/powerdebug.h
+++ b/powerdebug.h
@@ -57,6 +57,4 @@ extern void show_header(int selectedwindow);
extern void create_windows(int selectedwindow);
extern void create_selectedwindow(int selectedwindow);
-struct regulator_info;
-extern void show_regulator_info(struct regulator_info *reg_info,
- int nr_reg, int verbose);
+extern int regulator_display(void);
diff --git a/regulator.c b/regulator.c
index 60529ed..d4b41e1 100644
--- a/regulator.c
+++ b/regulator.c
@@ -11,197 +11,209 @@
* Contributors:
* Amit Arora <amit.arora@linaro.org> (IBM Corporation)
* - initial API and implementation
+ * Daniel Lezcano <daniel.lezcano@linaro.org> (IBM Corporation)
+ * - rewrote code and API based on the tree
*******************************************************************************/
#include "regulator.h"
#define SYSFS_REGULATOR "/sys/class/regulator"
-
-struct regulator_info *regulator_init(int *nr_regulators)
+#define _GNU_SOURCE
+#include <stdio.h>
+#undef _GNU_SOURCE
+#include <sys/types.h>
+#include <stdbool.h>
+#include <dirent.h>
+#include <string.h>
+#include <stdlib.h>
+#include "powerdebug.h"
+#include "tree.h"
+#include "utils.h"
+
+struct regulator_info {
+ char name[NAME_MAX];
+ char state[VALUE_MAX];
+ char status[VALUE_MAX];
+ char type[VALUE_MAX];
+ char opmode[VALUE_MAX];
+ int microvolts;
+ int min_microvolts;
+ int max_microvolts;
+ int microamps;
+ int min_microamps;
+ int max_microamps;
+ int requested_microamps;
+ int num_users;
+};
+
+struct regulator_data {
+ const char *name;
+ const char *ifmt;
+ const char *ofmt;
+ bool derefme;
+};
+
+static struct regulator_data regdata[] = {
+ { "name", "%s", "\tname: %s\n" },
+ { "status", "%s", "\tstatus: %s\n" },
+ { "state", "%s", "\tstate: %s\n" },
+ { "type", "%s", "\ttype: %s\n" },
+ { "num_users", "%d", "\tnum_users: %d\n", true },
+ { "microvolts", "%d", "\tmicrovolts: %d\n", true },
+ { "max_microvolts", "%d", "\tmax_microvolts: %d\n", true },
+ { "min_microvolts", "%d", "\tmin_microvolts: %d\n", true },
+};
+
+static struct tree *reg_tree;
+
+static struct regulator_info *regulator_alloc(void)
{
- DIR *regdir;
- struct dirent *item;
+ struct regulator_info *regi;
- *nr_regulators = 0;
+ regi = malloc(sizeof(*regi));
+ if (regi)
+ memset(regi, 0, sizeof(*regi));
- regdir = opendir(SYSFS_REGULATOR);
- if (!regdir) {
- fprintf(stderr, "failed to open '%s': %m\n", SYSFS_REGULATOR);
- return NULL;
- }
+ return regi;
+}
- while ((item = readdir(regdir))) {
+static int regulator_dump_cb(struct tree *tree, void *data)
+{
+ int i;
+ char buffer[NAME_MAX];
+ size_t nregdata = sizeof(regdata) / sizeof(regdata[0]);
- if (!strcmp(item->d_name, "."))
- continue;
+ if (!strncmp("regulator.", tree->name, strlen("regulator.")))
+ printf("\n%s:\n", tree->name);
- if (!strcmp(item->d_name, ".."))
+ for (i = 0; i < nregdata; i++) {
+
+ if (file_read_value(tree->path, regdata[i].name,
+ regdata[i].ifmt, buffer))
continue;
- (*nr_regulators)++;
+ printf(regdata[i].ofmt, regdata[i].derefme ?
+ *((int *)buffer) : buffer);
}
- closedir(regdir);
+ return 0;
+}
- return malloc(*nr_regulators * sizeof(struct regulator_info));
+int regulator_dump(void)
+{
+ printf("\nRegulator Information:\n");
+ printf("*********************\n\n");
+
+ return tree_for_each(reg_tree, regulator_dump_cb, NULL);
}
-static void print_string_val(char *name, char *val)
+static int regulator_display_cb(struct tree *t, void *data)
{
- printf("\t%s=%s", name, val);
- if (!strchr(val, '\n'))
- printf("\n");
+ struct regulator_info *reg = t->private;
+ int *line = data;
+ char *buf;
+
+ /* we skip the root node of the tree */
+ if (!t->parent)
+ return 0;
+
+ if (!strlen(reg->name))
+ return 0;
+
+ if (asprintf(&buf, "%-11s %-11s %-11s %-11s %-11d %-11d %-11d %-12d",
+ reg->name, reg->status, reg->state, reg->type,
+ reg->num_users, reg->microvolts, reg->min_microvolts,
+ reg->max_microvolts) < 0)
+ return -1;
+
+ display_print_line(REGULATOR, *line, buf, reg->num_users, t);
+
+ (*line)++;
+
+ free(buf);
+
+ return 0;
}
-void regulator_print_info(struct regulator_info *reg_info, int nr_reg, int verbose)
+int regulator_display(void)
{
- int i;
+ int ret, line = 0;
- printf("\nRegulator Information:\n");
- printf("*********************\n\n");
+ display_reset_cursor(REGULATOR);
- for (i = 0; i < nr_reg; i++) {
- printf("Regulator %d:\n", i + 1);
- print_string_val("name", reg_info[i].name);
- if (strcmp(reg_info[i].status, ""))
- print_string_val("status", reg_info[i].status);
- if (strcmp(reg_info[i].state, ""))
- print_string_val("state", reg_info[i].state);
+ print_regulator_header();
- if (!verbose)
- continue;
+ ret = tree_for_each(reg_tree, regulator_display_cb, &line);
- if (strcmp(reg_info[i].type, ""))
- print_string_val("type", reg_info[i].type);
- if (strcmp(reg_info[i].opmode, ""))
- print_string_val("opmode", reg_info[i].opmode);
-
- if (reg_info[i].microvolts)
- printf("\tmicrovolts=%d\n",
- reg_info[i].microvolts);
- if (reg_info[i].min_microvolts)
- printf("\tmin_microvolts=%d\n",
- reg_info[i].min_microvolts);
- if (reg_info[i].max_microvolts)
- printf("\tmax_microvolts=%d\n",
- reg_info[i].max_microvolts);
-
- if (reg_info[i].microamps)
- printf("\tmicroamps=%d\n",
- reg_info[i].microamps);
- if (reg_info[i].min_microamps)
- printf("\tmin_microamps=%d\n",
- reg_info[i].min_microamps);
- if (reg_info[i].max_microamps)
- printf("\tmax_microamps=%d\n",
- reg_info[i].max_microamps);
- if (reg_info[i].requested_microamps)
- printf("\trequested_microamps=%d\n",
- reg_info[i].requested_microamps);
-
- if (reg_info[i].num_users)
- printf("\tnum_users=%d\n",
- reg_info[i].num_users);
- printf("\n");
- }
+ display_refresh_pad(REGULATOR);
- if (!nr_reg && verbose) {
- printf("Could not find regulator information!");
- printf(" Looks like %s is empty.\n\n", SYSFS_REGULATOR);
- }
+ return ret;
+}
- printf("\n\n");
+static int regulator_filter_cb(const char *name)
+{
+ /* let's ignore some directories in order to avoid to be
+ * pulled inside the sysfs circular symlinks mess/hell
+ * (choose the word which fit better)
+ */
+ if (!strcmp(name, "device"))
+ return 1;
+
+ if (!strcmp(name, "subsystem"))
+ return 1;
+
+ if (!strcmp(name, "driver"))
+ return 1;
+
+ return 0;
}
-static void read_info_from_dirent(struct regulator_info *reg_info,
- struct dirent *ritem, char *str, int idx)
+static inline int read_regulator_cb(struct tree *t, void *data)
{
- if (!strcmp(ritem->d_name, "name"))
- strcpy(reg_info[idx].name, str);
- if (!strcmp(ritem->d_name, "state"))
- strcpy(reg_info[idx].state, str);
- if (!strcmp(ritem->d_name, "status"))
- strcpy(reg_info[idx].status, str);
-
- if (!strcmp(ritem->d_name, "type"))
- strcpy(reg_info[idx].type, str);
- if (!strcmp(ritem->d_name, "opmode"))
- strcpy(reg_info[idx].opmode, str);
-
- if (!strcmp(ritem->d_name, "microvolts"))
- reg_info[idx].microvolts = atoi(str);
- if (!strcmp(ritem->d_name, "min_microvolts"))
- reg_info[idx].min_microvolts = atoi(str);
- if (!strcmp(ritem->d_name, "max_microvolts"))
- reg_info[idx].max_microvolts = atoi(str);
-
- if (!strcmp(ritem->d_name, "microamps"))
- reg_info[idx].microamps = atoi(str);
- if (!strcmp(ritem->d_name, "min_microamps"))
- reg_info[idx].min_microamps = atoi(str);
- if (!strcmp(ritem->d_name, "max_microamps"))
- reg_info[idx].max_microamps = atoi(str);
- if (!strcmp(ritem->d_name, "requested_microamps"))
- reg_info[idx].requested_microamps = atoi(str);
-
- if (!strcmp(ritem->d_name, "num_users"))
- reg_info[idx].num_users = atoi(str);
+ struct regulator_info *reg = t->private;
+
+ file_read_value(t->path, "name", "%s", reg->name);
+ file_read_value(t->path, "state", "%s", reg->state);
+ file_read_value(t->path, "status", "%s", reg->status);
+ file_read_value(t->path, "type", "%s", reg->type);
+ file_read_value(t->path, "opmode", "%s", reg->opmode);
+ file_read_value(t->path, "num_users", "%d", &reg->num_users);
+ file_read_value(t->path, "microvolts", "%d", &reg->microvolts);
+ file_read_value(t->path, "min_microvolts", "%d", &reg->min_microvolts);
+ file_read_value(t->path, "max_microvolts", "%d", &reg->max_microvolts);
+ file_read_value(t->path, "microamps", "%d", &reg->microamps);
+ file_read_value(t->path, "min_microamps", "%d", &reg->min_microamps);
+ file_read_value(t->path, "max_microamps", "%d", &reg->max_microamps);
+
+ return 0;
}
-int regulator_read_info(struct regulator_info *reg_info, int nr_reg)
+static int fill_regulator_cb(struct tree *t, void *data)
{
- FILE *file = NULL;
- DIR *regdir, *dir;
- int len, count = 0, ret = 0;
- char line[1024], filename[1024], *fptr;
- struct dirent *item, *ritem;
-
- regdir = opendir(SYSFS_REGULATOR);
- if (!regdir)
- return(1);
- while ((item = readdir(regdir))) {
- if (strlen(item->d_name) < 3)
- continue;
+ struct regulator_info *reg;
- if (strncmp(item->d_name, "regulator", 9))
- continue;
+ reg = regulator_alloc();
+ if (!reg)
+ return -1;
+ t->private = reg;
- len = sprintf(filename, "%s/%s", SYSFS_REGULATOR, item->d_name);
+ /* we skip the root node but we set it expanded for its children */
+ if (!t->parent)
+ return 0;
- dir = opendir(filename);
- if (!dir)
- continue;
- count++;
-
- if (count > nr_reg) {
- ret = 1;
- goto exit;
- }
-
- strcpy(reg_info[count-1].name, item->d_name);
- while ((ritem = readdir(dir))) {
- if (strlen(ritem->d_name) < 3)
- continue;
-
- sprintf(filename + len, "/%s", ritem->d_name);
- file = fopen(filename, "r");
- if (!file)
- continue;
- memset(line, 0, 1024);
- fptr = fgets(line, 1024, file);
- fclose(file);
- if (!fptr)
- continue;
-
- read_info_from_dirent(reg_info, ritem,
- fptr, count - 1);
- }
- exit:
- closedir(dir);
- if (ret)
- break;
- }
- closedir(regdir);
+ return read_regulator_cb(t, data);
+}
- return ret;
+static int fill_regulator_tree(void)
+{
+ return tree_for_each(reg_tree, fill_regulator_cb, NULL);
+}
+
+int regulator_init(void)
+{
+ reg_tree = tree_load(SYSFS_REGULATOR, regulator_filter_cb);
+ if (!reg_tree)
+ return -1;
+
+ return fill_regulator_tree();
}
diff --git a/regulator.h b/regulator.h
index 1633cfd..5f8c473 100644
--- a/regulator.h
+++ b/regulator.h
@@ -13,32 +13,7 @@
* - initial API and implementation
*******************************************************************************/
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <dirent.h>
-#include <getopt.h>
-
#define VALUE_MAX 16
-struct regulator_info {
- char name[NAME_MAX];
- char state[VALUE_MAX];
- char status[VALUE_MAX];
- char type[VALUE_MAX];
- char opmode[VALUE_MAX];
- int microvolts;
- int min_microvolts;
- int max_microvolts;
- int microamps;
- int min_microamps;
- int max_microamps;
- int requested_microamps;
- int num_users;
-};
-
-extern struct regulator_info *regulator_init(int *nr_regulators);
-extern int regulator_read_info(struct regulator_info *reg_info, int nr_reg);
-extern void regulator_print_info(struct regulator_info *reg_info,
- int nr_reg, int verbose);
+extern int regulator_init(void);
+extern int regulator_dump(void);