mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2024-12-28 16:52:18 +00:00
tools: gpio: implement gpio-watch
Add a simple program that allows to test the new LINECHANGED_FD ioctl(). Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com> Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
This commit is contained in:
parent
51c1064e82
commit
33f0c47b8f
1
tools/gpio/.gitignore
vendored
1
tools/gpio/.gitignore
vendored
@ -1,4 +1,5 @@
|
||||
gpio-event-mon
|
||||
gpio-hammer
|
||||
gpio-watch
|
||||
lsgpio
|
||||
include/linux/gpio.h
|
||||
|
@ -2,3 +2,4 @@ gpio-utils-y += gpio-utils.o
|
||||
lsgpio-y += lsgpio.o gpio-utils.o
|
||||
gpio-hammer-y += gpio-hammer.o gpio-utils.o
|
||||
gpio-event-mon-y += gpio-event-mon.o gpio-utils.o
|
||||
gpio-watch-y += gpio-watch.o
|
||||
|
@ -18,7 +18,7 @@ MAKEFLAGS += -r
|
||||
|
||||
override CFLAGS += -O2 -Wall -g -D_GNU_SOURCE -I$(OUTPUT)include
|
||||
|
||||
ALL_TARGETS := lsgpio gpio-hammer gpio-event-mon
|
||||
ALL_TARGETS := lsgpio gpio-hammer gpio-event-mon gpio-watch
|
||||
ALL_PROGRAMS := $(patsubst %,$(OUTPUT)%,$(ALL_TARGETS))
|
||||
|
||||
all: $(ALL_PROGRAMS)
|
||||
@ -66,6 +66,15 @@ $(GPIO_EVENT_MON_IN): prepare FORCE $(OUTPUT)gpio-utils-in.o
|
||||
$(OUTPUT)gpio-event-mon: $(GPIO_EVENT_MON_IN)
|
||||
$(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $< -o $@
|
||||
|
||||
#
|
||||
# gpio-watch
|
||||
#
|
||||
GPIO_WATCH_IN := $(OUTPUT)gpio-watch-in.o
|
||||
$(GPIO_WATCH_IN): prepare FORCE
|
||||
$(Q)$(MAKE) $(build)=gpio-watch
|
||||
$(OUTPUT)gpio-watch: $(GPIO_WATCH_IN)
|
||||
$(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $< -o $@
|
||||
|
||||
clean:
|
||||
rm -f $(ALL_PROGRAMS)
|
||||
rm -f $(OUTPUT)include/linux/gpio.h
|
||||
|
99
tools/gpio/gpio-watch.c
Normal file
99
tools/gpio/gpio-watch.c
Normal file
@ -0,0 +1,99 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* gpio-watch - monitor unrequested lines for property changes using the
|
||||
* character device
|
||||
*
|
||||
* Copyright (C) 2019 BayLibre SAS
|
||||
* Author: Bartosz Golaszewski <bgolaszewski@baylibre.com>
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <poll.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct gpioline_info_changed chg;
|
||||
struct gpioline_info req;
|
||||
struct pollfd pfd;
|
||||
int fd, i, j, ret;
|
||||
char *event, *end;
|
||||
ssize_t rd;
|
||||
|
||||
if (argc < 3)
|
||||
goto err_usage;
|
||||
|
||||
fd = open(argv[1], O_RDWR | O_CLOEXEC);
|
||||
if (fd < 0) {
|
||||
perror("unable to open gpiochip");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
for (i = 0, j = 2; i < argc - 2; i++, j++) {
|
||||
memset(&req, 0, sizeof(req));
|
||||
|
||||
req.line_offset = strtoul(argv[j], &end, 0);
|
||||
if (*end != '\0')
|
||||
goto err_usage;
|
||||
|
||||
ret = ioctl(fd, GPIO_GET_LINEINFO_WATCH_IOCTL, &req);
|
||||
if (ret) {
|
||||
perror("unable to set up line watch");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
pfd.fd = fd;
|
||||
pfd.events = POLLIN | POLLPRI;
|
||||
|
||||
for (;;) {
|
||||
ret = poll(&pfd, 1, 5000);
|
||||
if (ret < 0) {
|
||||
perror("error polling the linechanged fd");
|
||||
return EXIT_FAILURE;
|
||||
} else if (ret > 0) {
|
||||
memset(&chg, 0, sizeof(chg));
|
||||
rd = read(pfd.fd, &chg, sizeof(chg));
|
||||
if (rd < 0 || rd != sizeof(chg)) {
|
||||
if (rd != sizeof(chg))
|
||||
errno = EIO;
|
||||
|
||||
perror("error reading line change event");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
switch (chg.event_type) {
|
||||
case GPIOLINE_CHANGED_REQUESTED:
|
||||
event = "requested";
|
||||
break;
|
||||
case GPIOLINE_CHANGED_RELEASED:
|
||||
event = "released";
|
||||
break;
|
||||
case GPIOLINE_CHANGED_CONFIG:
|
||||
event = "config changed";
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr,
|
||||
"invalid event type received from the kernel\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
printf("line %u: %s at %llu\n",
|
||||
chg.info.line_offset, event, chg.timestamp);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_usage:
|
||||
printf("%s: <gpiochip> <line0> <line1> ...\n", argv[0]);
|
||||
return EXIT_FAILURE;
|
||||
}
|
Loading…
Reference in New Issue
Block a user