Commit d4868b18 authored by Jan Kiszka's avatar Jan Kiszka
Browse files

drivers/gpio: Add support for selecting real-time clock timestamps



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's avatarJan Kiszka <jan.kiszka@siemens.com>
parent 8a2f250d
......@@ -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 {
......
......@@ -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
......
......@@ -42,7 +42,10 @@ static int gpio_pin_interrupt(rtdm_irq_t *irqh)
pin = rtdm_irq_get_arg(irqh, struct rtdm_gpio_pin);
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 RTDM_IRQ_HANDLED;
......@@ -189,11 +192,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 +233,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 +497,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;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment