* [libgpiod][PATCH v2] core: Basic port to uAPI v2
@ 2020-10-14 11:30 Kent Gibson
2020-10-14 13:15 ` Bartosz Golaszewski
2020-10-14 17:27 ` Andy Shevchenko
0 siblings, 2 replies; 3+ messages in thread
From: Kent Gibson @ 2020-10-14 11:30 UTC (permalink / raw)
To: linux-gpio, bgolaszewski; +Cc: Kent Gibson
Port existing implementation from GPIO uAPI v1 to v2.
The libgpiod external interface remains unchanged, only the internal
implementation switches from uAPI v1 to v2.
This is a minimal port - uAPI v2 features are not used, only the
uAPI v1 calls are switched to the v2 equivalent.
Signed-off-by: Kent Gibson <warthog618@gmail.com>
---
Changes for v2:
- reverted to using a line request for each line in an event request to
retain complete compatiblity with the existing libgpiod API.
All tests now pass, including CXX and Python, and also tested on a kernel
with uAPI v1 removed to double check it is only using uAPI v2.
include/gpiod.h | 2 +
lib/core.c | 287 ++++++++++++++++++++++++++++++++----------------
2 files changed, 193 insertions(+), 96 deletions(-)
diff --git a/include/gpiod.h b/include/gpiod.h
index 3477f9d..a6e34ae 100644
--- a/include/gpiod.h
+++ b/include/gpiod.h
@@ -1485,6 +1485,8 @@ struct gpiod_line_event {
/**< Best estimate of time of event occurrence. */
int event_type;
/**< Type of the event that occurred. */
+ int offset;
+ /**< Offset of line on which the event occurred. */
};
/**
diff --git a/lib/core.c b/lib/core.c
index b964272..1abe3a4 100644
--- a/lib/core.c
+++ b/lib/core.c
@@ -403,26 +403,49 @@ bool gpiod_line_needs_update(struct gpiod_line *line GPIOD_UNUSED)
return false;
}
+static int line_info_v2_to_info_flags(struct gpio_v2_line_info *info)
+{
+ int iflags = 0;
+
+ if (info->flags & GPIO_V2_LINE_FLAG_USED)
+ iflags |= GPIOLINE_FLAG_KERNEL;
+
+ if (info->flags & GPIO_V2_LINE_FLAG_OPEN_DRAIN)
+ iflags |= GPIOLINE_FLAG_OPEN_DRAIN;
+ if (info->flags & GPIO_V2_LINE_FLAG_OPEN_SOURCE)
+ iflags |= GPIOLINE_FLAG_OPEN_SOURCE;
+
+ if (info->flags & GPIO_V2_LINE_FLAG_BIAS_DISABLED)
+ iflags |= GPIOLINE_FLAG_BIAS_DISABLE;
+ if (info->flags & GPIO_V2_LINE_FLAG_BIAS_PULL_UP)
+ iflags |= GPIOLINE_FLAG_BIAS_PULL_UP;
+ if (info->flags & GPIO_V2_LINE_FLAG_BIAS_PULL_DOWN)
+ iflags |= GPIOLINE_FLAG_BIAS_PULL_DOWN;
+
+ return iflags;
+}
+
int gpiod_line_update(struct gpiod_line *line)
{
- struct gpioline_info info;
+ struct gpio_v2_line_info info;
int rv;
memset(&info, 0, sizeof(info));
- info.line_offset = line->offset;
+ info.offset = line->offset;
- rv = ioctl(line->chip->fd, GPIO_GET_LINEINFO_IOCTL, &info);
+ rv = ioctl(line->chip->fd, GPIO_V2_GET_LINEINFO_IOCTL, &info);
if (rv < 0)
return -1;
- line->direction = info.flags & GPIOLINE_FLAG_IS_OUT
+ line->direction = info.flags & GPIO_V2_LINE_FLAG_OUTPUT
? GPIOD_LINE_DIRECTION_OUTPUT
: GPIOD_LINE_DIRECTION_INPUT;
- line->active_state = info.flags & GPIOLINE_FLAG_ACTIVE_LOW
+
+ line->active_state = info.flags & GPIO_V2_LINE_FLAG_ACTIVE_LOW
? GPIOD_LINE_ACTIVE_STATE_LOW
: GPIOD_LINE_ACTIVE_STATE_HIGH;
- line->info_flags = info.flags;
+ line->info_flags = line_info_v2_to_info_flags(&info);
strncpy(line->name, info.name, sizeof(line->name));
strncpy(line->consumer, info.consumer, sizeof(line->consumer));
@@ -508,86 +531,149 @@ static bool line_request_direction_is_valid(int direction)
return false;
}
-static __u32 line_request_direction_to_gpio_handleflag(int direction)
+static void line_request_type_to_gpio_v2_line_config(int reqtype,
+ struct gpio_v2_line_config *config)
{
- if (direction == GPIOD_LINE_REQUEST_DIRECTION_INPUT)
- return GPIOHANDLE_REQUEST_INPUT;
- if (direction == GPIOD_LINE_REQUEST_DIRECTION_OUTPUT)
- return GPIOHANDLE_REQUEST_OUTPUT;
+ if (reqtype == GPIOD_LINE_REQUEST_DIRECTION_AS_IS)
+ return;
- return 0;
+ if (reqtype == GPIOD_LINE_REQUEST_DIRECTION_OUTPUT) {
+ config->flags |= GPIO_V2_LINE_FLAG_OUTPUT;
+ return;
+ }
+ config->flags |= GPIO_V2_LINE_FLAG_INPUT;
+
+ if (reqtype == GPIOD_LINE_REQUEST_EVENT_RISING_EDGE)
+ config->flags |= GPIO_V2_LINE_FLAG_EDGE_RISING;
+ else if (reqtype == GPIOD_LINE_REQUEST_EVENT_FALLING_EDGE)
+ config->flags |= GPIO_V2_LINE_FLAG_EDGE_FALLING;
+ else if (reqtype == GPIOD_LINE_REQUEST_EVENT_BOTH_EDGES)
+ config->flags |= (GPIO_V2_LINE_FLAG_EDGE_RISING |
+ GPIO_V2_LINE_FLAG_EDGE_FALLING);
}
-static __u32 line_request_flag_to_gpio_handleflag(int flags)
+static void line_request_flag_to_gpio_v2_line_config(int flags,
+ struct gpio_v2_line_config *config)
{
- int hflags = 0;
+ if (flags & GPIOD_LINE_REQUEST_FLAG_ACTIVE_LOW)
+ config->flags |= GPIO_V2_LINE_FLAG_ACTIVE_LOW;
if (flags & GPIOD_LINE_REQUEST_FLAG_OPEN_DRAIN)
- hflags |= GPIOHANDLE_REQUEST_OPEN_DRAIN;
- if (flags & GPIOD_LINE_REQUEST_FLAG_OPEN_SOURCE)
- hflags |= GPIOHANDLE_REQUEST_OPEN_SOURCE;
- if (flags & GPIOD_LINE_REQUEST_FLAG_ACTIVE_LOW)
- hflags |= GPIOHANDLE_REQUEST_ACTIVE_LOW;
+ config->flags |= GPIO_V2_LINE_FLAG_OPEN_DRAIN;
+ else if (flags & GPIOD_LINE_REQUEST_FLAG_OPEN_SOURCE)
+ config->flags |= GPIO_V2_LINE_FLAG_OPEN_SOURCE;
+
if (flags & GPIOD_LINE_REQUEST_FLAG_BIAS_DISABLE)
- hflags |= GPIOHANDLE_REQUEST_BIAS_DISABLE;
- if (flags & GPIOD_LINE_REQUEST_FLAG_BIAS_PULL_DOWN)
- hflags |= GPIOHANDLE_REQUEST_BIAS_PULL_DOWN;
- if (flags & GPIOD_LINE_REQUEST_FLAG_BIAS_PULL_UP)
- hflags |= GPIOHANDLE_REQUEST_BIAS_PULL_UP;
+ config->flags |= GPIO_V2_LINE_FLAG_BIAS_DISABLED;
+ else if (flags & GPIOD_LINE_REQUEST_FLAG_BIAS_PULL_DOWN)
+ config->flags |= GPIO_V2_LINE_FLAG_BIAS_PULL_DOWN;
+ else if (flags & GPIOD_LINE_REQUEST_FLAG_BIAS_PULL_UP)
+ config->flags |= GPIO_V2_LINE_FLAG_BIAS_PULL_UP;
+}
+
+static void line_request_config_to_gpio_v2_line_config(
+ const struct gpiod_line_request_config *reqcfg,
+ struct gpio_v2_line_config *lc)
+{
+ line_request_type_to_gpio_v2_line_config(reqcfg->request_type, lc);
+ line_request_flag_to_gpio_v2_line_config(reqcfg->flags, lc);
+}
+
+static bool line_request_config_validate(
+ const struct gpiod_line_request_config *config)
+{
+ int bias_flags = 0;
+
+ if ((config->request_type != GPIOD_LINE_REQUEST_DIRECTION_OUTPUT) &&
+ (config->flags & (GPIOD_LINE_REQUEST_FLAG_OPEN_DRAIN |
+ GPIOD_LINE_REQUEST_FLAG_OPEN_SOURCE)))
+ return false;
+
+
+ if ((config->flags & GPIOD_LINE_REQUEST_FLAG_OPEN_DRAIN) &&
+ (config->flags & GPIOD_LINE_REQUEST_FLAG_OPEN_SOURCE)) {
+ return false;
+ }
+
+ if (config->flags & GPIOD_LINE_REQUEST_FLAG_BIAS_DISABLE)
+ bias_flags++;
+ if (config->flags & GPIOD_LINE_REQUEST_FLAG_BIAS_PULL_UP)
+ bias_flags++;
+ if (config->flags & GPIOD_LINE_REQUEST_FLAG_BIAS_PULL_DOWN)
+ bias_flags++;
+ if (bias_flags > 1)
+ return false;
+
+ return true;
+}
- return hflags;
+static void lines_bitmap_set_bit(__u64 *bits, int nr)
+{
+ *bits |= _BITULL(nr);
+}
+
+static void lines_bitmap_clear_bit(__u64 *bits, int nr)
+{
+ *bits &= ~_BITULL(nr);
+}
+
+static int lines_bitmap_test_bit(__u64 bits, int nr)
+{
+ return !!(bits & _BITULL(nr));
+}
+
+static void lines_bitmap_assign_bit(__u64 *bits, int nr, bool value)
+{
+ if (value)
+ lines_bitmap_set_bit(bits, nr);
+ else
+ lines_bitmap_clear_bit(bits, nr);
}
static int line_request_values(struct gpiod_line_bulk *bulk,
const struct gpiod_line_request_config *config,
- const int *default_vals)
+ const int *vals)
{
struct gpiod_line *line;
struct line_fd_handle *line_fd;
- struct gpiohandle_request req;
+ struct gpio_v2_line_request req;
unsigned int i;
int rv, fd;
- if ((config->request_type != GPIOD_LINE_REQUEST_DIRECTION_OUTPUT) &&
- (config->flags & (GPIOD_LINE_REQUEST_FLAG_OPEN_DRAIN |
- GPIOD_LINE_REQUEST_FLAG_OPEN_SOURCE))) {
- errno = EINVAL;
- return -1;
- }
-
- if ((config->flags & GPIOD_LINE_REQUEST_FLAG_OPEN_DRAIN) &&
- (config->flags & GPIOD_LINE_REQUEST_FLAG_OPEN_SOURCE)) {
+ if (!line_request_config_validate(config)) {
errno = EINVAL;
return -1;
}
memset(&req, 0, sizeof(req));
- req.lines = gpiod_line_bulk_num_lines(bulk);
- req.flags = line_request_flag_to_gpio_handleflag(config->flags);
-
- if (config->request_type == GPIOD_LINE_REQUEST_DIRECTION_INPUT)
- req.flags |= GPIOHANDLE_REQUEST_INPUT;
- else if (config->request_type == GPIOD_LINE_REQUEST_DIRECTION_OUTPUT)
- req.flags |= GPIOHANDLE_REQUEST_OUTPUT;
+ req.num_lines = gpiod_line_bulk_num_lines(bulk);
+ line_request_config_to_gpio_v2_line_config(config, &req.config);
-
- gpiod_line_bulk_foreach_line_off(bulk, line, i) {
- req.lineoffsets[i] = gpiod_line_offset(line);
- if (config->request_type ==
- GPIOD_LINE_REQUEST_DIRECTION_OUTPUT &&
- default_vals)
- req.default_values[i] = !!default_vals[i];
+ gpiod_line_bulk_foreach_line_off(bulk, line, i)
+ req.offsets[i] = gpiod_line_offset(line);
+
+ if (config->request_type == GPIOD_LINE_REQUEST_DIRECTION_OUTPUT &&
+ vals) {
+ req.config.num_attrs = 1;
+ req.config.attrs[0].attr.id = GPIO_V2_LINE_ATTR_ID_OUTPUT_VALUES;
+ gpiod_line_bulk_foreach_line_off(bulk, line, i) {
+ lines_bitmap_assign_bit(
+ &req.config.attrs[0].mask, i, 1);
+ lines_bitmap_assign_bit(
+ &req.config.attrs[0].attr.values,
+ i, vals[i]);
+ }
}
if (config->consumer)
- strncpy(req.consumer_label, config->consumer,
- sizeof(req.consumer_label) - 1);
+ strncpy(req.consumer, config->consumer,
+ sizeof(req.consumer) - 1);
line = gpiod_line_bulk_get_line(bulk, 0);
fd = line->chip->fd;
- rv = ioctl(fd, GPIO_GET_LINEHANDLE_IOCTL, &req);
+ rv = ioctl(fd, GPIO_V2_GET_LINE_IOCTL, &req);
if (rv < 0)
return -1;
@@ -598,9 +684,9 @@ static int line_request_values(struct gpiod_line_bulk *bulk,
gpiod_line_bulk_foreach_line_off(bulk, line, i) {
line->state = LINE_REQUESTED_VALUES;
line->req_flags = config->flags;
- if (config->request_type ==
- GPIOD_LINE_REQUEST_DIRECTION_OUTPUT)
- line->output_value = req.default_values[i];
+ if (config->request_type == GPIOD_LINE_REQUEST_DIRECTION_OUTPUT)
+ line->output_value = lines_bitmap_test_bit(
+ req.config.attrs[0].attr.values, i);
line_set_fd(line, line_fd);
rv = gpiod_line_update(line);
@@ -617,27 +703,20 @@ static int line_request_event_single(struct gpiod_line *line,
const struct gpiod_line_request_config *config)
{
struct line_fd_handle *line_fd;
- struct gpioevent_request req;
+ struct gpio_v2_line_request req;
int rv;
memset(&req, 0, sizeof(req));
if (config->consumer)
- strncpy(req.consumer_label, config->consumer,
- sizeof(req.consumer_label) - 1);
+ strncpy(req.consumer, config->consumer,
+ sizeof(req.consumer) - 1);
- req.lineoffset = gpiod_line_offset(line);
- req.handleflags = line_request_flag_to_gpio_handleflag(config->flags);
- req.handleflags |= GPIOHANDLE_REQUEST_INPUT;
+ req.offsets[0] = gpiod_line_offset(line);
+ req.num_lines = 1;
+ line_request_config_to_gpio_v2_line_config(config, &req.config);
- if (config->request_type == GPIOD_LINE_REQUEST_EVENT_RISING_EDGE)
- req.eventflags |= GPIOEVENT_REQUEST_RISING_EDGE;
- else if (config->request_type == GPIOD_LINE_REQUEST_EVENT_FALLING_EDGE)
- req.eventflags |= GPIOEVENT_REQUEST_FALLING_EDGE;
- else if (config->request_type == GPIOD_LINE_REQUEST_EVENT_BOTH_EDGES)
- req.eventflags |= GPIOEVENT_REQUEST_BOTH_EDGES;
-
- rv = ioctl(line->chip->fd, GPIO_GET_LINEEVENT_IOCTL, &req);
+ rv = ioctl(line->chip->fd, GPIO_V2_GET_LINE_IOCTL, &req);
if (rv < 0)
return -1;
@@ -708,13 +787,13 @@ static bool line_request_is_events(int request)
int gpiod_line_request_bulk(struct gpiod_line_bulk *bulk,
const struct gpiod_line_request_config *config,
- const int *default_vals)
+ const int *vals)
{
if (!line_bulk_same_chip(bulk) || !line_bulk_all_free(bulk))
return -1;
if (line_request_is_direction(config->request_type))
- return line_request_values(bulk, config, default_vals);
+ return line_request_values(bulk, config, vals);
else if (line_request_is_events(config->request_type))
return line_request_events(bulk, config);
@@ -772,7 +851,7 @@ int gpiod_line_get_value(struct gpiod_line *line)
int gpiod_line_get_value_bulk(struct gpiod_line_bulk *bulk, int *values)
{
- struct gpiohandle_data data;
+ struct gpio_v2_line_values lv;
struct gpiod_line *line;
unsigned int i;
int rv, fd;
@@ -782,27 +861,31 @@ int gpiod_line_get_value_bulk(struct gpiod_line_bulk *bulk, int *values)
line = gpiod_line_bulk_get_line(bulk, 0);
+ memset(&lv, 0, sizeof(lv));
+
if (line->state == LINE_REQUESTED_VALUES) {
- memset(&data, 0, sizeof(data));
+ for (i = 0; i < gpiod_line_bulk_num_lines(bulk); i++)
+ lines_bitmap_set_bit(&lv.mask, i);
fd = line_get_fd(line);
- rv = ioctl(fd, GPIOHANDLE_GET_LINE_VALUES_IOCTL, &data);
+ rv = ioctl(fd, GPIO_V2_LINE_GET_VALUES_IOCTL, &lv);
if (rv < 0)
return -1;
for (i = 0; i < gpiod_line_bulk_num_lines(bulk); i++)
- values[i] = data.values[i];
+ values[i] = lines_bitmap_test_bit(lv.bits, i);
} else if (line->state == LINE_REQUESTED_EVENTS) {
+ lines_bitmap_set_bit(&lv.mask, 0);
for (i = 0; i < gpiod_line_bulk_num_lines(bulk); i++) {
line = gpiod_line_bulk_get_line(bulk, i);
fd = line_get_fd(line);
- rv = ioctl(fd, GPIOHANDLE_GET_LINE_VALUES_IOCTL, &data);
+ rv = ioctl(fd, GPIO_V2_LINE_GET_VALUES_IOCTL, &lv);
if (rv < 0)
return -1;
- values[i] = data.values[0];
+ values[i] = lines_bitmap_test_bit(lv.bits, 0);
}
} else {
errno = EINVAL;
@@ -823,7 +906,7 @@ int gpiod_line_set_value(struct gpiod_line *line, int value)
int gpiod_line_set_value_bulk(struct gpiod_line_bulk *bulk, const int *values)
{
- struct gpiohandle_data data;
+ struct gpio_v2_line_values lv;
struct gpiod_line *line;
unsigned int i;
int rv, fd;
@@ -831,22 +914,22 @@ int gpiod_line_set_value_bulk(struct gpiod_line_bulk *bulk, const int *values)
if (!line_bulk_same_chip(bulk) || !line_bulk_all_requested(bulk))
return -1;
- memset(&data, 0, sizeof(data));
+ memset(&lv, 0, sizeof(lv));
- if (values) {
- for (i = 0; i < gpiod_line_bulk_num_lines(bulk); i++)
- data.values[i] = (uint8_t)!!values[i];
+ for (i = 0; i < gpiod_line_bulk_num_lines(bulk); i++) {
+ lines_bitmap_set_bit(&lv.mask, i);
+ lines_bitmap_assign_bit(&lv.bits, i, values && values[i]);
}
line = gpiod_line_bulk_get_line(bulk, 0);
fd = line_get_fd(line);
- rv = ioctl(fd, GPIOHANDLE_SET_LINE_VALUES_IOCTL, &data);
+ rv = ioctl(fd, GPIO_V2_LINE_SET_VALUES_IOCTL, &lv);
if (rv < 0)
return -1;
gpiod_line_bulk_foreach_line_off(bulk, line, i)
- line->output_value = data.values[i];
+ line->output_value = lines_bitmap_test_bit(lv.bits, i);
return 0;
}
@@ -866,7 +949,7 @@ int gpiod_line_set_config_bulk(struct gpiod_line_bulk *bulk,
int direction, int flags,
const int *values)
{
- struct gpiohandle_config hcfg;
+ struct gpio_v2_line_config hcfg;
struct gpiod_line *line;
unsigned int i;
int rv, fd;
@@ -880,24 +963,30 @@ int gpiod_line_set_config_bulk(struct gpiod_line_bulk *bulk,
memset(&hcfg, 0, sizeof(hcfg));
- hcfg.flags = line_request_flag_to_gpio_handleflag(flags);
- hcfg.flags |= line_request_direction_to_gpio_handleflag(direction);
+ line_request_flag_to_gpio_v2_line_config(flags, &hcfg);
+ line_request_type_to_gpio_v2_line_config(direction, &hcfg);
if (direction == GPIOD_LINE_REQUEST_DIRECTION_OUTPUT && values) {
- for (i = 0; i < gpiod_line_bulk_num_lines(bulk); i++)
- hcfg.default_values[i] = (uint8_t)!!values[i];
+ hcfg.num_attrs = 1;
+ hcfg.attrs[0].attr.id = GPIO_V2_LINE_ATTR_ID_OUTPUT_VALUES;
+ for (i = 0; i < gpiod_line_bulk_num_lines(bulk); i++) {
+ lines_bitmap_assign_bit(&hcfg.attrs[0].mask, i, 1);
+ lines_bitmap_assign_bit(
+ &hcfg.attrs[0].attr.values, i, values[i]);
+ }
}
line = gpiod_line_bulk_get_line(bulk, 0);
fd = line_get_fd(line);
- rv = ioctl(fd, GPIOHANDLE_SET_CONFIG_IOCTL, &hcfg);
+ rv = ioctl(fd, GPIO_V2_LINE_SET_CONFIG_IOCTL, &hcfg);
if (rv < 0)
return -1;
gpiod_line_bulk_foreach_line_off(bulk, line, i) {
line->req_flags = flags;
if (direction == GPIOD_LINE_REQUEST_DIRECTION_OUTPUT)
- line->output_value = hcfg.default_values[i];
+ line->output_value = lines_bitmap_test_bit(
+ hcfg.attrs[0].attr.values, i);
rv = gpiod_line_update(line);
if (rv < 0)
@@ -1082,8 +1171,13 @@ int gpiod_line_event_read_fd_multiple(int fd, struct gpiod_line_event *events,
/*
* 16 is the maximum number of events the kernel can store in the FIFO
* so we can allocate the buffer on the stack.
+ *
+ * NOTE: This is no longer strictly true for uAPI v2. While 16 is
+ * the default for single line, a request with multiple lines will
+ * have a larger buffer. So need to rethink the allocation here,
+ * or at least the comment above...
*/
- struct gpioevent_data evdata[16], *curr;
+ struct gpio_v2_line_event evdata[16], *curr;
struct gpiod_line_event *event;
unsigned int events_read, i;
ssize_t rd;
@@ -1109,11 +1203,12 @@ int gpiod_line_event_read_fd_multiple(int fd, struct gpiod_line_event *events,
curr = &evdata[i];
event = &events[i];
- event->event_type = curr->id == GPIOEVENT_EVENT_RISING_EDGE
+ event->offset = curr->offset;
+ event->event_type = curr->id == GPIO_V2_LINE_EVENT_RISING_EDGE
? GPIOD_LINE_EVENT_RISING_EDGE
: GPIOD_LINE_EVENT_FALLING_EDGE;
- event->ts.tv_sec = curr->timestamp / 1000000000ULL;
- event->ts.tv_nsec = curr->timestamp % 1000000000ULL;
+ event->ts.tv_sec = curr->timestamp_ns / 1000000000ULL;
+ event->ts.tv_nsec = curr->timestamp_ns % 1000000000ULL;
}
return i;
--
2.28.0
^ permalink raw reply related [flat|nested] 3+ messages in thread* Re: [libgpiod][PATCH v2] core: Basic port to uAPI v2
2020-10-14 11:30 [libgpiod][PATCH v2] core: Basic port to uAPI v2 Kent Gibson
@ 2020-10-14 13:15 ` Bartosz Golaszewski
2020-10-14 17:27 ` Andy Shevchenko
1 sibling, 0 replies; 3+ messages in thread
From: Bartosz Golaszewski @ 2020-10-14 13:15 UTC (permalink / raw)
To: Kent Gibson; +Cc: linux-gpio
On Wed, Oct 14, 2020 at 1:31 PM Kent Gibson <warthog618@gmail.com> wrote:
>
> Port existing implementation from GPIO uAPI v1 to v2.
> The libgpiod external interface remains unchanged, only the internal
> implementation switches from uAPI v1 to v2.
>
> This is a minimal port - uAPI v2 features are not used, only the
> uAPI v1 calls are switched to the v2 equivalent.
>
> Signed-off-by: Kent Gibson <warthog618@gmail.com>
> ---
>
Cool, thanks a lot! All tests pass with this - I'll force push it to
for-linux-v5.10 branch shortly.
Bartosz
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [libgpiod][PATCH v2] core: Basic port to uAPI v2
2020-10-14 11:30 [libgpiod][PATCH v2] core: Basic port to uAPI v2 Kent Gibson
2020-10-14 13:15 ` Bartosz Golaszewski
@ 2020-10-14 17:27 ` Andy Shevchenko
1 sibling, 0 replies; 3+ messages in thread
From: Andy Shevchenko @ 2020-10-14 17:27 UTC (permalink / raw)
To: Kent Gibson; +Cc: open list:GPIO SUBSYSTEM, Bartosz Golaszewski
On Wed, Oct 14, 2020 at 7:03 PM Kent Gibson <warthog618@gmail.com> wrote:
>
> Port existing implementation from GPIO uAPI v1 to v2.
> The libgpiod external interface remains unchanged, only the internal
> implementation switches from uAPI v1 to v2.
>
> This is a minimal port - uAPI v2 features are not used, only the
> uAPI v1 calls are switched to the v2 equivalent.
Thanks, this sounds good to me!
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
> Signed-off-by: Kent Gibson <warthog618@gmail.com>
> ---
>
> Changes for v2:
> - reverted to using a line request for each line in an event request to
> retain complete compatiblity with the existing libgpiod API.
>
> All tests now pass, including CXX and Python, and also tested on a kernel
> with uAPI v1 removed to double check it is only using uAPI v2.
>
> include/gpiod.h | 2 +
> lib/core.c | 287 ++++++++++++++++++++++++++++++++----------------
> 2 files changed, 193 insertions(+), 96 deletions(-)
>
> diff --git a/include/gpiod.h b/include/gpiod.h
> index 3477f9d..a6e34ae 100644
> --- a/include/gpiod.h
> +++ b/include/gpiod.h
> @@ -1485,6 +1485,8 @@ struct gpiod_line_event {
> /**< Best estimate of time of event occurrence. */
> int event_type;
> /**< Type of the event that occurred. */
> + int offset;
> + /**< Offset of line on which the event occurred. */
> };
>
> /**
> diff --git a/lib/core.c b/lib/core.c
> index b964272..1abe3a4 100644
> --- a/lib/core.c
> +++ b/lib/core.c
> @@ -403,26 +403,49 @@ bool gpiod_line_needs_update(struct gpiod_line *line GPIOD_UNUSED)
> return false;
> }
>
> +static int line_info_v2_to_info_flags(struct gpio_v2_line_info *info)
> +{
> + int iflags = 0;
> +
> + if (info->flags & GPIO_V2_LINE_FLAG_USED)
> + iflags |= GPIOLINE_FLAG_KERNEL;
> +
> + if (info->flags & GPIO_V2_LINE_FLAG_OPEN_DRAIN)
> + iflags |= GPIOLINE_FLAG_OPEN_DRAIN;
> + if (info->flags & GPIO_V2_LINE_FLAG_OPEN_SOURCE)
> + iflags |= GPIOLINE_FLAG_OPEN_SOURCE;
> +
> + if (info->flags & GPIO_V2_LINE_FLAG_BIAS_DISABLED)
> + iflags |= GPIOLINE_FLAG_BIAS_DISABLE;
> + if (info->flags & GPIO_V2_LINE_FLAG_BIAS_PULL_UP)
> + iflags |= GPIOLINE_FLAG_BIAS_PULL_UP;
> + if (info->flags & GPIO_V2_LINE_FLAG_BIAS_PULL_DOWN)
> + iflags |= GPIOLINE_FLAG_BIAS_PULL_DOWN;
> +
> + return iflags;
> +}
> +
> int gpiod_line_update(struct gpiod_line *line)
> {
> - struct gpioline_info info;
> + struct gpio_v2_line_info info;
> int rv;
>
> memset(&info, 0, sizeof(info));
> - info.line_offset = line->offset;
> + info.offset = line->offset;
>
> - rv = ioctl(line->chip->fd, GPIO_GET_LINEINFO_IOCTL, &info);
> + rv = ioctl(line->chip->fd, GPIO_V2_GET_LINEINFO_IOCTL, &info);
> if (rv < 0)
> return -1;
>
> - line->direction = info.flags & GPIOLINE_FLAG_IS_OUT
> + line->direction = info.flags & GPIO_V2_LINE_FLAG_OUTPUT
> ? GPIOD_LINE_DIRECTION_OUTPUT
> : GPIOD_LINE_DIRECTION_INPUT;
> - line->active_state = info.flags & GPIOLINE_FLAG_ACTIVE_LOW
> +
> + line->active_state = info.flags & GPIO_V2_LINE_FLAG_ACTIVE_LOW
> ? GPIOD_LINE_ACTIVE_STATE_LOW
> : GPIOD_LINE_ACTIVE_STATE_HIGH;
>
> - line->info_flags = info.flags;
> + line->info_flags = line_info_v2_to_info_flags(&info);
>
> strncpy(line->name, info.name, sizeof(line->name));
> strncpy(line->consumer, info.consumer, sizeof(line->consumer));
> @@ -508,86 +531,149 @@ static bool line_request_direction_is_valid(int direction)
> return false;
> }
>
> -static __u32 line_request_direction_to_gpio_handleflag(int direction)
> +static void line_request_type_to_gpio_v2_line_config(int reqtype,
> + struct gpio_v2_line_config *config)
> {
> - if (direction == GPIOD_LINE_REQUEST_DIRECTION_INPUT)
> - return GPIOHANDLE_REQUEST_INPUT;
> - if (direction == GPIOD_LINE_REQUEST_DIRECTION_OUTPUT)
> - return GPIOHANDLE_REQUEST_OUTPUT;
> + if (reqtype == GPIOD_LINE_REQUEST_DIRECTION_AS_IS)
> + return;
>
> - return 0;
> + if (reqtype == GPIOD_LINE_REQUEST_DIRECTION_OUTPUT) {
> + config->flags |= GPIO_V2_LINE_FLAG_OUTPUT;
> + return;
> + }
> + config->flags |= GPIO_V2_LINE_FLAG_INPUT;
> +
> + if (reqtype == GPIOD_LINE_REQUEST_EVENT_RISING_EDGE)
> + config->flags |= GPIO_V2_LINE_FLAG_EDGE_RISING;
> + else if (reqtype == GPIOD_LINE_REQUEST_EVENT_FALLING_EDGE)
> + config->flags |= GPIO_V2_LINE_FLAG_EDGE_FALLING;
> + else if (reqtype == GPIOD_LINE_REQUEST_EVENT_BOTH_EDGES)
> + config->flags |= (GPIO_V2_LINE_FLAG_EDGE_RISING |
> + GPIO_V2_LINE_FLAG_EDGE_FALLING);
> }
>
> -static __u32 line_request_flag_to_gpio_handleflag(int flags)
> +static void line_request_flag_to_gpio_v2_line_config(int flags,
> + struct gpio_v2_line_config *config)
> {
> - int hflags = 0;
> + if (flags & GPIOD_LINE_REQUEST_FLAG_ACTIVE_LOW)
> + config->flags |= GPIO_V2_LINE_FLAG_ACTIVE_LOW;
>
> if (flags & GPIOD_LINE_REQUEST_FLAG_OPEN_DRAIN)
> - hflags |= GPIOHANDLE_REQUEST_OPEN_DRAIN;
> - if (flags & GPIOD_LINE_REQUEST_FLAG_OPEN_SOURCE)
> - hflags |= GPIOHANDLE_REQUEST_OPEN_SOURCE;
> - if (flags & GPIOD_LINE_REQUEST_FLAG_ACTIVE_LOW)
> - hflags |= GPIOHANDLE_REQUEST_ACTIVE_LOW;
> + config->flags |= GPIO_V2_LINE_FLAG_OPEN_DRAIN;
> + else if (flags & GPIOD_LINE_REQUEST_FLAG_OPEN_SOURCE)
> + config->flags |= GPIO_V2_LINE_FLAG_OPEN_SOURCE;
> +
> if (flags & GPIOD_LINE_REQUEST_FLAG_BIAS_DISABLE)
> - hflags |= GPIOHANDLE_REQUEST_BIAS_DISABLE;
> - if (flags & GPIOD_LINE_REQUEST_FLAG_BIAS_PULL_DOWN)
> - hflags |= GPIOHANDLE_REQUEST_BIAS_PULL_DOWN;
> - if (flags & GPIOD_LINE_REQUEST_FLAG_BIAS_PULL_UP)
> - hflags |= GPIOHANDLE_REQUEST_BIAS_PULL_UP;
> + config->flags |= GPIO_V2_LINE_FLAG_BIAS_DISABLED;
> + else if (flags & GPIOD_LINE_REQUEST_FLAG_BIAS_PULL_DOWN)
> + config->flags |= GPIO_V2_LINE_FLAG_BIAS_PULL_DOWN;
> + else if (flags & GPIOD_LINE_REQUEST_FLAG_BIAS_PULL_UP)
> + config->flags |= GPIO_V2_LINE_FLAG_BIAS_PULL_UP;
> +}
> +
> +static void line_request_config_to_gpio_v2_line_config(
> + const struct gpiod_line_request_config *reqcfg,
> + struct gpio_v2_line_config *lc)
> +{
> + line_request_type_to_gpio_v2_line_config(reqcfg->request_type, lc);
> + line_request_flag_to_gpio_v2_line_config(reqcfg->flags, lc);
> +}
> +
> +static bool line_request_config_validate(
> + const struct gpiod_line_request_config *config)
> +{
> + int bias_flags = 0;
> +
> + if ((config->request_type != GPIOD_LINE_REQUEST_DIRECTION_OUTPUT) &&
> + (config->flags & (GPIOD_LINE_REQUEST_FLAG_OPEN_DRAIN |
> + GPIOD_LINE_REQUEST_FLAG_OPEN_SOURCE)))
> + return false;
> +
> +
> + if ((config->flags & GPIOD_LINE_REQUEST_FLAG_OPEN_DRAIN) &&
> + (config->flags & GPIOD_LINE_REQUEST_FLAG_OPEN_SOURCE)) {
> + return false;
> + }
> +
> + if (config->flags & GPIOD_LINE_REQUEST_FLAG_BIAS_DISABLE)
> + bias_flags++;
> + if (config->flags & GPIOD_LINE_REQUEST_FLAG_BIAS_PULL_UP)
> + bias_flags++;
> + if (config->flags & GPIOD_LINE_REQUEST_FLAG_BIAS_PULL_DOWN)
> + bias_flags++;
> + if (bias_flags > 1)
> + return false;
> +
> + return true;
> +}
>
> - return hflags;
> +static void lines_bitmap_set_bit(__u64 *bits, int nr)
> +{
> + *bits |= _BITULL(nr);
> +}
> +
> +static void lines_bitmap_clear_bit(__u64 *bits, int nr)
> +{
> + *bits &= ~_BITULL(nr);
> +}
> +
> +static int lines_bitmap_test_bit(__u64 bits, int nr)
> +{
> + return !!(bits & _BITULL(nr));
> +}
> +
> +static void lines_bitmap_assign_bit(__u64 *bits, int nr, bool value)
> +{
> + if (value)
> + lines_bitmap_set_bit(bits, nr);
> + else
> + lines_bitmap_clear_bit(bits, nr);
> }
>
> static int line_request_values(struct gpiod_line_bulk *bulk,
> const struct gpiod_line_request_config *config,
> - const int *default_vals)
> + const int *vals)
> {
> struct gpiod_line *line;
> struct line_fd_handle *line_fd;
> - struct gpiohandle_request req;
> + struct gpio_v2_line_request req;
> unsigned int i;
> int rv, fd;
>
> - if ((config->request_type != GPIOD_LINE_REQUEST_DIRECTION_OUTPUT) &&
> - (config->flags & (GPIOD_LINE_REQUEST_FLAG_OPEN_DRAIN |
> - GPIOD_LINE_REQUEST_FLAG_OPEN_SOURCE))) {
> - errno = EINVAL;
> - return -1;
> - }
> -
> - if ((config->flags & GPIOD_LINE_REQUEST_FLAG_OPEN_DRAIN) &&
> - (config->flags & GPIOD_LINE_REQUEST_FLAG_OPEN_SOURCE)) {
> + if (!line_request_config_validate(config)) {
> errno = EINVAL;
> return -1;
> }
>
> memset(&req, 0, sizeof(req));
>
> - req.lines = gpiod_line_bulk_num_lines(bulk);
> - req.flags = line_request_flag_to_gpio_handleflag(config->flags);
> -
> - if (config->request_type == GPIOD_LINE_REQUEST_DIRECTION_INPUT)
> - req.flags |= GPIOHANDLE_REQUEST_INPUT;
> - else if (config->request_type == GPIOD_LINE_REQUEST_DIRECTION_OUTPUT)
> - req.flags |= GPIOHANDLE_REQUEST_OUTPUT;
> + req.num_lines = gpiod_line_bulk_num_lines(bulk);
> + line_request_config_to_gpio_v2_line_config(config, &req.config);
>
> -
> - gpiod_line_bulk_foreach_line_off(bulk, line, i) {
> - req.lineoffsets[i] = gpiod_line_offset(line);
> - if (config->request_type ==
> - GPIOD_LINE_REQUEST_DIRECTION_OUTPUT &&
> - default_vals)
> - req.default_values[i] = !!default_vals[i];
> + gpiod_line_bulk_foreach_line_off(bulk, line, i)
> + req.offsets[i] = gpiod_line_offset(line);
> +
> + if (config->request_type == GPIOD_LINE_REQUEST_DIRECTION_OUTPUT &&
> + vals) {
> + req.config.num_attrs = 1;
> + req.config.attrs[0].attr.id = GPIO_V2_LINE_ATTR_ID_OUTPUT_VALUES;
> + gpiod_line_bulk_foreach_line_off(bulk, line, i) {
> + lines_bitmap_assign_bit(
> + &req.config.attrs[0].mask, i, 1);
> + lines_bitmap_assign_bit(
> + &req.config.attrs[0].attr.values,
> + i, vals[i]);
> + }
> }
>
> if (config->consumer)
> - strncpy(req.consumer_label, config->consumer,
> - sizeof(req.consumer_label) - 1);
> + strncpy(req.consumer, config->consumer,
> + sizeof(req.consumer) - 1);
>
> line = gpiod_line_bulk_get_line(bulk, 0);
> fd = line->chip->fd;
>
> - rv = ioctl(fd, GPIO_GET_LINEHANDLE_IOCTL, &req);
> + rv = ioctl(fd, GPIO_V2_GET_LINE_IOCTL, &req);
> if (rv < 0)
> return -1;
>
> @@ -598,9 +684,9 @@ static int line_request_values(struct gpiod_line_bulk *bulk,
> gpiod_line_bulk_foreach_line_off(bulk, line, i) {
> line->state = LINE_REQUESTED_VALUES;
> line->req_flags = config->flags;
> - if (config->request_type ==
> - GPIOD_LINE_REQUEST_DIRECTION_OUTPUT)
> - line->output_value = req.default_values[i];
> + if (config->request_type == GPIOD_LINE_REQUEST_DIRECTION_OUTPUT)
> + line->output_value = lines_bitmap_test_bit(
> + req.config.attrs[0].attr.values, i);
> line_set_fd(line, line_fd);
>
> rv = gpiod_line_update(line);
> @@ -617,27 +703,20 @@ static int line_request_event_single(struct gpiod_line *line,
> const struct gpiod_line_request_config *config)
> {
> struct line_fd_handle *line_fd;
> - struct gpioevent_request req;
> + struct gpio_v2_line_request req;
> int rv;
>
> memset(&req, 0, sizeof(req));
>
> if (config->consumer)
> - strncpy(req.consumer_label, config->consumer,
> - sizeof(req.consumer_label) - 1);
> + strncpy(req.consumer, config->consumer,
> + sizeof(req.consumer) - 1);
>
> - req.lineoffset = gpiod_line_offset(line);
> - req.handleflags = line_request_flag_to_gpio_handleflag(config->flags);
> - req.handleflags |= GPIOHANDLE_REQUEST_INPUT;
> + req.offsets[0] = gpiod_line_offset(line);
> + req.num_lines = 1;
> + line_request_config_to_gpio_v2_line_config(config, &req.config);
>
> - if (config->request_type == GPIOD_LINE_REQUEST_EVENT_RISING_EDGE)
> - req.eventflags |= GPIOEVENT_REQUEST_RISING_EDGE;
> - else if (config->request_type == GPIOD_LINE_REQUEST_EVENT_FALLING_EDGE)
> - req.eventflags |= GPIOEVENT_REQUEST_FALLING_EDGE;
> - else if (config->request_type == GPIOD_LINE_REQUEST_EVENT_BOTH_EDGES)
> - req.eventflags |= GPIOEVENT_REQUEST_BOTH_EDGES;
> -
> - rv = ioctl(line->chip->fd, GPIO_GET_LINEEVENT_IOCTL, &req);
> + rv = ioctl(line->chip->fd, GPIO_V2_GET_LINE_IOCTL, &req);
> if (rv < 0)
> return -1;
>
> @@ -708,13 +787,13 @@ static bool line_request_is_events(int request)
>
> int gpiod_line_request_bulk(struct gpiod_line_bulk *bulk,
> const struct gpiod_line_request_config *config,
> - const int *default_vals)
> + const int *vals)
> {
> if (!line_bulk_same_chip(bulk) || !line_bulk_all_free(bulk))
> return -1;
>
> if (line_request_is_direction(config->request_type))
> - return line_request_values(bulk, config, default_vals);
> + return line_request_values(bulk, config, vals);
> else if (line_request_is_events(config->request_type))
> return line_request_events(bulk, config);
>
> @@ -772,7 +851,7 @@ int gpiod_line_get_value(struct gpiod_line *line)
>
> int gpiod_line_get_value_bulk(struct gpiod_line_bulk *bulk, int *values)
> {
> - struct gpiohandle_data data;
> + struct gpio_v2_line_values lv;
> struct gpiod_line *line;
> unsigned int i;
> int rv, fd;
> @@ -782,27 +861,31 @@ int gpiod_line_get_value_bulk(struct gpiod_line_bulk *bulk, int *values)
>
> line = gpiod_line_bulk_get_line(bulk, 0);
>
> + memset(&lv, 0, sizeof(lv));
> +
> if (line->state == LINE_REQUESTED_VALUES) {
> - memset(&data, 0, sizeof(data));
> + for (i = 0; i < gpiod_line_bulk_num_lines(bulk); i++)
> + lines_bitmap_set_bit(&lv.mask, i);
>
> fd = line_get_fd(line);
>
> - rv = ioctl(fd, GPIOHANDLE_GET_LINE_VALUES_IOCTL, &data);
> + rv = ioctl(fd, GPIO_V2_LINE_GET_VALUES_IOCTL, &lv);
> if (rv < 0)
> return -1;
>
> for (i = 0; i < gpiod_line_bulk_num_lines(bulk); i++)
> - values[i] = data.values[i];
> + values[i] = lines_bitmap_test_bit(lv.bits, i);
>
> } else if (line->state == LINE_REQUESTED_EVENTS) {
> + lines_bitmap_set_bit(&lv.mask, 0);
> for (i = 0; i < gpiod_line_bulk_num_lines(bulk); i++) {
> line = gpiod_line_bulk_get_line(bulk, i);
>
> fd = line_get_fd(line);
> - rv = ioctl(fd, GPIOHANDLE_GET_LINE_VALUES_IOCTL, &data);
> + rv = ioctl(fd, GPIO_V2_LINE_GET_VALUES_IOCTL, &lv);
> if (rv < 0)
> return -1;
> - values[i] = data.values[0];
> + values[i] = lines_bitmap_test_bit(lv.bits, 0);
> }
> } else {
> errno = EINVAL;
> @@ -823,7 +906,7 @@ int gpiod_line_set_value(struct gpiod_line *line, int value)
>
> int gpiod_line_set_value_bulk(struct gpiod_line_bulk *bulk, const int *values)
> {
> - struct gpiohandle_data data;
> + struct gpio_v2_line_values lv;
> struct gpiod_line *line;
> unsigned int i;
> int rv, fd;
> @@ -831,22 +914,22 @@ int gpiod_line_set_value_bulk(struct gpiod_line_bulk *bulk, const int *values)
> if (!line_bulk_same_chip(bulk) || !line_bulk_all_requested(bulk))
> return -1;
>
> - memset(&data, 0, sizeof(data));
> + memset(&lv, 0, sizeof(lv));
>
> - if (values) {
> - for (i = 0; i < gpiod_line_bulk_num_lines(bulk); i++)
> - data.values[i] = (uint8_t)!!values[i];
> + for (i = 0; i < gpiod_line_bulk_num_lines(bulk); i++) {
> + lines_bitmap_set_bit(&lv.mask, i);
> + lines_bitmap_assign_bit(&lv.bits, i, values && values[i]);
> }
>
> line = gpiod_line_bulk_get_line(bulk, 0);
> fd = line_get_fd(line);
>
> - rv = ioctl(fd, GPIOHANDLE_SET_LINE_VALUES_IOCTL, &data);
> + rv = ioctl(fd, GPIO_V2_LINE_SET_VALUES_IOCTL, &lv);
> if (rv < 0)
> return -1;
>
> gpiod_line_bulk_foreach_line_off(bulk, line, i)
> - line->output_value = data.values[i];
> + line->output_value = lines_bitmap_test_bit(lv.bits, i);
>
> return 0;
> }
> @@ -866,7 +949,7 @@ int gpiod_line_set_config_bulk(struct gpiod_line_bulk *bulk,
> int direction, int flags,
> const int *values)
> {
> - struct gpiohandle_config hcfg;
> + struct gpio_v2_line_config hcfg;
> struct gpiod_line *line;
> unsigned int i;
> int rv, fd;
> @@ -880,24 +963,30 @@ int gpiod_line_set_config_bulk(struct gpiod_line_bulk *bulk,
>
> memset(&hcfg, 0, sizeof(hcfg));
>
> - hcfg.flags = line_request_flag_to_gpio_handleflag(flags);
> - hcfg.flags |= line_request_direction_to_gpio_handleflag(direction);
> + line_request_flag_to_gpio_v2_line_config(flags, &hcfg);
> + line_request_type_to_gpio_v2_line_config(direction, &hcfg);
> if (direction == GPIOD_LINE_REQUEST_DIRECTION_OUTPUT && values) {
> - for (i = 0; i < gpiod_line_bulk_num_lines(bulk); i++)
> - hcfg.default_values[i] = (uint8_t)!!values[i];
> + hcfg.num_attrs = 1;
> + hcfg.attrs[0].attr.id = GPIO_V2_LINE_ATTR_ID_OUTPUT_VALUES;
> + for (i = 0; i < gpiod_line_bulk_num_lines(bulk); i++) {
> + lines_bitmap_assign_bit(&hcfg.attrs[0].mask, i, 1);
> + lines_bitmap_assign_bit(
> + &hcfg.attrs[0].attr.values, i, values[i]);
> + }
> }
>
> line = gpiod_line_bulk_get_line(bulk, 0);
> fd = line_get_fd(line);
>
> - rv = ioctl(fd, GPIOHANDLE_SET_CONFIG_IOCTL, &hcfg);
> + rv = ioctl(fd, GPIO_V2_LINE_SET_CONFIG_IOCTL, &hcfg);
> if (rv < 0)
> return -1;
>
> gpiod_line_bulk_foreach_line_off(bulk, line, i) {
> line->req_flags = flags;
> if (direction == GPIOD_LINE_REQUEST_DIRECTION_OUTPUT)
> - line->output_value = hcfg.default_values[i];
> + line->output_value = lines_bitmap_test_bit(
> + hcfg.attrs[0].attr.values, i);
>
> rv = gpiod_line_update(line);
> if (rv < 0)
> @@ -1082,8 +1171,13 @@ int gpiod_line_event_read_fd_multiple(int fd, struct gpiod_line_event *events,
> /*
> * 16 is the maximum number of events the kernel can store in the FIFO
> * so we can allocate the buffer on the stack.
> + *
> + * NOTE: This is no longer strictly true for uAPI v2. While 16 is
> + * the default for single line, a request with multiple lines will
> + * have a larger buffer. So need to rethink the allocation here,
> + * or at least the comment above...
> */
> - struct gpioevent_data evdata[16], *curr;
> + struct gpio_v2_line_event evdata[16], *curr;
> struct gpiod_line_event *event;
> unsigned int events_read, i;
> ssize_t rd;
> @@ -1109,11 +1203,12 @@ int gpiod_line_event_read_fd_multiple(int fd, struct gpiod_line_event *events,
> curr = &evdata[i];
> event = &events[i];
>
> - event->event_type = curr->id == GPIOEVENT_EVENT_RISING_EDGE
> + event->offset = curr->offset;
> + event->event_type = curr->id == GPIO_V2_LINE_EVENT_RISING_EDGE
> ? GPIOD_LINE_EVENT_RISING_EDGE
> : GPIOD_LINE_EVENT_FALLING_EDGE;
> - event->ts.tv_sec = curr->timestamp / 1000000000ULL;
> - event->ts.tv_nsec = curr->timestamp % 1000000000ULL;
> + event->ts.tv_sec = curr->timestamp_ns / 1000000000ULL;
> + event->ts.tv_nsec = curr->timestamp_ns % 1000000000ULL;
> }
>
> return i;
> --
> 2.28.0
>
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2020-10-14 17:26 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-10-14 11:30 [libgpiod][PATCH v2] core: Basic port to uAPI v2 Kent Gibson
2020-10-14 13:15 ` Bartosz Golaszewski
2020-10-14 17:27 ` Andy Shevchenko
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).