Hello Amit/Sanjay, Did you get a chance to look at the patch?
-- Thanks, -Meraj On Mon, Jun 30, 2014 at 2:06 PM, Mohammad Merajul Islam Molla <meraj.eni...@gmail.com> wrote: > Add support for pinctrl in powerdebug. Both dump and display > modes supported. Tested only on Samsung Arndale board. > > Sample output in display mode on Arndale Board - > > Pin Name MUX Owner GPIO Owner HOG Function > Group > 0 gpa0-0 MUX UNCLAIMED GPIO UNCLAIMED > 1 gpa0-1 MUX UNCLAIMED GPIO UNCLAIMED > 2 gpa0-2 MUX UNCLAIMED GPIO UNCLAIMED > 3 gpa0-3 MUX UNCLAIMED GPIO UNCLAIMED > 4 gpa0-4 MUX UNCLAIMED GPIO UNCLAIMED > 5 gpa0-5 MUX UNCLAIMED GPIO UNCLAIMED > 6 gpa0-6 12c80000.i2c GPIO UNCLAIMED i2c2-bus-mux > i2c2-bus-grp > 7 gpa0-7 12c80000.i2c GPIO UNCLAIMED i2c2-bus-mux > i2c2-bus-grp > 8 gpa1-0 MUX UNCLAIMED GPIO UNCLAIMED > 9 gpa1-1 MUX UNCLAIMED GPIO UNCLAIMED > 10 gpa1-2 12c90000.i2c GPIO UNCLAIMED i2c3-bus-mux > i2c3-bus-grp > 11 gpa1-3 12c90000.i2c GPIO UNCLAIMED i2c3-bus-mux > i2c3-bus-grp > > > > --- > Android.mk | 2 +- > Makefile | 2 +- > README | 4 +- > display.c | 3 +- > display.h | 2 +- > pinctrl.c | 329 > +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > pinctrl.h | 19 ++++ > powerdebug.c | 35 +++++-- > 8 files changed, 381 insertions(+), 15 deletions(-) > create mode 100644 pinctrl.c > create mode 100644 pinctrl.h > > diff --git a/Android.mk b/Android.mk > index 36c73cd..19d00ca 100644 > --- a/Android.mk > +++ b/Android.mk > @@ -29,6 +29,6 @@ LOCAL_C_INCLUDES += external/stlport/stlport/ \ > > LOCAL_SRC_FILES += \ > powerdebug.c sensor.c clocks.c regulator.c \ > - display.c tree.c utils.c mainloop.c gpio.c > + display.c tree.c utils.c mainloop.c gpio.c pinctrl.c > > include $(BUILD_EXECUTABLE) > diff --git a/Makefile b/Makefile > index 2da9d67..f002438 100644 > --- a/Makefile > +++ b/Makefile > @@ -5,7 +5,7 @@ CFLAGS?=-O1 -g -Wall -Wshadow > CC?=gcc > > OBJS = powerdebug.o sensor.o clocks.o regulator.o gpio.o \ > - display.o tree.o utils.o mainloop.o > + display.o tree.o utils.o mainloop.o pinctrl.o > > default: powerdebug > > diff --git a/README b/README > index 1479db1..b24dd98 100644 > --- a/README > +++ b/README > @@ -1,8 +1,8 @@ > powerdebug > ---------- > > -This is a new tool which displays regulator, sensor and clock tree > -information. > +This is a new tool which displays regulator, sensor, clock tree, gpio and > +pinctrl information. > > Current version only displays regulator information and clock tree from > debugfs. Support will be added for sensors later. > diff --git a/display.c b/display.c > index 0000ee9..fb899c0 100644 > --- a/display.c > +++ b/display.c > @@ -63,7 +63,8 @@ struct windata windata[] = { > [CLOCK] = { .name = "Clocks" }, > [REGULATOR] = { .name = "Regulators" }, > [SENSOR] = { .name = "Sensors" }, > - [GPIO] = { .name = "Gpio" }, > + [GPIO] = { .name = "Gpio" }, > + [PINCTRL] = { .name = "Pins" }, > }; > > static void display_fini(void) > diff --git a/display.h b/display.h > index e3a1529..4496f30 100644 > --- a/display.h > +++ b/display.h > @@ -13,7 +13,7 @@ > * - initial API and implementation > > *******************************************************************************/ > > -enum { CLOCK, REGULATOR, SENSOR, GPIO }; > +enum { CLOCK, REGULATOR, SENSOR, GPIO, PINCTRL }; > > struct display_ops { > int (*display)(bool refresh); > diff --git a/pinctrl.c b/pinctrl.c > new file mode 100644 > index 0000000..eef06e2 > --- /dev/null > +++ b/pinctrl.c > @@ -0,0 +1,329 @@ > + > +/******************************************************************************* > + * Copyright (C) 2014, Linaro Limited. > + * > + * This file is part of PowerDebug. > + * > + * All rights reserved. This program and the accompanying materials > + * are made available under the terms of the Eclipse Public License v1.0 > + * which accompanies this distribution, and is available at > + * http://www.eclipse.org/legal/epl-v10.html > + * > + * Contributors: > + * Mohammad Merajul Islam Molla <meraj.mo...@samsung.com> > + * (Samsung R&D Institute Bangladesh) > + * - initial API and implementation > + > *******************************************************************************/ > + > +#ifndef _GNU_SOURCE > +#define _GNU_SOURCE > +#include <stdio.h> > +#undef _GNU_SOURCE > +#endif > +#include <string.h> > +#include <stdbool.h> > +#include <unistd.h> > +#include <stdlib.h> > +#include <dirent.h> > +#include <sys/stat.h> > +#include <sys/types.h> > + > +#include "pinctrl.h" > +#include "display.h" > + > +#define SIZE 64 > +#define MAX_PINS 256 > + > +#define PIN_fmt "%*[^ ] %d" > +#define NAME_fmt "%*[^(]( %s" > +#define MUX_fmt "%*[^:]: %s" > +#define GPIO_fmt "%*[^:]: %*[^ ] %s" > +#define GPIO_fmt1 "%*[^:]: %*[^ ] %*[^ ] %s" > + > +#define SYS_PINCTRL "/sys/kernel/debug/pinctrl" > + > +static bool pinctrl_error = false; > + > +static struct pintcrl_info { > + int pin; > + char name[SIZE]; > + char mux_owner[SIZE]; > + char gpio_owner[SIZE]; > + char hog[SIZE]; > + char function[SIZE]; > + char group[SIZE]; > +} pins_info[MAX_PINS]; > + > +static int fill_pinctrl_info(); > + > +static int pinctrl_print_header(void) > +{ > + char *buf; > + int ret; > + > + if (asprintf(&buf, "%-5s %-10s %-15s %-15s %-5s %-20s %-20s", > + "Pin", "Name", "MUX Owner", "GPIO Owner", "HOG", > "Function", > + "Group") < 0) > + return -1; > + > + ret = display_column_name(buf); > + > + free(buf); > + > + return ret; > +} > + > +static char *pin_line(int pin) > +{ > + char *pinline = 0; > + > + if (asprintf(&pinline,"%-5d %-10s %-15s %-15s %-5s %-20s %-20s", > + pins_info[pin].pin, pins_info[pin].name, > + pins_info[pin].mux_owner, pins_info[pin].gpio_owner, > + pins_info[pin].hog, pins_info[pin].function, > + pins_info[pin].group) < 0) > + return NULL; > + > + return pinline; > +} > + > +static int pinctrl_print_info() > +{ > + int i; > + int line = 0; > + char *buffer; > + > + display_reset_cursor(PINCTRL); > + > + pinctrl_print_header(); > + > + for (i = 0; i < MAX_PINS; i++) { > + if (pins_info[i].pin == -1) > + continue; > + > + buffer = pin_line(i); > + if (!buffer) > + return -1; > + > + display_print_line(PINCTRL, line, buffer, 0, NULL); > + line++; > + > + free(buffer); > + } > + > + display_refresh_pad(PINCTRL); > + > + return 0; > +} > + > +static int dump_pinctrl_info() > +{ > + int i; > + > + for (i = 0; i < MAX_PINS; i++) { > + if (pins_info[i].pin == -1) > + continue; > + printf("\tPin %d: (Name: %s, MUX_owner: %s, > GPIO_owner: %s, HOG: %s, Function: %s, Group: %s)\n", > + pins_info[i].pin, pins_info[i].name, > + pins_info[i].mux_owner, pins_info[i].gpio_owner, > + pins_info[i].hog, > + pins_info[i].function, pins_info[i].group); > + } > + > + return 0; > +} > + > + > +int pinctrl_dump() > +{ > + int ret; > + > + if (pinctrl_error) > + return -1; > + > + printf("\nPin Information:\n"); > + printf("****************\n"); > + ret = dump_pinctrl_info(); > + printf("\n\n"); > + > + return ret; > + > +} > + > +static int pinctrl_display(bool refresh) > +{ > + if (pinctrl_error) { > + display_message(PINCTRL, > + "error: path " SYS_PINCTRL " not found or not root"); > + return -2; > + } > + > + if (refresh && fill_pinctrl_info()) > + return -1; > + > + return pinctrl_print_info(); > +} > + > +static struct display_ops pinctrl_ops = { > + .display = pinctrl_display, > +}; > + > +static int read_pin_info(const char *path) > +{ > + FILE *fpinmux; > + int pin; > + int ret = 0; > + char *p; > + char buf[4096]; > + > + fpinmux = fopen(path, "r"); > + if (!fpinmux) { > + printf("error: failed to read %s\n", path); > + return -1; > + } > + > + /* first two lines are headers, ignore */ > + fgets(buf, 4096, fpinmux); > + fgets(buf, 4096, fpinmux); > + > + while (fgets(buf, 4096, fpinmux)) { > + int mux_owner = 0; > + > + /* get pin number */ > + sscanf(buf, PIN_fmt, &pin); > + > + if (pin >= MAX_PINS) { > + printf("WARNING: # of pins > max pins (256), > need to increase limit\n"); > + continue; > + } > + > + pins_info[pin].pin = pin; > + sscanf(buf, NAME_fmt, pins_info[pin].name); > + pins_info[pin].name[strlen(pins_info[pin].name) - 2] = '\0'; > + > + if (strstr(buf, "MUX UNCLAIMED")) > + strcpy(pins_info[pin].mux_owner, "MUX UNCLAIMED"); > + else { > + sscanf(buf, MUX_fmt, pins_info[pin].mux_owner); > + mux_owner = 1; > + } > + > + if (strstr(buf, "GPIO UNCLAIMED")) > + strcpy(pins_info[pin].gpio_owner, "GPIO UNCLAIMED"); > + else { > + if (mux_owner) > + sscanf(buf, GPIO_fmt, > pins_info[pin].gpio_owner); > + else > + sscanf(buf, GPIO_fmt1, > pins_info[pin].gpio_owner); > + } > + > + if (strstr(buf, "HOG")) > + strcpy(pins_info[pin].hog, "HOG"); > + else > + strcpy(pins_info[pin].hog, ""); > + > + if ((p = strstr(buf, "function"))) { > + p += 9; > + sscanf(p, "%s", pins_info[pin].function); > + } > + else > + strcpy(pins_info[pin].function, ""); > + > + if ((p = strstr(buf, "group"))) { > + p += 5; > + sscanf(p, "%s", pins_info[pin].group); > + } > + else > + strcpy(pins_info[pin].group, ""); > + } > + > + fclose(fpinmux); > + return ret; > +} > + > +static void init_pins_info() > +{ > + int i; > + > + memset(pins_info, 0, sizeof(pins_info)); > + > + for (i = 0; i < MAX_PINS; i++) > + pins_info[i].pin = -1; > +} > + > +static int fill_pinctrl_info() > +{ > + DIR *dir; > + char *newpath, *pinmux_path; > + struct dirent dirent, *direntp; > + struct stat s; > + int ret = 0; > + > + dir = opendir(SYS_PINCTRL); > + if (!dir) { > + printf("error: unable to open directory " SYS_PINCTRL); > + ret = -1; > + goto out; > + } > + > + init_pins_info(); > + > + while (!readdir_r(dir, &dirent, &direntp)) { > + ret = 0; > + > + if (!direntp) > + break; > + > + if (direntp->d_name[0] == '.') > + continue; > + > + ret = asprintf(&newpath, "%s/%s", SYS_PINCTRL, > direntp->d_name); > + if (ret < 0) > + goto out; > + > + ret = stat(newpath, &s); > + if (ret) > + goto out_free_newpath; > + > + if (S_ISDIR(s.st_mode)) { > + ret = asprintf(&pinmux_path, "%s/%s", newpath, > + "pinmux-pins"); > + if (ret < 0) > + goto out_free_newpath; > + > + if (read_pin_info(pinmux_path)) { > + ret = -1; > + goto out_free_pinmux; > + } > + } > + } > + > +out_free_pinmux: > + free(pinmux_path); > + > +out_free_newpath: > + free(newpath); > + > +out: > + closedir(dir); > + return ret; > +} > + > +int pinctrl_init(void) > +{ > + int ret = 0; > + > + ret = display_register(PINCTRL, &pinctrl_ops); > + if (ret) > + printf("error: pinctrl display register failed"); > + > + if (access(SYS_PINCTRL, F_OK)) { > + pinctrl_error = true; > + return -1; > + } > + > + if (fill_pinctrl_info()) > + return -1; > + > + return ret; > +} > diff --git a/pinctrl.h b/pinctrl.h > new file mode 100644 > index 0000000..2fa4f3a > --- /dev/null > +++ b/pinctrl.h > @@ -0,0 +1,19 @@ > +/******************************************************************************* > + * Copyright (C) 2014, Linaro Limited. > + * > + * This file is part of PowerDebug. > + * > + * All rights reserved. This program and the accompanying materials > + * are made available under the terms of the Eclipse Public License v1.0 > + * which accompanies this distribution, and is available at > + * http://www.eclipse.org/legal/epl-v10.html > + * > + * Contributors: > + * Mohammad merajul Islam Molla <meraj.mo...@samsung.com> > + * (Samsung R&D Institute Bangladesh) > + * > + * - initial API and implementation > + > *******************************************************************************/ > + > +extern int pinctrl_init(void); > +extern int pinctrl_dump(void); > diff --git a/powerdebug.c b/powerdebug.c > index 6cf3a1b..b4f4833 100644 > --- a/powerdebug.c > +++ b/powerdebug.c > @@ -26,6 +26,7 @@ > #include "clocks.h" > #include "sensor.h" > #include "gpio.h" > +#include "pinctrl.h" > #include "mainloop.h" > #include "powerdebug.h" > > @@ -35,13 +36,14 @@ void usage(void) > { > printf("Usage: powerdebug [OPTIONS]\n"); > printf("\n"); > - printf("powerdebug -d [ -r ] [ -s ] [ -c [ -p <clock-name> ] ] " > + printf("powerdebug -d [ -r ] [ -s ] [ -p ][ -c [ -P <clock-name> ] ] " > "[ -v ]\n"); > - printf("powerdebug [ -r | -s | -c ]\n"); > + printf("powerdebug [ -r | -s | -c | -p] \n"); > printf(" -r, --regulator Show regulator information\n"); > printf(" -s, --sensor Show sensor information\n"); > printf(" -c, --clock Show clock information\n"); > - printf(" -p, --findparents Show all parents for a particular" > + printf(" -p, --pin Show pin information\n"); > + printf(" -P, --findparents Show all parents for a particular" > " clock\n"); > printf(" -t, --time Set ticktime in seconds (eg. > 10.0)\n"); > printf(" -d, --dump Dump information once (no > refresh)\n"); > @@ -62,7 +64,8 @@ void version() > * -s, --sensor : sensors > * -c, --clock : clocks > * -g, --gpio : gpios > - * -p, --findparents : clockname whose parents have to be found > + * -p, --pin : pins > + * -P, --findparents : clockname whose parents have to be found > * -t, --time : ticktime > * -d, --dump : dump > * -v, --verbose : verbose > @@ -76,7 +79,8 @@ static struct option long_options[] = { > { "sensor", 0, 0, 's' }, > { "clock", 0, 0, 'c' }, > { "gpio", 0, 0, 'g' }, > - { "findparents", 1, 0, 'p' }, > + { "pin", 0 , 0, 'p' }, > + { "findparents", 1, 0, 'P' }, > { "time", 1, 0, 't' }, > { "dump", 0, 0, 'd' }, > { "verbose", 0, 0, 'v' }, > @@ -91,6 +95,7 @@ struct powerdebug_options { > bool sensors; > bool clocks; > bool gpios; > + bool pins; > bool dump; > unsigned int ticktime; > int selectedwindow; > @@ -108,7 +113,7 @@ int getoptions(int argc, char *argv[], struct > powerdebug_options *options) > while (1) { > int optindex = 0; > > - c = getopt_long(argc, argv, "rscgp:t:dvVh", > + c = getopt_long(argc, argv, "rscgpP:t:dvVh", > long_options, &optindex); > if (c == -1) > break; > @@ -131,6 +136,10 @@ int getoptions(int argc, char *argv[], struct > powerdebug_options *options) > options->selectedwindow = GPIO; > break; > case 'p': > + options->pins = true; > + options->selectedwindow = PINCTRL; > + break; > + case 'P': > options->clkname = strdup(optarg); > if (!options->clkname) { > fprintf(stderr, "failed to allocate memory"); > @@ -161,9 +170,9 @@ int getoptions(int argc, char *argv[], struct > powerdebug_options *options) > > /* No system specified to be dump, let's default to all */ > if (!options->regulators && !options->clocks && > - !options->sensors && !options->gpios) > - options->regulators = options->clocks = > - options->sensors = options->gpios = true; > + !options->sensors && !options->gpios && !options->pins) > + options->regulators = options->clocks = options->sensors = > + options->gpios = options->pins = true; > > if (options->selectedwindow == -1) > options->selectedwindow = CLOCK; > @@ -185,6 +194,9 @@ static int powerdebug_dump(struct > powerdebug_options *options) > if (options->gpios) > gpio_dump(); > > + if (options->pins) > + pinctrl_dump(); > + > return 0; > } > > @@ -266,6 +278,11 @@ int main(int argc, char **argv) > options->gpios = false; > } > > + if (pinctrl_init()) { > + printf("failed to initialize pinctrl\n"); > + options->pins = false; > + } > + > ret = options->dump ? powerdebug_dump(options) : > powerdebug_display(options); > > > > -- > Thanks, > -Meraj _______________________________________________ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev