Use the tree to build a sensor tree and make the code consistent
with the other pm blocks.

Signed-off-by: Daniel Lezcano <daniel.lezc...@linaro.org>
---
 powerdebug.c |    7 ++-
 powerdebug.h |    2 +-
 sensor.c     |  261 ++++++++++++++++++++++++++++++++--------------------------
 3 files changed, 150 insertions(+), 120 deletions(-)

diff --git a/powerdebug.c b/powerdebug.c
index a303757..641673b 100644
--- a/powerdebug.c
+++ b/powerdebug.c
@@ -335,7 +335,7 @@ static int powerdebug_dump(struct powerdebug_options 
*options)
                read_and_dump_clock_info(options->clkname);
 
        if (options->sensors)
-               read_and_print_sensor_info(options->verbose);
+               sensor_dump();
 
        return 0;
 }
@@ -392,6 +392,11 @@ int main(int argc, char **argv)
                options->clocks = false;
        }
 
+       if (sensor_init()) {
+               printf("failed to initialize sensors\n");
+               options->sensors = false;
+       }
+
        ret = options->dump ? powerdebug_dump(options) :
                powerdebug_display(options);
 
diff --git a/powerdebug.h b/powerdebug.h
index ab1e6f0..7175839 100644
--- a/powerdebug.h
+++ b/powerdebug.h
@@ -49,7 +49,7 @@ extern int display_clock_select(int window, int line);
 extern int display_clock_unselect(int window, int line, bool bold);
 
 extern void get_sensor_info(char *path, char *name, char *sensor, int verbose);
-extern int  read_and_print_sensor_info(int verbose);
+extern int  sensor_dump(void);
 extern void print_sensor_header(void);
 
 extern void killall_windows(int all);
diff --git a/sensor.c b/sensor.c
index df07593..f386f0c 100644
--- a/sensor.c
+++ b/sensor.c
@@ -15,164 +15,189 @@
 
 #include "powerdebug.h"
 #include "sensor.h"
+#include "tree.h"
+#include "utils.h"
 
-static char *items_temp[32] = {"min", "max", "input", "label", ""};
-static char *suffix_temp[32] = {"°C", "°C", "°C", "", ""};
-static char *items_in[32] = {"min", "max", "input", "label", ""};
-static char *suffix_in[32] = {"Volts", "Volts", "Volts", "", ""};
-static char *items_fan[32] = {"min", "max", "input", "label", "div", "target", 
""};
-static char *suffix_fan[32] = {"RPM", "RPM", "RPM", "", "", "RPM", ""};
-static char *items_pwm[32] = {"freq", "enable", "mode", ""};
-static char *suffix_pwm[32] = {"Hz", "", "", ""};
+#define SYSFS_SENSOR "/sys/class/hwmon"
 
-char *get_num(char *fname, char *sensor)
-{
-       char tmpstr[NAME_MAX];
-       char *str;
+static struct tree *sensor_tree;
 
-       strcpy(tmpstr, (fname+strlen(sensor)));
+struct temp_info {
+       char name[NAME_MAX];
+       int temp;
+};
 
-       str = strrchr(tmpstr, '_');
-       str[0] = '\0';
+struct fan_info {
+       char name[NAME_MAX];
+       int rpms;
+};
 
-       str = strdup(tmpstr);
-       return str;
-}
+struct sensor_info {
+       char name[NAME_MAX];
+       struct temp_info *temperatures;
+       struct fan_info *fans;
+       short nrtemps;
+       short nrfans;
+};
 
-void get_sensor_info(char *path, char *fname, char *sensor, int verbose)
+static int sensor_dump_cb(struct tree *tree, void *data)
 {
-       FILE *filep;
-       char filename[PATH_MAX];
-       char **items = NULL, **suffix = NULL;
-       char *item, result[NAME_MAX], *num;
-       int ret, count = 0;
+       int i;
+       struct sensor_info *sensor = tree->private;
 
-       (void)verbose; // get rid of warning
+       if (!strlen(sensor->name))
+               return 0;
 
-       sprintf(filename, "%s/%s", path, fname);
+       printf("%s\n", sensor->name);
 
-       if (!strcmp(sensor, "in")) {
-               items = (char **)items_in;
-               suffix = (char **)suffix_in;
-       }
+       for (i = 0; i < sensor->nrtemps; i++)
+               printf(" %s %.1f °C\n", sensor->temperatures[i].name,
+                      (float)sensor->temperatures[i].temp / 1000);
 
-       if (!strcmp(sensor, "temp")) {
-               items = (char **)items_temp;
-               suffix = (char **)suffix_temp;
-       }
-
-       if (!strcmp(sensor, "fan")) {
-               items = (char **)items_fan;
-               suffix = (char **)suffix_fan;
-       }
-       if (!strcmp(sensor, "pwm")) {
-               items = (char **)items_pwm;
-               suffix = (char **)suffix_pwm;
-       }
+       for (i = 0; i < sensor->nrfans; i++)
+               printf(" %s %d rpm\n", sensor->fans[i].name,
+                      sensor->fans[i].rpms);
 
+       return 0;
+}
 
-       if (!items || !suffix)
-               return;
-
-       item = strrchr(fname, '_');
-       if (!item)
-               return;
-
-       if (item)
-               item++;
-
-       if (item > (fname + strlen(fname)))
-               return;
+int sensor_dump(void)
+{
+       printf("\nSensor Information:\n");
+       printf("*******************\n\n");
 
-       num = get_num(fname, sensor);
-       filep = fopen(filename, "r");
+       return tree_for_each(sensor_tree, sensor_dump_cb, NULL);
+}
 
