Make the code consistent with the clocks and use the tree to build the regulators.
Signed-off-by: Daniel Lezcano daniel.lezcano@linaro.org --- display.c | 50 ++++++---- powerdebug.c | 50 +++++---- powerdebug.h | 4 +- regulator.c | 322 ++++++++++++++++++++++++++++++---------------------------- regulator.h | 29 +----- 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", ®->num_users); + file_read_value(t->path, "microvolts", "%d", ®->microvolts); + file_read_value(t->path, "min_microvolts", "%d", ®->min_microvolts); + file_read_value(t->path, "max_microvolts", "%d", ®->max_microvolts); + file_read_value(t->path, "microamps", "%d", ®->microamps); + file_read_value(t->path, "min_microamps", "%d", ®->min_microamps); + file_read_value(t->path, "max_microamps", "%d", ®->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);