From patchwork Wed Jun 15 13:50:37 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Lezcano X-Patchwork-Id: 1926 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id 80C1F24B1C for ; Wed, 15 Jun 2011 13:52:41 +0000 (UTC) Received: from mail-qy0-f180.google.com (mail-qy0-f180.google.com [209.85.216.180]) by fiordland.canonical.com (Postfix) with ESMTP id 1EF82A18976 for ; Wed, 15 Jun 2011 13:52:41 +0000 (UTC) Received: by qyk10 with SMTP id 10so261357qyk.11 for ; Wed, 15 Jun 2011 06:52:40 -0700 (PDT) Received: by 10.52.168.65 with SMTP id zu1mr795568vdb.207.1308145960350; Wed, 15 Jun 2011 06:52:40 -0700 (PDT) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.52.183.130 with SMTP id em2cs126627vdc; Wed, 15 Jun 2011 06:52:40 -0700 (PDT) Received: by 10.216.28.1 with SMTP id f1mr649036wea.41.1308145957344; Wed, 15 Jun 2011 06:52:37 -0700 (PDT) Received: from smtp.smtpout.orange.fr (smtp05.smtpout.orange.fr [80.12.242.127]) by mx.google.com with ESMTP id r52si1384465weq.99.2011.06.15.06.52.36; Wed, 15 Jun 2011 06:52:37 -0700 (PDT) Received-SPF: neutral (google.com: 80.12.242.127 is neither permitted nor denied by best guess record for domain of daniel.lezcano@linaro.org) client-ip=80.12.242.127; Authentication-Results: mx.google.com; spf=neutral (google.com: 80.12.242.127 is neither permitted nor denied by best guess record for domain of daniel.lezcano@linaro.org) smtp.mail=daniel.lezcano@linaro.org Received: from monster.dhcp.lxc ([92.134.76.78]) by mwinf5d28 with ME id wDsa1g00D1hMfSL03DscAw; Wed, 15 Jun 2011 15:52:36 +0200 From: Daniel Lezcano To: daniel.lezcano@linaro.org Cc: linaro-dev@lists.linaro.org, patches@linaro.org Subject: [powerdebug 03/22] Rewrite the regulator code based on the tree Date: Wed, 15 Jun 2011 15:50:37 +0200 Message-Id: <1308145856-6112-3-git-send-email-daniel.lezcano@linaro.org> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1308145856-6112-1-git-send-email-daniel.lezcano@linaro.org> References: <1308145856-6112-1-git-send-email-daniel.lezcano@linaro.org> Make the code consistent with the clocks and use the tree to build the regulators. Signed-off-by: Daniel Lezcano --- 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 (IBM Corporation) * - initial API and implementation + * Daniel Lezcano (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 +#undef _GNU_SOURCE +#include +#include +#include +#include +#include +#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 -#include -#include -#include -#include -#include - #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);