From: Jan Kiszka <jan.kis...@siemens.com> This allows to compare timestamps of GPIO pins against other devices and ensures that the stamps are synchronized cross-systems in case PTP is in use (dovetail-based kernels). Keep default to monotonic for now.
Signed-off-by: Jan Kiszka <jan.kis...@siemens.com> --- include/cobalt/kernel/rtdm/gpio.h | 1 + include/rtdm/uapi/gpio.h | 4 +++- kernel/drivers/gpio/gpio-core.c | 14 +++++++++++--- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/include/cobalt/kernel/rtdm/gpio.h b/include/cobalt/kernel/rtdm/gpio.h index 00055ec0a9..72cc3a0356 100644 --- a/include/cobalt/kernel/rtdm/gpio.h +++ b/include/cobalt/kernel/rtdm/gpio.h @@ -34,6 +34,7 @@ struct rtdm_gpio_pin { char *name; struct gpio_desc *desc; nanosecs_abs_t timestamp; + bool monotonic_timestamp; }; struct rtdm_gpio_chip { diff --git a/include/rtdm/uapi/gpio.h b/include/rtdm/uapi/gpio.h index 2839f7d51c..fb84274453 100644 --- a/include/rtdm/uapi/gpio.h +++ b/include/rtdm/uapi/gpio.h @@ -29,7 +29,9 @@ struct rtdm_gpio_readout { #define GPIO_RTIOC_IRQDIS _IO(RTDM_CLASS_GPIO, 3) #define GPIO_RTIOC_REQS _IO(RTDM_CLASS_GPIO, 4) #define GPIO_RTIOC_RELS _IO(RTDM_CLASS_GPIO, 5) -#define GPIO_RTIOC_TS _IOR(RTDM_CLASS_GPIO, 7, int) +#define GPIO_RTIOC_TS_MONO _IOR(RTDM_CLASS_GPIO, 7, int) +#define GPIO_RTIOC_TS GPIO_RTIOC_TS_MONO +#define GPIO_RTIOC_TS_REAL _IOR(RTDM_CLASS_GPIO, 8, int) #define GPIO_TRIGGER_NONE 0x0 /* unspecified */ #define GPIO_TRIGGER_EDGE_RISING 0x1 diff --git a/kernel/drivers/gpio/gpio-core.c b/kernel/drivers/gpio/gpio-core.c index 600ef9789a..06a19b33a9 100644 --- a/kernel/drivers/gpio/gpio-core.c +++ b/kernel/drivers/gpio/gpio-core.c @@ -189,11 +189,13 @@ static int gpio_pin_ioctl_nrt(struct rtdm_fd *fd, gpio_free(gpio); chan->requested = false; break; - case GPIO_RTIOC_TS: + case GPIO_RTIOC_TS_MONO: + case GPIO_RTIOC_TS_REAL: ret = rtdm_safe_copy_from_user(fd, &val, arg, sizeof(val)); if (ret) return ret; chan->want_timestamp = !!val; + pin->monotonic_timestamp = request == GPIO_RTIOC_TS_MONO; break; default: return -EINVAL; @@ -228,8 +230,11 @@ static ssize_t gpio_pin_read_rt(struct rtdm_fd *fd, if (ret) return ret; rdo.timestamp = pin->timestamp; - } else + } else if (pin->monotonic_timestamp) { rdo.timestamp = rtdm_clock_read_monotonic(); + } else { + rdo.timestamp = rtdm_clock_read(); + } len = sizeof(rdo); rdo.value = gpiod_get_raw_value(pin->desc); @@ -489,7 +494,10 @@ int rtdm_gpiochip_post_event(struct rtdm_gpio_chip *rgc, return -EINVAL; pin = rgc->pins + offset; - pin->timestamp = rtdm_clock_read_monotonic(); + if (pin->monotonic_timestamp) + pin->timestamp = rtdm_clock_read_monotonic(); + else + pin->timestamp = rtdm_clock_read(); rtdm_event_signal(&pin->event); return 0; -- 2.31.1