[RFC PATCH v1 05/20] tools: gpio: Add additional polling support to gpio-event-mon

From: lakshmi . sowjanya . d
Date: Tue Aug 24 2021 - 12:48:31 EST


From: Christopher Hall <christopher.s.hall@xxxxxxxxx>

Intel Timed I/O hardware doesn't support reading the current levels,
allow application to continue if this fails.

The Timed I/O hardware aggregates muliple events, but doesn't distinguish
between rising and falling edges *if* both types are selected. Add
output 'verbiage' for unknown event type.

Add verbosity parameter to suppress printing of "nothing available" poll
result. This can be re-enabled at runtime with "-vv" parameter.

Signed-off-by: Christopher Hall <christopher.s.hall@xxxxxxxxx>
Signed-off-by: Tamal Saha <tamal.saha@xxxxxxxxx>
Co-developed-by: Lakshmi Sowjanya D <lakshmi.sowjanya.d@xxxxxxxxx>
Signed-off-by: Lakshmi Sowjanya D <lakshmi.sowjanya.d@xxxxxxxxx>
Reviewed-by: Mark Gross <mgross@xxxxxxxxxxxxxxx>
---
include/uapi/linux/gpio.h | 1 +
tools/gpio/gpio-event-mon.c | 42 ++++++++++++++++++++++++++-----------
2 files changed, 31 insertions(+), 12 deletions(-)

diff --git a/include/uapi/linux/gpio.h b/include/uapi/linux/gpio.h
index eaaea3d8e6b4..ed84805baee8 100644
--- a/include/uapi/linux/gpio.h
+++ b/include/uapi/linux/gpio.h
@@ -267,6 +267,7 @@ struct gpio_v2_line_info_changed {
enum gpio_v2_line_event_id {
GPIO_V2_LINE_EVENT_RISING_EDGE = 1,
GPIO_V2_LINE_EVENT_FALLING_EDGE = 2,
+ GPIO_V2_LINE_EVENT_UNKNOWN_EDGE = 3,
};

/**
diff --git a/tools/gpio/gpio-event-mon.c b/tools/gpio/gpio-event-mon.c
index a2b233fdb572..d8f0bbf78728 100644
--- a/tools/gpio/gpio-event-mon.c
+++ b/tools/gpio/gpio-event-mon.c
@@ -29,7 +29,8 @@ int monitor_device(const char *device_name,
unsigned int *lines,
unsigned int num_lines,
struct gpio_v2_line_config *config,
- unsigned int loops)
+ unsigned int loops,
+ int verbosity)
{
struct gpio_v2_line_values values;
char *chrdev_name;
@@ -62,16 +63,23 @@ int monitor_device(const char *device_name,
gpiotools_set_bit(&values.mask, i);
ret = gpiotools_get_values(lfd, &values);
if (ret < 0) {
- fprintf(stderr,
- "Failed to issue GPIO LINE GET VALUES IOCTL (%d)\n",
- ret);
- goto exit_line_close;
+ if (errno == EIO) {
+ fprintf(stdout,
+ "Failed to get line values. Function unimplemented, continuing\n");
+ } else {
+ ret = -errno;
+ fprintf(stderr,
+ "Failed to issue GPIO LINE GET VALUES IOCTL (%d)\n",
+ ret);
+ goto exit_line_close;
+ }
}

if (num_lines == 1) {
fprintf(stdout, "Monitoring line %d on %s\n", lines[0], device_name);
- fprintf(stdout, "Initial line value: %d\n",
- gpiotools_test_bit(values.bits, 0));
+ if (ret != -1)
+ fprintf(stdout, "Initial line value: %d\n",
+ gpiotools_test_bit(values.bits, 0));
} else {
fprintf(stdout, "Monitoring lines %d", lines[0]);
for (i = 1; i < num_lines - 1; i++)
@@ -91,8 +99,9 @@ int monitor_device(const char *device_name,

ret = read(lfd, &event, sizeof(event));
if (ret == -1) {
- if (errno == -EAGAIN) {
- fprintf(stderr, "nothing available\n");
+ if (errno == EAGAIN) {
+ if (verbosity >= 2)
+ fprintf(stdout, "nothing available\n");
continue;
} else {
ret = -errno;
@@ -117,8 +126,11 @@ int monitor_device(const char *device_name,
case GPIO_V2_LINE_EVENT_FALLING_EDGE:
fprintf(stdout, "falling edge");
break;
+ case GPIO_V2_LINE_EVENT_UNKNOWN_EDGE:
+ fprintf(stdout, "rising/falling edge");
+ break;
default:
- fprintf(stdout, "unknown event");
+ fprintf(stdout, "unknown event spec: %x", event.id);
}
fprintf(stdout, "\n");

@@ -150,6 +162,7 @@ void print_usage(void)
" -f Listen for falling edges\n"
" -w Report the wall-clock time for events\n"
" -b <n> Debounce the line with period n microseconds\n"
+ " -v Verbosity\n"
" [-c <n>] Do <n> loops (optional, infinite loop if not stated)\n"
" -? This helptext\n"
"\n"
@@ -169,12 +182,13 @@ int main(int argc, char **argv)
unsigned int num_lines = 0;
unsigned int loops = 0;
struct gpio_v2_line_config config;
+ int verbosity = 0;
int c, attr, i;
unsigned long debounce_period_us = 0;

memset(&config, 0, sizeof(config));
config.flags = GPIO_V2_LINE_FLAG_INPUT;
- while ((c = getopt(argc, argv, "c:n:o:b:dsrfw?")) != -1) {
+ while ((c = getopt(argc, argv, "c:n:o:b:dsrfwv?")) != -1) {
switch (c) {
case 'c':
loops = strtoul(optarg, NULL, 10);
@@ -208,6 +222,9 @@ int main(int argc, char **argv)
case 'w':
config.flags |= GPIO_V2_LINE_FLAG_EVENT_CLOCK_REALTIME;
break;
+ case 'v':
+ ++verbosity;
+ break;
case '?':
print_usage();
return -1;
@@ -232,5 +249,6 @@ int main(int argc, char **argv)
"falling edges\n");
config.flags |= EDGE_FLAGS;
}
- return monitor_device(device_name, lines, num_lines, &config, loops);
+ return monitor_device(device_name, lines, num_lines, &config, loops,
+ verbosity);
}
--
2.17.1