[libgpiod][PATCH 2/2] ctxless: drop all context-less interfaces

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Bartosz Golaszewski <bgolaszewski@xxxxxxxxxxxx>

The context-less family of functions seems to be largely unused.
Drop this part of the codebase and convert tools to using the regular
low-level API.

Signed-off-by: Bartosz Golaszewski <bgolaszewski@xxxxxxxxxxxx>
---
 include/gpiod.h            | 406 ---------------------------------
 lib/Makefile.am            |   2 +-
 lib/ctxless.c              | 456 -------------------------------------
 tests/Makefile.am          |   1 -
 tests/tests-ctxless.c      | 375 ------------------------------
 tools/gpio-tools-test.bats |  12 +-
 tools/gpiofind.c           |  25 +-
 tools/gpioget.c            |  36 ++-
 tools/gpiomon.c            | 177 +++++++-------
 tools/gpioset.c            |  42 +++-
 tools/tools-common.c       |   6 +-
 11 files changed, 169 insertions(+), 1369 deletions(-)
 delete mode 100644 lib/ctxless.c
 delete mode 100644 tests/tests-ctxless.c

diff --git a/include/gpiod.h b/include/gpiod.h
index 7610eb1..97427b9 100644
--- a/include/gpiod.h
+++ b/include/gpiod.h
@@ -74,412 +74,6 @@ struct gpiod_line_bulk_iter;
  */
 #define GPIOD_BIT(nr)		(1UL << (nr))
 