-       if (!filep)
-               goto exit;
-       ret = fscanf(filep, "%s", result);
-       fclose(filep);
+static struct sensor_info *sensor_alloc(void)
+{
+       struct sensor_info *sensor;
 
-       if (ret != 1)
-               goto exit;
+       sensor = malloc(sizeof(*sensor));
+       if (sensor)
+               memset(sensor, 0, sizeof(*sensor));
 
-       while (strcmp(items[count], "")) {
-               if (!strcmp(items[count], item))
-                       printf("\'temp\' %s sensor %s\t\t%d%s\n",
-                               num, items[count], atoi(result)/1000,
-                               suffix[count]);
-               count++;
-       }
-exit:
-       free(num);
-       return;
+       return sensor;
 }
 
-int read_and_print_sensor_info(int verbose)
+static int read_sensor_cb(struct tree *tree, void *data)
 {
-       DIR *dir, *subdir;
-       int len, found = 0;
-       char filename[PATH_MAX], devpath[PATH_MAX];
-       char device[PATH_MAX];
-       struct dirent *item, *subitem;
+       DIR *dir;
+       int value;
+        struct dirent dirent, *direntp;
+       struct sensor_info *sensor = tree->private;
 
-       printf("\nSensor Information:\n");
-       printf("******************\n");
+       int nrtemps = 0;
+       int nrfans = 0;
 
-       sprintf(filename, "%s", "/sys/class/hwmon");
-       dir = opendir(filename);
+       dir = opendir(tree->path);
        if (!dir)
-               return errno;
+               return -1;
+
+       file_read_value(tree->path, "name", "%s", sensor->name);
 
-       while ((item = readdir(dir))) {
-               if (item->d_name[0] == '.')  /* skip the hidden files */
+       while (!readdir_r(dir, &dirent, &direntp)) {
+
+                if (!direntp)
+                        break;
+
+               if (direntp->d_type != DT_REG)
                        continue;
 
-               found = 1;
+               if (!strncmp(direntp->d_name, "temp", 4)) {
+
+                       if (file_read_value(tree->path, direntp->d_name, "%d",
+                                           &value))
+                               continue;
 
-               sprintf(filename, "/sys/class/hwmon/%s", item->d_name);
-               sprintf(devpath, "%s/device", filename);
+                       sensor->temperatures =
+                               realloc(sensor->temperatures,
+                                       sizeof(struct temp_info) * (nrtemps + 
1));
+                       if (!sensor->temperatures)
+                               continue;
 
-               len = readlink(devpath, device, PATH_MAX - 1);
+                       strcpy(sensor->temperatures[nrtemps].name,
+                              direntp->d_name);
+                       sensor->temperatures[nrtemps].temp = value;
 
-               if (len < 0)
-                       strcpy(devpath, filename);
-               else
-                       device[len] = '\0';
+                       nrtemps++;
+               }
 
-               subdir = opendir(devpath);
+               if (!strncmp(direntp->d_name, "fan", 3)) {
 
-               printf("\nSensor Information for %s :\n", item->d_name);
-               fflush(stdin);
+                       if (file_read_value(tree->path, direntp->d_name, "%d",
+                                           &value))
+                               continue;
 
-               while ((subitem = readdir(subdir))) {
-                       if (subitem->d_name[0] == '.') /* skip hidden files */
+                       sensor->fans =
+                               realloc(sensor->fans,
+                                       sizeof(struct temp_info) * (nrfans + 
1));
+                       if (!sensor->fans)
                                continue;
 
-                       if (!strncmp(subitem->d_name, "in", 2))
-                               get_sensor_info(devpath, subitem->d_name, "in",
-                                               verbose);
-                       else if (!strncmp(subitem->d_name, "temp", 4))
-                               get_sensor_info(devpath, subitem->d_name,
-                                               "temp", verbose);
-                       else if (!strncmp(subitem->d_name, "fan", 4))
-                               get_sensor_info(devpath, subitem->d_name,
-                                               "fan", verbose);
-                       else if (!strncmp(subitem->d_name, "pwm", 4))
-                               get_sensor_info(devpath, subitem->d_name,
-                                               "pwm", verbose);
+                       strcpy(sensor->fans[nrfans].name,
+                              direntp->d_name);
+                       sensor->fans[nrfans].rpms = value;
 
+                       nrfans++;
                }
-
-               closedir(subdir);
        }
+
+       sensor->nrtemps = nrtemps;
+       sensor->nrfans = nrfans;
+
        closedir(dir);
 
-       if (!found && verbose) {
-               printf("Could not find sensor information!");
-               printf(" Looks like /sys/class/hwmon is empty.\n");
-       }
+       return 0;
+}
 
-       printf("\n");
+static int fill_sensor_cb(struct tree *t, void *data)
+{
+       struct sensor_info *sensor;
+
+       sensor = sensor_alloc();
+       if (!sensor)
+               return -1;
+
+       t->private = sensor;
+
+       if (!t->parent)
+               return 0;
+
+       return read_sensor_cb(t, data);
+}
+
+static int fill_sensor_tree(void)
+{
+       return tree_for_each(sensor_tree, fill_sensor_cb, NULL);
+}
+
+static int sensor_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, "subsystem"))
+               return 1;
+
+       if (!strcmp(name, "driver"))
+               return 1;
+
+       if (!strcmp(name, "hwmon"))
+               return 1;
+
+       if (!strcmp(name, "power"))
+               return 1;
 
        return 0;
 }
+
+int sensor_init(void)
+{
+       sensor_tree = tree_load(SYSFS_SENSOR, sensor_filter_cb);
+       if (!sensor_tree)
+               return -1;
+
+       return fill_sensor_tree();
+}
-- 
1.7.1


_______________________________________________
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev

Reply via email to