diff options
Diffstat (limited to 'drivers/gpio/gpiolib-cdev.c')
-rw-r--r-- | drivers/gpio/gpiolib-cdev.c | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/drivers/gpio/gpiolib-cdev.c b/drivers/gpio/gpiolib-cdev.c index 192721f829a3..f64a35767434 100644 --- a/drivers/gpio/gpiolib-cdev.c +++ b/drivers/gpio/gpiolib-cdev.c @@ -509,6 +509,7 @@ struct linereq { GPIO_V2_LINE_DIRECTION_FLAGS | \ GPIO_V2_LINE_DRIVE_FLAGS | \ GPIO_V2_LINE_EDGE_FLAGS | \ + GPIO_V2_LINE_FLAG_EVENT_CLOCK_REALTIME | \ GPIO_V2_LINE_BIAS_FLAGS) static void linereq_put_event(struct linereq *lr, @@ -529,6 +530,14 @@ static void linereq_put_event(struct linereq *lr, pr_debug_ratelimited("event FIFO is full - event dropped\n"); } +static u64 line_event_timestamp(struct line *line) +{ + if (test_bit(FLAG_EVENT_CLOCK_REALTIME, &line->desc->flags)) + return ktime_get_real_ns(); + + return ktime_get_ns(); +} + static irqreturn_t edge_irq_thread(int irq, void *p) { struct line *line = p; @@ -546,7 +555,7 @@ static irqreturn_t edge_irq_thread(int irq, void *p) * which case we didn't get the timestamp from * edge_irq_handler(). */ - le.timestamp_ns = ktime_get_ns(); + le.timestamp_ns = line_event_timestamp(line); if (lr->num_lines != 1) line->req_seqno = atomic_inc_return(&lr->seqno); } @@ -590,7 +599,7 @@ static irqreturn_t edge_irq_handler(int irq, void *p) * Just store the timestamp in hardirq context so we get it as * close in time as possible to the actual event. */ - line->timestamp_ns = ktime_get_ns(); + line->timestamp_ns = line_event_timestamp(line); if (lr->num_lines != 1) line->req_seqno = atomic_inc_return(&lr->seqno); @@ -663,7 +672,7 @@ static void debounce_work_func(struct work_struct *work) memset(&le, 0, sizeof(le)); lr = line->req; - le.timestamp_ns = ktime_get_ns(); + le.timestamp_ns = line_event_timestamp(line); le.offset = gpio_chip_hwgpio(line->desc); line->line_seqno++; le.line_seqno = line->line_seqno; @@ -967,6 +976,9 @@ static void gpio_v2_line_config_flags_to_desc_flags(u64 flags, flags & GPIO_V2_LINE_FLAG_BIAS_PULL_DOWN); assign_bit(FLAG_BIAS_DISABLE, flagsp, flags & GPIO_V2_LINE_FLAG_BIAS_DISABLED); + + assign_bit(FLAG_EVENT_CLOCK_REALTIME, flagsp, + flags & GPIO_V2_LINE_FLAG_EVENT_CLOCK_REALTIME); } static long linereq_get_values(struct linereq *lr, void __user *ip) @@ -1930,6 +1942,9 @@ static void gpio_desc_to_lineinfo(struct gpio_desc *desc, if (test_bit(FLAG_EDGE_FALLING, &desc->flags)) info->flags |= GPIO_V2_LINE_FLAG_EDGE_FALLING; + if (test_bit(FLAG_EVENT_CLOCK_REALTIME, &desc->flags)) + info->flags |= GPIO_V2_LINE_FLAG_EVENT_CLOCK_REALTIME; + debounce_period_us = READ_ONCE(desc->debounce_period_us); if (debounce_period_us) { info->attrs[num_attrs].id = GPIO_V2_LINE_ATTR_ID_DEBOUNCE; |