-/**
- * @}
- *
- * @defgroup high_level High-level API
- * @{
- *
- * Simple high-level routines for straightforward GPIO manipulation without
- * the need to use the gpiod_* structures or to keep track of resources.
- */
-
-/**
- * @brief Miscellaneous GPIO flags.
- */
-enum {
-	GPIOD_CTXLESS_FLAG_OPEN_DRAIN		= GPIOD_BIT(0),
-	/**< The line is an open-drain port. */
-	GPIOD_CTXLESS_FLAG_OPEN_SOURCE		= GPIOD_BIT(1),
-	/**< The line is an open-source port. */
-	GPIOD_CTXLESS_FLAG_BIAS_DISABLE		= GPIOD_BIT(2),
-	/**< The line has neither either pull-up nor pull-down resistor */
-	GPIOD_CTXLESS_FLAG_BIAS_PULL_DOWN	= GPIOD_BIT(3),
-	/**< The line has pull-down resistor enabled */
-	GPIOD_CTXLESS_FLAG_BIAS_PULL_UP		= GPIOD_BIT(4),
-	/**< The line has pull-up resistor enabled */
-};
-
-/**
- * @brief Read current value from a single GPIO line.
- * @param device Name, path, number or label of the gpiochip.
- * @param offset Offset of the GPIO line.
- * @param active_low The active state of this line - true if low.
- * @param consumer Name of the consumer.
- * @return 0 or 1 (GPIO value) if the operation succeeds, -1 on error.
- */
-int gpiod_ctxless_get_value(const char *device, unsigned int offset,
-			    bool active_low, const char *consumer) GPIOD_API;
-
-/**
- * @brief Read current value from a single GPIO line.
- * @param device Name, path, number or label of the gpiochip.
- * @param offset Offset of the GPIO line.
- * @param active_low The active state of this line - true if low.
- * @param consumer Name of the consumer.
- * @param flags The flags for the line.
- * @return 0 or 1 (GPIO value) if the operation succeeds, -1 on error.
- */
-int gpiod_ctxless_get_value_ext(const char *device, unsigned int offset,
-				bool active_low, const char *consumer,
-				int flags) GPIOD_API;
-
-/**
- * @brief Read current values from a set of GPIO lines.
- * @param device Name, path, number or label of the gpiochip.
- * @param offsets Array of offsets of lines whose values should be read.
- * @param values Buffer in which the values will be stored.
- * @param num_lines Number of lines, must be > 0.
- * @param active_low The active state of the lines - true if low.
- * @param consumer Name of the consumer.
- * @return 0 if the operation succeeds, -1 on error.
- */
-int gpiod_ctxless_get_value_multiple(const char *device,
-				     const unsigned int *offsets, int *values,
-				     unsigned int num_lines, bool active_low,
-				     const char *consumer) GPIOD_API;
-
-/**
- * @brief Read current values from a set of GPIO lines.
- * @param device Name, path, number or label of the gpiochip.
- * @param offsets Array of offsets of lines whose values should be read.
- * @param values Buffer in which the values will be stored.
- * @param num_lines Number of lines, must be > 0.
- * @param active_low The active state of this line - true if low.
- * @param consumer Name of the consumer.
- * @param flags The flags for the lines.
- * @return 0 if the operation succeeds, -1 on error.
- */
-int gpiod_ctxless_get_value_multiple_ext(const char *device,
-					 const unsigned int *offsets,
-					 int *values, unsigned int num_lines,
-					 bool active_low, const char *consumer,
-					 int flags) GPIOD_API;
-
-/**
- * @brief Simple set value callback signature.
- */
-typedef void (*gpiod_ctxless_set_value_cb)(void *);
-
-/**
- * @brief Set value of a single GPIO line.
- * @param device Name, path, number or label of the gpiochip.
- * @param offset The offset of the GPIO line.
- * @param value New value (0 or 1).
- * @param active_low The active state of this line - true if low.
- * @param consumer Name of the consumer.
- * @param cb Optional callback function that will be called right after setting
- *           the value. Users can use this, for example, to pause the execution
- *           after toggling a GPIO.
- * @param data Optional user data that will be passed to the callback function.
- * @return 0 if the operation succeeds, -1 on error.
- */
-int gpiod_ctxless_set_value(const char *device, unsigned int offset, int value,
-			    bool active_low, const char *consumer,
-			    gpiod_ctxless_set_value_cb cb,
-			    void *data) GPIOD_API;
-
-/**
- * @brief Set value of a single GPIO line.
- * @param device Name, path, number or label of the gpiochip.
- * @param offset The offset of the GPIO line.
- * @param value New value (0 or 1).
- * @param active_low The active state of this line - true if low.
- * @param consumer Name of the consumer.
- * @param cb Optional callback function that will be called right after setting
- *           the value. Users can use this, for example, to pause the execution
- *           after toggling a GPIO.
- * @param data Optional user data that will be passed to the callback function.
- * @param flags The flags for the line.
- * @return 0 if the operation succeeds, -1 on error.
- */
-int gpiod_ctxless_set_value_ext(const char *device, unsigned int offset,
-				int value, bool active_low,
-				const char *consumer,
-				gpiod_ctxless_set_value_cb cb,
-				void *data, int flags) GPIOD_API;
-
-/**
- * @brief Set values of multiple GPIO lines.
- * @param device Name, path, number or label of the gpiochip.
- * @param offsets Array of offsets of lines the values of which should be set.
- * @param values Array of integers containing new values.
- * @param num_lines Number of lines, must be > 0.
- * @param active_low The active state of the lines - true if low.
- * @param consumer Name of the consumer.
- * @param cb Optional callback function that will be called right after setting
- *           all values. Works the same as in ::gpiod_ctxless_set_value.
- * @param data Optional user data that will be passed to the callback function.
- * @return 0 if the operation succeeds, -1 on error.
- */
-int gpiod_ctxless_set_value_multiple(const char *device,
-				     const unsigned int *offsets,
-				     const int *values, unsigned int num_lines,
-				     bool active_low, const char *consumer,
-				     gpiod_ctxless_set_value_cb cb,
-				     void *data) GPIOD_API;
-
-/**
- * @brief Set values of multiple GPIO lines.
- * @param device Name, path, number or label of the gpiochip.
- * @param offsets Array of offsets of lines the values of which should be set.
- * @param values Array of integers containing new values.
- * @param num_lines Number of lines, must be > 0.
- * @param active_low The active state of this line - true if low.
- * @param consumer Name of the consumer.
- * @param cb Optional callback function that will be called right after setting
- *           all values. Works the same as in ::gpiod_ctxless_set_value.
- * @param data Optional user data that will be passed to the callback function.
- * @param flags The flags for the lines.
- * @return 0 if the operation succeeds, -1 on error.
- */
-int gpiod_ctxless_set_value_multiple_ext(const char *device,
-					 const unsigned int *offsets,
-					 const int *values,
-					 unsigned int num_lines,
-					 bool active_low,
-					 const char *consumer,
-					 gpiod_ctxless_set_value_cb cb,
-					 void *data, int flags) GPIOD_API;
-
-/**
- * @brief Event types that the ctxless event monitor can wait for.
- */
-enum {
-	/**< Wait for rising edge events only. */
-	GPIOD_CTXLESS_EVENT_RISING_EDGE = 1,
-	/**< Wait for falling edge events only. */
-	GPIOD_CTXLESS_EVENT_FALLING_EDGE,
-	/**< Wait for both types of events. */
-	GPIOD_CTXLESS_EVENT_BOTH_EDGES,
-};
-
-/**
- * @brief Event types that can be passed to the ctxless event callback.
- */
-enum {
-	GPIOD_CTXLESS_EVENT_CB_TIMEOUT = 1,
-	/**< Waiting for events timed out. */
-	GPIOD_CTXLESS_EVENT_CB_RISING_EDGE,
-	/**< Rising edge event occured. */
-	GPIOD_CTXLESS_EVENT_CB_FALLING_EDGE,
-	/**< Falling edge event occured. */
-};
-
-/**
- * @brief Return status values that the ctxless event callback can return.
- */
-enum {
-	GPIOD_CTXLESS_EVENT_CB_RET_ERR = -1,
-	/**< Stop processing events and indicate an error. */
-	GPIOD_CTXLESS_EVENT_CB_RET_OK = 0,
-	/**< Continue processing events. */
-	GPIOD_CTXLESS_EVENT_CB_RET_STOP = 1,
-	/**< Stop processing events. */
-};
-
-/**
- * @brief Simple event callback signature.
- *
- * The callback function takes the following arguments: event type (int),
- * GPIO line offset (unsigned int), event timestamp (const struct timespec *)
- * and a pointer to user data (void *).
- *
- * This callback is called by the ctxless event loop functions for each GPIO
- * event. If the callback returns ::GPIOD_CTXLESS_EVENT_CB_RET_ERR, it should
- * also set errno.
- */
-typedef int (*gpiod_ctxless_event_handle_cb)(int, unsigned int,
-					     const struct timespec *, void *);
-
-/**
- * @brief Return status values that the ctxless event poll callback can return.
- *
- * Positive value returned from the polling callback indicates the number of
- * events that occurred on the set of monitored lines.
- */
-enum {
-	GPIOD_CTXLESS_EVENT_POLL_RET_STOP = -2,
-	/**< The event loop should stop processing events. */
-	GPIOD_CTXLESS_EVENT_POLL_RET_ERR = -1,
-	/**< Polling error occurred (the polling function should set errno). */
-	GPIOD_CTXLESS_EVENT_POLL_RET_TIMEOUT = 0,
-	/**< Poll timed out. */
-};
-
-/**
- * @brief Helper structure for the ctxless event loop poll callback.
- */
-struct gpiod_ctxless_event_poll_fd {
-	int fd;
-	/**< File descriptor number. */
-	bool event;
-	/**< Indicates whether an event occurred on this file descriptor. */
-};
-
-/**
- * @brief Simple event poll callback signature.
- *
- * The poll callback function takes the following arguments: number of lines
- * (unsigned int), an array of file descriptors on which input events should
- * be monitored (struct gpiod_ctxless_event_poll_fd *), poll timeout
- * (const struct timespec *) and a pointer to user data (void *).
- *
- * The callback should poll for input events on the set of descriptors and
- * return an appropriate value that can be interpreted by the event loop
- * routine.
- */
-typedef int (*gpiod_ctxless_event_poll_cb)(unsigned int,
-				struct gpiod_ctxless_event_poll_fd *,
-				const struct timespec *, void *);
-
-/**
- * @brief Wait for events on a single GPIO line.
- * @param device Name, path, number or label of the gpiochip.
- * @param event_type Type of events to listen for.
- * @param offset GPIO line offset to monitor.
- * @param active_low The active state of this line - true if low.
- * @param consumer Name of the consumer.
- * @param timeout Maximum wait time for each iteration.
- * @param poll_cb Callback function to call when waiting for events.
- * @param event_cb Callback function to call for each line event.
- * @param data User data passed to the callback.
- * @return 0 if no errors were encountered, -1 if an error occurred.
- * @note The way the ctxless event loop works is described in detail in
- *       ::gpiod_ctxless_event_monitor_multiple - this is just a wrapper aound
- *       this routine which calls it for a single GPIO line.
- */
-int gpiod_ctxless_event_monitor(const char *device, int event_type,
-				unsigned int offset, bool active_low,
-				const char *consumer,
-				const struct timespec *timeout,
-				gpiod_ctxless_event_poll_cb poll_cb,
-				gpiod_ctxless_event_handle_cb event_cb,
-				void *data) GPIOD_API;
-
-/**
- * @brief Wait for events on a single GPIO line.
- * @param device Name, path, number or label of the gpiochip.
- * @param event_type Type of events to listen for.
- * @param offset GPIO line offset to monitor.
- * @param active_low The active state of this line - true if low.
- * @param consumer Name of the consumer.
- * @param timeout Maximum wait time for each iteration.
- * @param poll_cb Callback function to call when waiting for events.
- * @param event_cb Callback function to call for each line event.
- * @param data User data passed to the callback.
- * @param flags The flags for the line.
- * @return 0 if no errors were encountered, -1 if an error occurred.
- * @note The way the ctxless event loop works is described in detail in
- *       ::gpiod_ctxless_event_monitor_multiple - this is just a wrapper aound
- *       this routine which calls it for a single GPIO line.
- */
-int gpiod_ctxless_event_monitor_ext(const char *device, int event_type,
-				    unsigned int offset, bool active_low,
-				    const char *consumer,
-				    const struct timespec *timeout,
-				    gpiod_ctxless_event_poll_cb poll_cb,
-				    gpiod_ctxless_event_handle_cb event_cb,
-				    void *data, int flags) GPIOD_API;
-
-/**
- * @brief Wait for events on multiple GPIO lines.
- * @param device Name, path, number or label of the gpiochip.
- * @param event_type Type of events to listen for.
- * @param offsets Array of GPIO line offsets to monitor.
- * @param num_lines Number of lines to monitor.
- * @param active_low The active state of this line - true if low.
- * @param consumer Name of the consumer.
- * @param timeout Maximum wait time for each iteration.
- * @param poll_cb Callback function to call when waiting for events. Can
- *                be NULL.
- * @param event_cb Callback function to call on event occurrence.
- * @param data User data passed to the callback.
- * @return 0 no errors were encountered, -1 if an error occurred.
- * @note The poll callback can be NULL in which case the routine will fall
- *       back to a basic, ppoll() based callback.
- *
- * Internally this routine opens the GPIO chip, requests the set of lines for
- * the type of events specified in the event_type parameter and calls the
- * polling callback in a loop. The role of the polling callback is to detect
- * input events on a set of file descriptors and notify the caller about the
- * fds ready for reading.
- *
- * The ctxless event loop then reads each queued event from marked descriptors
- * and calls the event callback. Both callbacks can stop the loop at any
- * point.
- *
- * The poll_cb argument can be NULL in which case the function falls back to
- * a default, ppoll() based callback.
- */
-int gpiod_ctxless_event_monitor_multiple(
-			const char *device, int event_type,
-			const unsigned int *offsets,
-			unsigned int num_lines, bool active_low,
-			const char *consumer, const struct timespec *timeout,
-			gpiod_ctxless_event_poll_cb poll_cb,
-			gpiod_ctxless_event_handle_cb event_cb,
-			void *data) GPIOD_API;
-
-/**
- * @brief Wait for events on multiple GPIO lines.
- * @param device Name, path, number or label of the gpiochip.
- * @param event_type Type of events to listen for.
- * @param offsets Array of GPIO line offsets to monitor.
- * @param num_lines Number of lines to monitor.
- * @param active_low The active state of this line - true if low.
- * @param consumer Name of the consumer.
- * @param timeout Maximum wait time for each iteration.
- * @param poll_cb Callback function to call when waiting for events. Can
- *                be NULL.
- * @param event_cb Callback function to call on event occurrence.
- * @param data User data passed to the callback.
- * @param flags The flags for the lines.
- * @return 0 no errors were encountered, -1 if an error occurred.
- * @note The poll callback can be NULL in which case the routine will fall
- *       back to a basic, ppoll() based callback.
- *
- * Internally this routine opens the GPIO chip, requests the set of lines for
- * the type of events specified in the event_type parameter and calls the
- * polling callback in a loop. The role of the polling callback is to detect
- * input events on a set of file descriptors and notify the caller about the
- * fds ready for reading.
- *
- * The ctxless event loop then reads each queued event from marked descriptors
- * and calls the event callback. Both callbacks can stop the loop at any
- * point.
- *
- * The poll_cb argument can be NULL in which case the function falls back to
- * a default, ppoll() based callback.
- */
-int gpiod_ctxless_event_monitor_multiple_ext(
-			const char *device, int event_type,
-			const unsigned int *offsets,
-			unsigned int num_lines, bool active_low,
-			const char *consumer, const struct timespec *timeout,
-			gpiod_ctxless_event_poll_cb poll_cb,
-			gpiod_ctxless_event_handle_cb event_cb,
-			void *data, int flags) GPIOD_API;
-
-
-/**
- * @brief Determine the chip name and line offset of a line with given name.
- * @param name The name of the GPIO line to lookup.
- * @param chipname Buffer in which the name of the GPIO chip will be stored.
- * @param chipname_size Size of the chip name buffer.
- * @param offset Pointer to an integer in which the line offset will be stored.
- * @return -1 on error, 0 if the line with given name doesn't exist and 1 if
- *         the line was found. In the first two cases the contents of chipname
- *         and offset remain unchanged.
- * @note The chip name is truncated if the buffer can't hold its entire size.
- * @attention GPIO line names are not unique in the linux kernel, neither
- *            globally nor within a single chip. This function finds the first
- *            line with given name.
- */
-int gpiod_ctxless_find_line(const char *name, char *chipname,
-			    size_t chipname_size,
-			    unsigned int *offset) GPIOD_API;
-
 /**
  * @}
  *
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 53ef771..c5277ce 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -7,7 +7,7 @@
 #
 
 lib_LTLIBRARIES = libgpiod.la
-libgpiod_la_SOURCES = core.c ctxless.c helpers.c iter.c misc.c
+libgpiod_la_SOURCES = core.c helpers.c iter.c misc.c
 libgpiod_la_CFLAGS = -Wall -Wextra -g -std=gnu89
 libgpiod_la_CFLAGS += -fvisibility=hidden -I$(top_srcdir)/include/
 libgpiod_la_CFLAGS += -include $(top_builddir)/config.h
diff --git a/lib/ctxless.c b/lib/ctxless.c
deleted file mode 100644
index 091d788..0000000
--- a/lib/ctxless.c
+++ /dev/null
@@ -1,456 +0,0 @@
-// SPDX-License-Identifier: LGPL-2.1-or-later
-/*
- * This file is part of libgpiod.
- *
- * Copyright (C) 2017-2018 Bartosz Golaszewski <bartekgola@xxxxxxxxx>
- */
-
-/* Implementation of the high-level API. */
-
-
-#include <errno.h>
-#include <gpiod.h>
-#include <poll.h>
-#include <stdio.h>
-#include <string.h>
-
-static int ctxless_flags_to_line_request_flags(bool active_low, int flags)
-{
-	int req_flags = 0;
-
-	if (active_low)
-		req_flags |= GPIOD_LINE_REQUEST_FLAG_ACTIVE_LOW;
-	if (flags & GPIOD_CTXLESS_FLAG_OPEN_DRAIN)
-		req_flags |= GPIOD_LINE_REQUEST_FLAG_OPEN_DRAIN;
-	if (flags & GPIOD_CTXLESS_FLAG_OPEN_SOURCE)
-		req_flags |= GPIOD_LINE_REQUEST_FLAG_OPEN_SOURCE;
-	if (flags & GPIOD_CTXLESS_FLAG_BIAS_DISABLE)
-		req_flags |= GPIOD_LINE_REQUEST_FLAG_BIAS_DISABLE;
-	if (flags & GPIOD_CTXLESS_FLAG_BIAS_PULL_UP)
-		req_flags |= GPIOD_LINE_REQUEST_FLAG_BIAS_PULL_UP;
-	if (flags & GPIOD_CTXLESS_FLAG_BIAS_PULL_DOWN)
-		req_flags |= GPIOD_LINE_REQUEST_FLAG_BIAS_PULL_DOWN;
-
-	return req_flags;
-}
-
-int gpiod_ctxless_get_value(const char *device, unsigned int offset,
-			    bool active_low, const char *consumer)
-{
-	int value, rv;
-
-	rv = gpiod_ctxless_get_value_multiple(device, &offset, &value,
-					      1, active_low, consumer);
-	if (rv < 0)
-		return rv;
-
-	return value;
-}
-
-int gpiod_ctxless_get_value_ext(const char *device, unsigned int offset,
-				bool active_low, const char *consumer,
-				int flags)
-{
-	int value, rv;
-
-	rv = gpiod_ctxless_get_value_multiple_ext(device, &offset, &value, 1,
-						  active_low, consumer, flags);
-	if (rv < 0)
-		return rv;
-
-	return value;
-}
-
-int gpiod_ctxless_get_value_multiple(const char *device,
-				     const unsigned int *offsets, int *values,
-				     unsigned int num_lines, bool active_low,
-				     const char *consumer)
-{
-	int rv;
-
-	rv = gpiod_ctxless_get_value_multiple_ext(device, offsets, values,
-						  num_lines, active_low,
-						  consumer, 0);
-	return rv;
-}
-
-int gpiod_ctxless_get_value_multiple_ext(const char *device,
-					 const unsigned int *offsets,
-					 int *values, unsigned int num_lines,
-					 bool active_low,
-					 const char *consumer, int flags)
-{
-	struct gpiod_line_bulk *bulk;
-	struct gpiod_chip *chip;
-	struct gpiod_line *line;
-	unsigned int i;
-	int rv, req_flags;
-
-	if (!num_lines || num_lines > GPIOD_LINE_BULK_MAX_LINES) {
-		errno = EINVAL;
-		return -1;
-	}
-
-	chip = gpiod_chip_open_lookup(device);
-	if (!chip)
-		return -1;
-
-	bulk = gpiod_line_bulk_new(num_lines);
-	if (!bulk) {
-		gpiod_chip_close(chip);
-		return -1;
-	}
-
-	for (i = 0; i < num_lines; i++) {
-		line = gpiod_chip_get_line(chip, offsets[i]);
-		if (!line) {
-			gpiod_line_bulk_free(bulk);
-			gpiod_chip_close(chip);
-			return -1;
-		}
-
-		gpiod_line_bulk_add_line(bulk, line);
-	}
-
-	req_flags = ctxless_flags_to_line_request_flags(active_low, flags);
-	rv = gpiod_line_request_bulk_input_flags(bulk, consumer, req_flags);
-	if (rv < 0) {
-		gpiod_line_bulk_free(bulk);
-		gpiod_chip_close(chip);
-		return -1;
-	}
-
-	memset(values, 0, sizeof(*values) * num_lines);
-	rv = gpiod_line_get_value_bulk(bulk, values);
-
-	gpiod_line_bulk_free(bulk);
-	gpiod_chip_close(chip);
-
-	return rv;
-}
-
-int gpiod_ctxless_set_value(const char *device, unsigned int offset, int value,
-			    bool active_low, const char *consumer,
-			    gpiod_ctxless_set_value_cb cb, void *data)
-{
-	return gpiod_ctxless_set_value_multiple(device, &offset, &value, 1,
-						active_low, consumer, cb, data);
-}
-
-int gpiod_ctxless_set_value_ext(const char *device, unsigned int offset,
-				int value, bool active_low,
-				const char *consumer,
-				gpiod_ctxless_set_value_cb cb,
-				void *data, int flags)
-{
-	return gpiod_ctxless_set_value_multiple_ext(device, &offset, &value,
-						    1, active_low, consumer,
-						    cb, data, flags);
-}
-
-int gpiod_ctxless_set_value_multiple(const char *device,
-				     const unsigned int *offsets,
-				     const int *values, unsigned int num_lines,
-				     bool active_low, const char *consumer,
-				     gpiod_ctxless_set_value_cb cb, void *data)
-{
-	return gpiod_ctxless_set_value_multiple_ext(device, offsets, values,
-						    num_lines, active_low,
-						    consumer, cb, data, 0);
-}
-
-int gpiod_ctxless_set_value_multiple_ext(
-			const char *device, const unsigned int *offsets,
-			const int *values, unsigned int num_lines,
-			bool active_low, const char *consumer,
-			gpiod_ctxless_set_value_cb cb, void *data, int flags)
-{
-	struct gpiod_line_bulk *bulk;
-	struct gpiod_chip *chip;
-	struct gpiod_line *line;
-	unsigned int i;
-	int rv, req_flags;
-
-	if (!num_lines || num_lines > GPIOD_LINE_BULK_MAX_LINES) {
-		errno = EINVAL;
-		return -1;
-	}
-
-	chip = gpiod_chip_open_lookup(device);
-	if (!chip)
-		return -1;
-
-	bulk = gpiod_line_bulk_new(num_lines);
-	if (!bulk) {
-		gpiod_chip_close(chip);
-		return -1;
-	}
-
-	for (i = 0; i < num_lines; i++) {
-		line = gpiod_chip_get_line(chip, offsets[i]);
-		if (!line) {
-			gpiod_line_bulk_free(bulk);
-			gpiod_chip_close(chip);
-			return -1;
-		}
-
-		gpiod_line_bulk_add_line(bulk, line);
-	}
-
-	req_flags = ctxless_flags_to_line_request_flags(active_low, flags);
-	rv = gpiod_line_request_bulk_output_flags(bulk, consumer,
-						  req_flags, values);
-	if (rv < 0) {
-		gpiod_line_bulk_free(bulk);
-		gpiod_chip_close(chip);
-		return -1;
-	}
-
-	if (cb)
-		cb(data);
-
-	gpiod_line_bulk_free(bulk);
-	gpiod_chip_close(chip);
-
-	return 0;
-}
-
-static int basic_event_poll(unsigned int num_lines,
-			    struct gpiod_ctxless_event_poll_fd *fds,
-			    const struct timespec *timeout,
-			    void *data GPIOD_UNUSED)
-{
-	struct pollfd poll_fds[GPIOD_LINE_BULK_MAX_LINES];
-	unsigned int i;
-	int rv, ret;
-
-	if (!num_lines || num_lines > GPIOD_LINE_BULK_MAX_LINES)
-		return GPIOD_CTXLESS_EVENT_POLL_RET_ERR;
-
-	memset(poll_fds, 0, sizeof(poll_fds));
-
-	for (i = 0; i < num_lines; i++) {
-		poll_fds[i].fd = fds[i].fd;
-		poll_fds[i].events = POLLIN | POLLPRI;
-	}
-
-	rv = ppoll(poll_fds, num_lines, timeout, NULL);
-	if (rv < 0) {
-		if (errno == EINTR)
-			return GPIOD_CTXLESS_EVENT_POLL_RET_TIMEOUT;
-		else
-			return GPIOD_CTXLESS_EVENT_POLL_RET_ERR;
-	} else if (rv == 0) {
-		return GPIOD_CTXLESS_EVENT_POLL_RET_TIMEOUT;
-	}
-
-	ret = rv;
-	for (i = 0; i < num_lines; i++) {
-		if (poll_fds[i].revents) {
-			fds[i].event = true;
-			if (!--rv)
-				break;
-		}
-	}
-
-	return ret;
-}
-
-int gpiod_ctxless_event_monitor(const char *device, int event_type,
-				unsigned int offset, bool active_low,
-				const char *consumer,
-				const struct timespec *timeout,
-				gpiod_ctxless_event_poll_cb poll_cb,
-				gpiod_ctxless_event_handle_cb event_cb,
-				void *data)
-{
-	return gpiod_ctxless_event_monitor_multiple(device, event_type,
-						    &offset, 1, active_low,
-						    consumer, timeout,
-						    poll_cb, event_cb, data);
-}
-
-int gpiod_ctxless_event_monitor_ext(const char *device, int event_type,
-				    unsigned int offset, bool active_low,
-				    const char *consumer,
-				    const struct timespec *timeout,
-				    gpiod_ctxless_event_poll_cb poll_cb,
-				    gpiod_ctxless_event_handle_cb event_cb,
-				    void *data, int flags)
-{
-	return gpiod_ctxless_event_monitor_multiple_ext(
-			device, event_type, &offset, 1, active_low,
-			consumer, timeout, poll_cb, event_cb, data, flags);
-}
-
-int gpiod_ctxless_event_monitor_multiple(
-			const char *device, int event_type,
-			const unsigned int *offsets,
-			unsigned int num_lines, bool active_low,
-			const char *consumer,
-			const struct timespec *timeout,
-			gpiod_ctxless_event_poll_cb poll_cb,
-			gpiod_ctxless_event_handle_cb event_cb,
-			void *data)
-{
-	return gpiod_ctxless_event_monitor_multiple_ext(
-			device, event_type, offsets,
-			num_lines, active_low, consumer, timeout,
-			poll_cb, event_cb, data, 0);
-}
-
-int gpiod_ctxless_event_monitor_multiple_ext(
-			const char *device, int event_type,
-			const unsigned int *offsets,
-			unsigned int num_lines, bool active_low,
-			const char *consumer, const struct timespec *timeout,
-			gpiod_ctxless_event_poll_cb poll_cb,
-			gpiod_ctxless_event_handle_cb event_cb,
-			void *data, int flags)
-{
-	struct gpiod_ctxless_event_poll_fd fds[GPIOD_LINE_BULK_MAX_LINES];
-	struct gpiod_line_request_config conf;
-	struct gpiod_line_event event;
-	struct gpiod_line_bulk *bulk;
-	int rv, ret, evtype, cnt;
-	struct gpiod_chip *chip;
-	struct gpiod_line *line;
-	unsigned int i;
-
-	if (!num_lines || num_lines > GPIOD_LINE_BULK_MAX_LINES) {
-		errno = EINVAL;
-		return -1;
-	}
-
-	if (!poll_cb)
-		poll_cb = basic_event_poll;
-
-	chip = gpiod_chip_open_lookup(device);
-	if (!chip)
-		return -1;
-
-	bulk = gpiod_line_bulk_new(num_lines);
-	if (!bulk) {
-		gpiod_chip_close(chip);
-		return -1;
-	}
-
-	for (i = 0; i < num_lines; i++) {
-		line = gpiod_chip_get_line(chip, offsets[i]);
-		if (!line) {
-			ret = -1;
-			goto out;
-		}
-
-		gpiod_line_bulk_add_line(bulk, line);
-	}
-
-	conf.flags = ctxless_flags_to_line_request_flags(active_low, flags);
-	conf.consumer = consumer;
-
-	if (event_type == GPIOD_CTXLESS_EVENT_RISING_EDGE) {
-		conf.request_type = GPIOD_LINE_REQUEST_EVENT_RISING_EDGE;
-	} else if (event_type == GPIOD_CTXLESS_EVENT_FALLING_EDGE) {
-		conf.request_type = GPIOD_LINE_REQUEST_EVENT_FALLING_EDGE;
-	} else if (event_type == GPIOD_CTXLESS_EVENT_BOTH_EDGES) {
-		conf.request_type = GPIOD_LINE_REQUEST_EVENT_BOTH_EDGES;
-	} else {
-		errno = -EINVAL;
-		ret = -1;
-		goto out;
-	}
-
-	rv = gpiod_line_request_bulk(bulk, &conf, NULL);
-	if (rv) {
-		ret = -1;
-		goto out;
-	}
-
-	memset(fds, 0, sizeof(fds));
-	for (i = 0; i < num_lines; i++) {
-		line = gpiod_line_bulk_get_line(bulk, i);
-		fds[i].fd = gpiod_line_event_get_fd(line);
-	}
-
-	for (;;) {
-		for (i = 0; i < num_lines; i++)
-			fds[i].event = false;
-
-		cnt = poll_cb(num_lines, fds, timeout, data);
-		if (cnt == GPIOD_CTXLESS_EVENT_POLL_RET_ERR) {
-			ret = -1;
-			goto out;
-		} else if (cnt == GPIOD_CTXLESS_EVENT_POLL_RET_TIMEOUT) {
-			rv = event_cb(GPIOD_CTXLESS_EVENT_CB_TIMEOUT,
-				      0, &event.ts, data);
-			if (rv == GPIOD_CTXLESS_EVENT_CB_RET_ERR) {
-				ret = -1;
-				goto out;
-			} else if (rv == GPIOD_CTXLESS_EVENT_CB_RET_STOP) {
-				ret = 0;
-				goto out;
-			}
-		} else if (cnt == GPIOD_CTXLESS_EVENT_POLL_RET_STOP) {
-			ret = 0;
-			goto out;
-		}
-
-		for (i = 0; i < num_lines; i++) {
-			if (!fds[i].event)
-				continue;
-
-			line = gpiod_line_bulk_get_line(bulk, i);
-			rv = gpiod_line_event_read(line, &event);
-			if (rv < 0) {
-				ret = rv;
-				goto out;
-			}
-
-			if (event.event_type == GPIOD_LINE_EVENT_RISING_EDGE)
-				evtype = GPIOD_CTXLESS_EVENT_CB_RISING_EDGE;
-			else
-				evtype = GPIOD_CTXLESS_EVENT_CB_FALLING_EDGE;
-
-			rv = event_cb(evtype, gpiod_line_offset(line),
-				      &event.ts, data);
-			if (rv == GPIOD_CTXLESS_EVENT_CB_RET_ERR) {
-				ret = -1;
-				goto out;
-			} else if (rv == GPIOD_CTXLESS_EVENT_CB_RET_STOP) {
-				ret = 0;
-				goto out;
-			}
-
-			if (!--cnt)
-				break;
-		}
-	}
-
-out:
-	gpiod_line_bulk_free(bulk);
-	gpiod_chip_close(chip);
-
-	return ret;
-}
-
-int gpiod_ctxless_find_line(const char *name, char *chipname,
-			    size_t chipname_size, unsigned int *offset)
-{
-	struct gpiod_chip *chip;
-	struct gpiod_line *line;
-
-	line = gpiod_line_find(name);
-	if (!line) {
-		if (errno == ENOENT)
-			return 0;
-		else
-			return -1;
-	}
-
-	chip = gpiod_line_get_chip(line);
-	snprintf(chipname, chipname_size, "%s", gpiod_chip_name(chip));
-	*offset = gpiod_line_offset(line);
-	gpiod_chip_close(chip);
-
-	return 1;
-}
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 4a3befd..5c7edb6 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -24,7 +24,6 @@ gpiod_test_SOURCES =			\
 		gpiod-test.h		\
 		tests-bulk.c		\
 		tests-chip.c		\
-		tests-ctxless.c		\
 		tests-event.c		\
 		tests-iter.c		\
 		tests-line.c		\
diff --git a/tests/tests-ctxless.c b/tests/tests-ctxless.c
deleted file mode 100644
index 76b9a7c..0000000
--- a/tests/tests-ctxless.c
+++ /dev/null
@@ -1,375 +0,0 @@
-// SPDX-License-Identifier: LGPL-2.1-or-later
-/*
- * This file is part of libgpiod.
- *
- * Copyright (C) 2019 Bartosz Golaszewski <bgolaszewski@xxxxxxxxxxxx>
- */
-
-#include <errno.h>
-
-#include "gpiod-test.h"
-
-#define GPIOD_TEST_GROUP "ctxless"
-
-GPIOD_TEST_CASE(get_value, 0, { 8 })
-{
-	gint ret;
-
-	ret = gpiod_ctxless_get_value(gpiod_test_chip_name(0), 3,
-				      false, GPIOD_TEST_CONSUMER);
-	g_assert_cmpint(ret, ==, 0);
-
-	gpiod_test_chip_set_pull(0, 3, 1);
-
-	ret = gpiod_ctxless_get_value(gpiod_test_chip_name(0), 3,
-				      false, GPIOD_TEST_CONSUMER);
-	g_assert_cmpint(ret, ==, 1);
-}
-
-GPIOD_TEST_CASE(get_value_ext, 0, { 8 })
-{
-	gint ret;
-
-	ret = gpiod_ctxless_get_value_ext(gpiod_test_chip_name(0), 3,
-				false, GPIOD_TEST_CONSUMER,
-				GPIOD_CTXLESS_FLAG_BIAS_PULL_DOWN);
-	g_assert_cmpint(ret, ==, 0);
-
-	ret = gpiod_ctxless_get_value_ext(gpiod_test_chip_name(0), 3,
-				false, GPIOD_TEST_CONSUMER,
-				GPIOD_CTXLESS_FLAG_BIAS_PULL_UP);
-	g_assert_cmpint(ret, ==, 1);
-
-	ret = gpiod_ctxless_get_value_ext(gpiod_test_chip_name(0), 3,
-				true, GPIOD_TEST_CONSUMER
-				, GPIOD_CTXLESS_FLAG_BIAS_PULL_DOWN);
-	g_assert_cmpint(ret, ==, 1);
-
-	ret = gpiod_ctxless_get_value_ext(gpiod_test_chip_name(0), 3,
-				true, GPIOD_TEST_CONSUMER,
-				GPIOD_CTXLESS_FLAG_BIAS_PULL_UP);
-	g_assert_cmpint(ret, ==, 0);
-}
-
-static void set_value_check_hi(gpointer data G_GNUC_UNUSED)
-{
-	g_assert_cmpint(gpiod_test_chip_get_value(0, 3), ==, 1);
-}
-
-static void set_value_check_lo(gpointer data G_GNUC_UNUSED)
-{
-	g_assert_cmpint(gpiod_test_chip_get_value(0, 3), ==, 0);
-}
-
-GPIOD_TEST_CASE(set_value, 0, { 8 })
-{
-	gint ret;
-
-	gpiod_test_chip_set_pull(0, 3, 0);
-
-	ret = gpiod_ctxless_set_value(gpiod_test_chip_name(0), 3, 1,
-				      false, GPIOD_TEST_CONSUMER,
-				      set_value_check_hi, NULL);
-	gpiod_test_return_if_failed();
-	g_assert_cmpint(ret, ==, 0);
-
-	g_assert_cmpint(gpiod_test_chip_get_value(0, 3), ==, 0);
-}
-
-GPIOD_TEST_CASE(set_value_ext, 0, { 8 })
-{
-	gint ret;
-
-	gpiod_test_chip_set_pull(0, 3, 0);
-
-	ret = gpiod_ctxless_set_value_ext(gpiod_test_chip_name(0), 3, 1,
-			false, GPIOD_TEST_CONSUMER,
-			set_value_check_hi, NULL, 0);
-	gpiod_test_return_if_failed();
-	g_assert_cmpint(ret, ==, 0);
-	g_assert_cmpint(gpiod_test_chip_get_value(0, 3), ==, 0);
-
-	/* test drive flags by checking that sets are caught by emulation */
-	ret = gpiod_ctxless_set_value_ext(gpiod_test_chip_name(0), 3, 1,
-			false, GPIOD_TEST_CONSUMER, set_value_check_lo,
-			NULL, GPIOD_CTXLESS_FLAG_OPEN_DRAIN);
-	gpiod_test_return_if_failed();
-	g_assert_cmpint(ret, ==, 0);
-	g_assert_cmpint(gpiod_test_chip_get_value(0, 3), ==, 0);
-
-	gpiod_test_chip_set_pull(0, 3, 1);
-	ret = gpiod_ctxless_set_value_ext(gpiod_test_chip_name(0), 3, 0,
-			false, GPIOD_TEST_CONSUMER, set_value_check_hi,
-			NULL, GPIOD_CTXLESS_FLAG_OPEN_SOURCE);
-	gpiod_test_return_if_failed();
-	g_assert_cmpint(ret, ==, 0);
-	g_assert_cmpint(gpiod_test_chip_get_value(0, 3), ==, 1);
-}
-
-static const guint get_value_multiple_offsets[] = {
-	1, 3, 4, 5, 6, 7, 8, 9, 13, 14
-};
-
-static const gint get_value_multiple_expected[] = {
-	1, 1, 1, 0, 0, 0, 1, 0, 1, 1
-};
-
-GPIOD_TEST_CASE(get_value_multiple, 0, { 16 })
-{
-	gint ret, values[10];
-	guint i;
-
-	for (i = 0; i < G_N_ELEMENTS(get_value_multiple_offsets); i++)
-		gpiod_test_chip_set_pull(0, get_value_multiple_offsets[i],
-					 get_value_multiple_expected[i]);
-
-	ret = gpiod_ctxless_get_value_multiple(gpiod_test_chip_name(0),
-					       get_value_multiple_offsets,
-					       values, 10, false,
-					       GPIOD_TEST_CONSUMER);
-	g_assert_cmpint(ret, ==, 0);
-
-	for (i = 0; i < G_N_ELEMENTS(get_value_multiple_offsets); i++)
-		g_assert_cmpint(values[i], ==, get_value_multiple_expected[i]);
-}
-
-static const guint set_value_multiple_offsets[] = {
-	0, 1, 2, 3, 4, 5, 6, 12, 13, 15
-};
-
-static const gint set_value_multiple_values[] = {
-	1, 1, 1, 0, 0, 1, 0, 1, 0, 0
-};
-
-static void set_value_multiple_check(gpointer data G_GNUC_UNUSED)
-{
-	guint i, offset;
-	gint val, exp;
-
-	for (i = 0; i < G_N_ELEMENTS(set_value_multiple_values); i++) {
-		offset = set_value_multiple_offsets[i];
-		exp = set_value_multiple_values[i];
-		val = gpiod_test_chip_get_value(0, offset);
-
-		g_assert_cmpint(val, ==, exp);
-	}
-}
-
-GPIOD_TEST_CASE(set_value_multiple, 0, { 16 })
-{
-	gint values[10], ret;
-	guint i;
-
-	for (i = 0; i < G_N_ELEMENTS(set_value_multiple_offsets); i++)
-		values[i] = set_value_multiple_values[i];
-
-	ret = gpiod_ctxless_set_value_multiple(gpiod_test_chip_name(0),
-			set_value_multiple_offsets, values, 10, false,
-			GPIOD_TEST_CONSUMER, set_value_multiple_check, NULL);
-	gpiod_test_return_if_failed();
-	g_assert_cmpint(ret, ==, 0);
-}
-
-GPIOD_TEST_CASE(get_value_multiple_max_lines, 0, { 128 })
-{
-	gint values[GPIOD_LINE_BULK_MAX_LINES + 1], ret;
-	guint offsets[GPIOD_LINE_BULK_MAX_LINES + 1];
-
-	ret = gpiod_ctxless_get_value_multiple(gpiod_test_chip_name(0),
-					       offsets, values,
-					       GPIOD_LINE_BULK_MAX_LINES + 1,
-					       false, GPIOD_TEST_CONSUMER);
-	g_assert_cmpint(ret, ==, -1);
-	g_assert_cmpint(errno, ==, EINVAL);
-}
-
-GPIOD_TEST_CASE(set_value_multiple_max_lines, 0, { 128 })
-{
-	gint values[GPIOD_LINE_BULK_MAX_LINES + 1], ret;
-	guint offsets[GPIOD_LINE_BULK_MAX_LINES + 1];
-
-	ret = gpiod_ctxless_set_value_multiple(gpiod_test_chip_name(0),
-				offsets, values, GPIOD_LINE_BULK_MAX_LINES + 1,
-				false, GPIOD_TEST_CONSUMER, NULL, NULL);
-	g_assert_cmpint(ret, ==, -1);
-	g_assert_cmpint(errno, ==, EINVAL);
-}
-
-struct ctxless_event_data {
-	gboolean got_rising_edge;
-	gboolean got_falling_edge;
-	guint offset;
-	guint count;
-};
-
-static int ctxless_event_cb(gint evtype, guint offset,
-			    const struct timespec *ts G_GNUC_UNUSED,
-			    gpointer data)
-{
-	struct ctxless_event_data *evdata = data;
-
-	if (evtype == GPIOD_CTXLESS_EVENT_CB_RISING_EDGE)
-		evdata->got_rising_edge = TRUE;
-	else if (evtype == GPIOD_CTXLESS_EVENT_CB_FALLING_EDGE)
-		evdata->got_falling_edge = TRUE;
-
-	evdata->offset = offset;
-
-	return ++evdata->count == 2 ? GPIOD_CTXLESS_EVENT_CB_RET_STOP
-				    : GPIOD_CTXLESS_EVENT_CB_RET_OK;
-}
-
-GPIOD_TEST_CASE(event_monitor, 0, { 8 })
-{
-	g_autoptr(GpiodTestEventThread) ev_thread = NULL;
-	struct ctxless_event_data evdata = { false, false, 0, 0 };
-	struct timespec ts = { 1, 0 };
-	gint ret;
-
-	ev_thread = gpiod_test_start_event_thread(0, 3, 100);
-
-	ret = gpiod_ctxless_event_monitor(gpiod_test_chip_name(0),
-					  GPIOD_CTXLESS_EVENT_BOTH_EDGES,
-					  3, false, GPIOD_TEST_CONSUMER, &ts,
-					  NULL, ctxless_event_cb, &evdata);
-	g_assert_cmpint(ret, ==, 0);
-	g_assert_true(evdata.got_rising_edge);
-	g_assert_true(evdata.got_falling_edge);
-	g_assert_cmpuint(evdata.count, ==, 2);
-	g_assert_cmpuint(evdata.offset, ==, 3);
-}
-
-GPIOD_TEST_CASE(event_monitor_single_event_type, 0, { 8 })
-{
-	g_autoptr(GpiodTestEventThread) ev_thread = NULL;
-	struct ctxless_event_data evdata = { false, false, 0, 0 };
-	struct timespec ts = { 1, 0 };
-	gint ret;
-
-	ev_thread = gpiod_test_start_event_thread(0, 3, 100);
-
-	ret = gpiod_ctxless_event_monitor(gpiod_test_chip_name(0),
-					  GPIOD_CTXLESS_EVENT_FALLING_EDGE,
-					  3, false, GPIOD_TEST_CONSUMER, &ts,
-					  NULL, ctxless_event_cb, &evdata);
-	g_assert_cmpint(ret, ==, 0);
-	g_assert_false(evdata.got_rising_edge);
-	g_assert_true(evdata.got_falling_edge);
-	g_assert_cmpuint(evdata.count, ==, 2);
-	g_assert_cmpuint(evdata.offset, ==, 3);
-}
-
-GPIOD_TEST_CASE(event_monitor_multiple, 0, { 8 })
-{
-	g_autoptr(GpiodTestEventThread) ev_thread = NULL;
-	struct ctxless_event_data evdata = { false, false, 0, 0 };
-	struct timespec ts = { 1, 0 };
-	guint offsets[4];
-	gint ret;
-
-	offsets[0] = 2;
-	offsets[1] = 3;
-	offsets[2] = 5;
-	offsets[3] = 6;
-
-	ev_thread = gpiod_test_start_event_thread(0, 3, 100);
-
-	ret = gpiod_ctxless_event_monitor_multiple(gpiod_test_chip_name(0),
-		GPIOD_CTXLESS_EVENT_BOTH_EDGES, offsets, 4, false,
-		GPIOD_TEST_CONSUMER, &ts, NULL, ctxless_event_cb, &evdata);
-	g_assert_cmpint(ret, ==, 0);
-	g_assert_true(evdata.got_rising_edge);
-	g_assert_true(evdata.got_falling_edge);
-	g_assert_cmpuint(evdata.count, ==, 2);
-	g_assert_cmpuint(evdata.offset, ==, 3);
-}
-
-static int error_event_cb(gint evtype G_GNUC_UNUSED,
-			  guint offset G_GNUC_UNUSED,
-			  const struct timespec *ts G_GNUC_UNUSED,
-			  gpointer data G_GNUC_UNUSED)
-{
-	errno = ENOTBLK;
-
-	return GPIOD_CTXLESS_EVENT_CB_RET_ERR;
-}
-
-GPIOD_TEST_CASE(event_monitor_indicate_error, 0, { 8 })
-{
-	g_autoptr(GpiodTestEventThread) ev_thread = NULL;
-	struct timespec ts = { 1, 0 };
-	gint ret;
-
-	ev_thread = gpiod_test_start_event_thread(0, 3, 100);
-
-	ret = gpiod_ctxless_event_monitor(gpiod_test_chip_name(0),
-					  GPIOD_CTXLESS_EVENT_BOTH_EDGES,
-					  3, false, GPIOD_TEST_CONSUMER, &ts,
-					  NULL, error_event_cb, NULL);
-	g_assert_cmpint(ret, ==, -1);
-	g_assert_cmpint(errno, ==, ENOTBLK);
-}
-
-static int error_event_cb_timeout(gint evtype,
-				  guint offset G_GNUC_UNUSED,
-				  const struct timespec *ts G_GNUC_UNUSED,
-				  gpointer data G_GNUC_UNUSED)
-{
-	errno = ENOTBLK;
-
-	g_assert_cmpint(evtype, ==, GPIOD_CTXLESS_EVENT_CB_TIMEOUT);
-
-	return GPIOD_CTXLESS_EVENT_CB_RET_ERR;
-}
-
-GPIOD_TEST_CASE(event_monitor_indicate_error_timeout, 0, { 8 })
-{
-	struct timespec ts = { 0, 100000 };
-	gint ret;
-
-	ret = gpiod_ctxless_event_monitor(gpiod_test_chip_name(0),
-					  GPIOD_CTXLESS_EVENT_BOTH_EDGES,
-					  3, false, GPIOD_TEST_CONSUMER, &ts,
-					  NULL, error_event_cb_timeout, NULL);
-	g_assert_cmpint(ret, ==, -1);
-	g_assert_cmpint(errno, ==, ENOTBLK);
-}
-
-GPIOD_TEST_CASE(find_line, GPIOD_TEST_FLAG_NAMED_LINES, { 8, 16, 16, 8 })
-{
-	gchar chip[32];
-	guint offset;
-	gint ret;
-
-	ret = gpiod_ctxless_find_line("gpio-mockup-C-14", chip,
-				      sizeof(chip), &offset);
-	g_assert_cmpint(ret, ==, 1);
-	g_assert_cmpuint(offset, ==, 14);
-	g_assert_cmpstr(chip, ==, gpiod_test_chip_name(2));
-}
-
-GPIOD_TEST_CASE(find_line_truncated,
-		GPIOD_TEST_FLAG_NAMED_LINES, { 8, 16, 16, 8 })
-{
-	gchar chip[6];
-	guint offset;
-	gint ret;
-
-	ret = gpiod_ctxless_find_line("gpio-mockup-C-14", chip,
-				      sizeof(chip), &offset);
-	g_assert_cmpint(ret, ==, 1);
-	g_assert_cmpuint(offset, ==, 14);
-	g_assert_cmpstr(chip, ==, "gpioc");
-}
-
-GPIOD_TEST_CASE(find_line_not_found,
-		GPIOD_TEST_FLAG_NAMED_LINES, { 8, 16, 16, 8 })
-{
-	gchar chip[32];
-	guint offset;
-	gint ret;
-
-	ret = gpiod_ctxless_find_line("nonexistent", chip,
-				      sizeof(chip), &offset);
-	g_assert_cmpint(ret, ==, 0);
-}
diff --git a/tools/gpio-tools-test.bats b/tools/gpio-tools-test.bats
index b756c43..ec39046 100755
--- a/tools/gpio-tools-test.bats
+++ b/tools/gpio-tools-test.bats
@@ -375,7 +375,7 @@ teardown() {
 	run_tool gpioget "$(gpio_mockup_chip_name 1)" 0 1 2 3 4
 
 	test "$status" -eq "1"
-	output_regex_match ".*error reading GPIO values"
+	output_regex_match ".*unable to retrieve GPIO lines from chip"
 }
 
 @test "gpioget: same line twice" {
@@ -384,7 +384,7 @@ teardown() {
 	run_tool gpioget "$(gpio_mockup_chip_name 1)" 0 0
 
 	test "$status" -eq "1"
-	output_regex_match ".*error reading GPIO values.*"
+	output_regex_match ".*unable to request lines.*"
 }
 
 @test "gpioget: invalid bias" {
@@ -583,7 +583,7 @@ teardown() {
 	run_tool gpioset "$(gpio_mockup_chip_name 1)" 0=1 1=1 2=1 3=1 4=1 5=1
 
 	test "$status" -eq "1"
-	output_regex_match ".*error setting the GPIO line values"
+	output_regex_match ".*unable to retrieve GPIO lines from chip"
 }
 
 @test "gpioset: use --sec without --mode=time" {
@@ -664,7 +664,7 @@ teardown() {
 	run_tool gpioset "$(gpio_mockup_chip_name 1)" 0=1 0=1
 
 	test "$status" -eq "1"
-	output_regex_match ".*error setting the GPIO line values.*"
+	output_regex_match ".*unable to request lines.*"
 }
 
 #
@@ -884,7 +884,7 @@ teardown() {
 	run_tool gpiomon "$(gpio_mockup_chip_name 1)" 0 0
 
 	test "$status" -eq "1"
-	output_regex_match ".*error waiting for events.*"
+	output_regex_match ".*unable to request GPIO lines for events"
 }
 
 @test "gpiomon: no arguments" {
@@ -909,7 +909,7 @@ teardown() {
 	run_tool gpiomon "$(gpio_mockup_chip_name 0)" 5
 
 	test "$status" -eq "1"
-	output_regex_match ".*error waiting for events"
+	output_regex_match ".*unable to retrieve GPIO lines from chip"
 }
 
 @test "gpiomon: invalid bias" {
diff --git a/tools/gpiofind.c b/tools/gpiofind.c
index 931ac40..2138ebf 100644
--- a/tools/gpiofind.c
+++ b/tools/gpiofind.c
@@ -5,6 +5,7 @@
  * Copyright (C) 2017-2018 Bartosz Golaszewski <bartekgola@xxxxxxxxx>
  */
 
+#include <errno.h>
 #include <getopt.h>
 #include <gpiod.h>
 #include <stdio.h>
@@ -33,9 +34,9 @@ static void print_help(void)
 
 int main(int argc, char **argv)
 {
-	unsigned int offset;
-	int optc, opti, rv;
-	char chip[32];
+	int optc, opti, ret = EXIT_SUCCESS;
+	struct gpiod_chip *chip;
+	struct gpiod_line *line;
 
 	for (;;) {
 		optc = getopt_long(argc, argv, shortopts, longopts, &opti);
@@ -62,13 +63,19 @@ int main(int argc, char **argv)
 	if (argc != 1)
 		die("exactly one GPIO line name must be specified");
 
-	rv = gpiod_ctxless_find_line(argv[0], chip, sizeof(chip), &offset);
-	if (rv < 0)
+	line = gpiod_line_find(argv[0]);
+	if (!line) {
+		if (errno == ENOENT)
+			return EXIT_FAILURE;
+
 		die_perror("error performing the line lookup");
-	else if (rv == 0)
-		return EXIT_FAILURE;
+	}
+
+	chip = gpiod_line_get_chip(line);
+
+	printf("%s %u\n", gpiod_chip_name(chip), gpiod_line_offset(line));
 
-	printf("%s %u\n", chip, offset);
+	gpiod_chip_close(chip);
 
-	return EXIT_SUCCESS;
+	return ret;
 }
diff --git a/tools/gpioget.c b/tools/gpioget.c
index 815507d..11a9c9f 100644
--- a/tools/gpioget.c
+++ b/tools/gpioget.c
@@ -42,10 +42,11 @@ static void print_help(void)
 
 int main(int argc, char **argv)
 {
+	struct gpiod_line_request_config config;
+	int *values, optc, opti, rv, flags = 0;
 	unsigned int *offsets, i, num_lines;
-	int *values, optc, opti, rv;
-	bool active_low = false;
-	int flags = 0;
+	struct gpiod_line_bulk *lines;
+	struct gpiod_chip *chip;
 	char *device, *end;
 
 	for (;;) {
@@ -61,10 +62,10 @@ int main(int argc, char **argv)
 			print_version();
 			return EXIT_SUCCESS;
 		case 'l':
-			active_low = true;
+			flags |= GPIOD_LINE_REQUEST_FLAG_ACTIVE_LOW;
 			break;
 		case 'B':
-			flags = bias_flags(optarg);
+			flags |= bias_flags(optarg);
 			break;
 		case '?':
 			die("try %s --help", get_progname());
@@ -96,9 +97,25 @@ int main(int argc, char **argv)
 			die("invalid GPIO offset: %s", argv[i + 1]);
 	}
 
-	rv = gpiod_ctxless_get_value_multiple_ext(device, offsets, values,
-						  num_lines, active_low,
-						  "gpioget", flags);
+	chip = gpiod_chip_open_lookup(device);
+	if (!chip)
+		die_perror("unable to open %s", device);
+
+	lines = gpiod_chip_get_lines(chip, offsets, num_lines);
+	if (!lines)
+		die_perror("unable to retrieve GPIO lines from chip");
+
+	memset(&config, 0, sizeof(config));
+
+	config.consumer = "gpioget";
+	config.request_type = GPIOD_LINE_REQUEST_DIRECTION_INPUT;
+	config.flags = flags;
+
+	rv = gpiod_line_request_bulk(lines, &config, NULL);
+	if (rv)
+		die_perror("unable to request lines");
+
+	rv = gpiod_line_get_value_bulk(lines, values);
 	if (rv < 0)
 		die_perror("error reading GPIO values");
 
@@ -109,6 +126,9 @@ int main(int argc, char **argv)
 	}
 	printf("\n");
 
+	gpiod_line_release_bulk(lines);
+	gpiod_chip_close(chip);
+	gpiod_line_bulk_free(lines);
 	free(values);
 	free(offsets);
 
diff --git a/tools/gpiomon.c b/tools/gpiomon.c
index 213efaa..09d1ffd 100644
--- a/tools/gpiomon.c
+++ b/tools/gpiomon.c
@@ -10,6 +10,7 @@
 #include <gpiod.h>
 #include <limits.h>
 #include <poll.h>
+#include <signal.h>
 #include <stdio.h>
 #include <string.h>
 #include <unistd.h>
@@ -63,13 +64,8 @@ static void print_help(void)
 
 struct mon_ctx {
 	unsigned int offset;
-	unsigned int events_wanted;
-	unsigned int events_done;
-
 	bool silent;
 	char *fmt;
-
-	int sigfd;
 };
 
 static void event_print_custom(unsigned int offset,
@@ -96,7 +92,7 @@ static void event_print_custom(unsigned int offset,
 			printf("%u", offset);
 			break;
 		case 'e':
-			if (event_type == GPIOD_CTXLESS_EVENT_CB_RISING_EDGE)
+			if (event_type == GPIOD_LINE_EVENT_RISING_EDGE)
 				fputc('1', stdout);
 			else
 				fputc('0', stdout);
@@ -132,7 +128,7 @@ static void event_print_human_readable(unsigned int offset,
 {
 	char *evname;
 
-	if (event_type == GPIOD_CTXLESS_EVENT_CB_RISING_EDGE)
+	if (event_type == GPIOD_LINE_EVENT_RISING_EDGE)
 		evname = " RISING EDGE";
 	else
 		evname = "FALLING EDGE";
@@ -141,52 +137,8 @@ static void event_print_human_readable(unsigned int offset,
 	       evname, offset, ts->tv_sec, ts->tv_nsec);
 }
 
-static int poll_callback(unsigned int num_lines,
-			 struct gpiod_ctxless_event_poll_fd *fds,
-			 const struct timespec *timeout, void *data)
-{
-	struct pollfd pfds[GPIOD_LINE_BULK_MAX_LINES + 1];
-	struct mon_ctx *ctx = data;
-	int cnt, ts, rv;
-	unsigned int i;
-
-	for (i = 0; i < num_lines; i++) {
-		pfds[i].fd = fds[i].fd;
-		pfds[i].events = POLLIN | POLLPRI;
-	}
-
-	pfds[i].fd = ctx->sigfd;
-	pfds[i].events = POLLIN | POLLPRI;
-
-	ts = timeout->tv_sec * 1000 + timeout->tv_nsec / 1000000;
-
-	cnt = poll(pfds, num_lines + 1, ts);
-	if (cnt < 0)
-		return GPIOD_CTXLESS_EVENT_POLL_RET_ERR;
-	else if (cnt == 0)
-		return GPIOD_CTXLESS_EVENT_POLL_RET_TIMEOUT;
-
-	rv = cnt;
-	for (i = 0; i < num_lines; i++) {
-		if (pfds[i].revents) {
-			fds[i].event = true;
-			if (!--cnt)
-				return rv;
-		}
-	}
-
-	/*
-	 * If we're here, then there's a signal pending. No need to read it,
-	 * we know we should quit now.
-	 */
-	close(ctx->sigfd);
-
-	return GPIOD_CTXLESS_EVENT_POLL_RET_STOP;
-}
-
-static void handle_event(struct mon_ctx *ctx, int event_type,
-			 unsigned int line_offset,
-			 const struct timespec *timestamp)
+static void handle_event(unsigned int line_offset, unsigned int event_type,
+			 struct timespec *timestamp, struct mon_ctx *ctx)
 {
 	if (!ctx->silent) {
 		if (ctx->fmt)
@@ -196,43 +148,35 @@ static void handle_event(struct mon_ctx *ctx, int event_type,
 			event_print_human_readable(line_offset,
 						   timestamp, event_type);
 	}
-
-	ctx->events_done++;
 }
 
-static int event_callback(int event_type, unsigned int line_offset,
-			  const struct timespec *timestamp, void *data)
+static void handle_signal(int signum GPIOD_UNUSED)
 {
-	struct mon_ctx *ctx = data;
-
-	switch (event_type) {
-	case GPIOD_CTXLESS_EVENT_CB_RISING_EDGE:
-	case GPIOD_CTXLESS_EVENT_CB_FALLING_EDGE:
-		handle_event(ctx, event_type, line_offset, timestamp);
-		break;
-	default:
-		/*
-		 * REVISIT: This happening would indicate a problem in the
-		 * library.
-		 */
-		return GPIOD_CTXLESS_EVENT_CB_RET_OK;
-	}
-
-	if (ctx->events_wanted && ctx->events_done >= ctx->events_wanted)
-		return GPIOD_CTXLESS_EVENT_CB_RET_STOP;
-
-	return GPIOD_CTXLESS_EVENT_CB_RET_OK;
+	exit(EXIT_SUCCESS);
 }
 
 int main(int argc, char **argv)
 {
-	unsigned int offsets[GPIOD_LINE_BULK_MAX_LINES], num_lines = 0, offset;
-	bool active_low = false, watch_rising = false, watch_falling = false;
+	unsigned int offsets[GPIOD_LINE_BULK_MAX_LINES], num_lines = 0, offset,
+		     events_wanted = 0, events_done = 0, x;
+	bool watch_rising = false, watch_falling = false;
 	int flags = 0;
 	struct timespec timeout = { 10, 0 };
-	int optc, opti, rv, i, event_type;
+	int optc, opti, rv, i, y, event_type;
 	struct mon_ctx ctx;
+	struct gpiod_chip *chip;
+	struct gpiod_line_bulk *lines, *evlines;
 	char *end;
+	struct gpiod_line_request_config config;
+	struct gpiod_line *line;
+	struct gpiod_line_event events[16];
+
+	/*
+	 * FIXME: use signalfd once the API has been converted to using a single file
+	 * descriptor as provided by uAPI v2.
+	 */
+	signal(SIGINT, handle_signal);
+	signal(SIGTERM, handle_signal);
 
 	memset(&ctx, 0, sizeof(ctx));
 
@@ -249,13 +193,13 @@ int main(int argc, char **argv)
 			print_version();
 			return EXIT_SUCCESS;
 		case 'l':
-			active_low = true;
+			flags |= GPIOD_LINE_REQUEST_FLAG_ACTIVE_LOW;
 			break;
 		case 'B':
-			flags = bias_flags(optarg);
+			flags |= bias_flags(optarg);
 			break;
 		case 'n':
-			ctx.events_wanted = strtoul(optarg, &end, 10);
+			events_wanted = strtoul(optarg, &end, 10);
 			if (*end != '\0')
 				die("invalid number: %s", optarg);
 			break;
@@ -285,11 +229,11 @@ int main(int argc, char **argv)
 	argv += optind;
 
 	if (watch_rising && !watch_falling)
-		event_type = GPIOD_CTXLESS_EVENT_RISING_EDGE;
+		event_type = GPIOD_LINE_REQUEST_EVENT_RISING_EDGE;
 	else if (watch_falling && !watch_rising)
-		event_type = GPIOD_CTXLESS_EVENT_FALLING_EDGE;
+		event_type = GPIOD_LINE_REQUEST_EVENT_FALLING_EDGE;
 	else
-		event_type = GPIOD_CTXLESS_EVENT_BOTH_EDGES;
+		event_type = GPIOD_LINE_REQUEST_EVENT_BOTH_EDGES;
 
 	if (argc < 1)
 		die("gpiochip must be specified");
@@ -306,15 +250,64 @@ int main(int argc, char **argv)
 		num_lines++;
 	}
 
-	ctx.sigfd = make_signalfd();
+	chip = gpiod_chip_open_lookup(argv[0]);
+	if (!chip)
+		die_perror("unable to open %s", argv[0]);
+
+	lines = gpiod_chip_get_lines(chip, offsets, num_lines);
+	if (!lines)
+		die_perror("unable to retrieve GPIO lines from chip");
 
-	rv = gpiod_ctxless_event_monitor_multiple_ext(
-				argv[0], event_type, offsets,
-				num_lines, active_low, "gpiomon",
-				&timeout, poll_callback,
-				event_callback, &ctx, flags);
+	memset(&config, 0, sizeof(config));
+
+	config.consumer = "gpiomon";
+	config.request_type = event_type;
+	config.flags = flags;
+
+	rv = gpiod_line_request_bulk(lines, &config, NULL);
 	if (rv)
-		die_perror("error waiting for events");
+		die_perror("unable to request GPIO lines for events");
+
+	evlines = gpiod_line_bulk_new(num_lines);
+	if (!evlines)
+		die("out of memory");
+
+	for (;;) {
+		gpiod_line_bulk_clear(evlines);
+		rv = gpiod_line_event_wait_bulk(lines, &timeout, evlines);
+		if (rv < 0)
+			die_perror("error waiting for events");
+		if (rv == 0)
+			continue;
+
+		num_lines = gpiod_line_bulk_num_lines(evlines);
+
+		for (x = 0; x < num_lines; x++) {
+			line = gpiod_line_bulk_get_line(evlines, x);
+
+			rv = gpiod_line_event_read_multiple(line, events,
+							    ARRAY_SIZE(events));
+			if (rv < 0)
+				die_perror("error reading line events");
+
+			for (y = 0; y < rv; y++) {
+				handle_event(gpiod_line_offset(line),
+					     events[y].event_type,
+					     &events[y].ts, &ctx);
+				events_done++;
+
+				if (events_wanted &&
+				    events_done >= events_wanted)
+					goto done;
+			}
+		}
+	}
+
+done:
+	gpiod_line_release_bulk(lines);
+	gpiod_line_bulk_free(lines);
+	gpiod_line_bulk_free(evlines);
+	gpiod_chip_close(chip);
 
 	return EXIT_SUCCESS;
 }
diff --git a/tools/gpioset.c b/tools/gpioset.c
index fb6d51e..82dfa71 100644
--- a/tools/gpioset.c
+++ b/tools/gpioset.c
@@ -142,7 +142,7 @@ enum {
 struct mode_mapping {
 	int id;
 	const char *name;
-	gpiod_ctxless_set_value_cb callback;
+	void (*callback)(void *);
 };
 
 static const struct mode_mapping modes[] = {
@@ -182,9 +182,9 @@ static const struct mode_mapping *parse_mode(const char *mode)
 static int drive_flags(const char *option)
 {
 	if (strcmp(option, "open-drain") == 0)
-		return GPIOD_CTXLESS_FLAG_OPEN_DRAIN;
+		return GPIOD_LINE_REQUEST_FLAG_OPEN_DRAIN;
 	if (strcmp(option, "open-source") == 0)
-		return GPIOD_CTXLESS_FLAG_OPEN_SOURCE;
+		return GPIOD_LINE_REQUEST_FLAG_OPEN_SOURCE;
 	if (strcmp(option, "push-pull") != 0)
 		die("invalid drive: %s", option);
 	return 0;
@@ -193,10 +193,12 @@ static int drive_flags(const char *option)
 int main(int argc, char **argv)
 {
 	const struct mode_mapping *mode = &modes[MODE_EXIT];
-	unsigned int *offsets, num_lines, i;
+	struct gpiod_line_request_config config;
 	int *values, rv, optc, opti, flags = 0;
+	unsigned int *offsets, num_lines, i;
+	struct gpiod_line_bulk *lines;
 	struct callback_data cbdata;
-	bool active_low = false;
+	struct gpiod_chip *chip;
 	char *device, *end;
 
 	memset(&cbdata, 0, sizeof(cbdata));
@@ -214,7 +216,7 @@ int main(int argc, char **argv)
 			print_version();
 			return EXIT_SUCCESS;
 		case 'l':
-			active_low = true;
+			flags |= GPIOD_LINE_REQUEST_FLAG_ACTIVE_LOW;
 			break;
 		case 'B':
 			flags |= bias_flags(optarg);
@@ -286,13 +288,29 @@ int main(int argc, char **argv)
 			die("invalid offset: %s", argv[i + 1]);
 	}
 
-	rv = gpiod_ctxless_set_value_multiple_ext(
-				device, offsets, values,
-				num_lines, active_low, "gpioset",
-				mode->callback, &cbdata, flags);
-	if (rv < 0)
-		die_perror("error setting the GPIO line values");
+	chip = gpiod_chip_open_lookup(device);
+	if (!chip)
+		die_perror("unable to open %s", device);
+
+	lines = gpiod_chip_get_lines(chip, offsets, num_lines);
+	if (!lines)
+		die_perror("unable to retrieve GPIO lines from chip");
+
+	memset(&config, 0, sizeof(config));
+
+	config.consumer = "gpioset";
+	config.request_type = GPIOD_LINE_REQUEST_DIRECTION_OUTPUT;
+	config.flags = flags;
+
+	rv = gpiod_line_request_bulk(lines, &config, values);
+	if (rv)
+		die_perror("unable to request lines");
+
+	mode->callback(&cbdata);
 
+	gpiod_line_release_bulk(lines);
+	gpiod_chip_close(chip);
+	gpiod_line_bulk_free(lines);
 	free(offsets);
 	free(values);
 
diff --git a/tools/tools-common.c b/tools/tools-common.c
index 12bde20..af05102 100644
--- a/tools/tools-common.c
+++ b/tools/tools-common.c
@@ -63,11 +63,11 @@ void print_version(void)
 int bias_flags(const char *option)
 {
 	if (strcmp(option, "pull-down") == 0)
-		return GPIOD_CTXLESS_FLAG_BIAS_PULL_DOWN;
+		return GPIOD_LINE_REQUEST_FLAG_BIAS_PULL_DOWN;
 	if (strcmp(option, "pull-up") == 0)
-		return GPIOD_CTXLESS_FLAG_BIAS_PULL_UP;
+		return GPIOD_LINE_REQUEST_FLAG_BIAS_PULL_UP;
 	if (strcmp(option, "disable") == 0)
-		return GPIOD_CTXLESS_FLAG_BIAS_DISABLE;
+		return GPIOD_LINE_REQUEST_FLAG_BIAS_DISABLE;
 	if (strcmp(option, "as-is") != 0)
 		die("invalid bias: %s", option);
 	return 0;
-- 
2.29.1





[Index of Archives]     [Linux SPI]     [Linux Kernel]     [Linux ARM (vger)]     [Linux ARM MSM]     [Linux Omap]     [Linux Arm]     [Linux Tegra]     [Fedora ARM]     [Linux for Samsung SOC]     [eCos]     [Linux Fastboot]     [Gcc Help]     [Git]     [DCCP]     [IETF Announce]     [Security]     [Linux MIPS]     [Yosemite Campsites]

  Powered by Linux