]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
pps: clients: gpio: Bypass edge's direction check when not needed
authorBastien Curutchet <bastien.curutchet@bootlin.com>
Wed, 8 Jan 2025 15:30:12 +0000 (16:30 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 10 Jan 2025 15:12:33 +0000 (16:12 +0100)
In the IRQ handler, the GPIO's state is read to verify the direction of
the edge that triggered the interruption before generating the PPS event.
If a pulse is too short, the GPIO line can reach back its original state
before this verification and the PPS event is lost.

This check is needed when info->capture_clear is set because it needs
interruptions on both rising and falling edges. When info->capture_clear
is not set, interruption is triggered by one edge only so this check can
be omitted.

Add a warning if irq_handler is left without triggering any PPS event.
Bypass the edge's direction verification when info->capture_clear is not
set.

Signed-off-by: Bastien Curutchet <bastien.curutchet@bootlin.com>
Acked-by: Rodolfo Giometti <giometti@enneenne.com>
Link: https://lore.kernel.org/r/20250108153012.514925-1-bastien.curutchet@bootlin.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/pps/clients/pps-gpio.c

index f77b19884f051b658dfbf9a9483c3e1bc053b79c..75c1bae30a7cb76ab89e77b35d998fe933c4f94c 100644 (file)
@@ -52,7 +52,9 @@ static irqreturn_t pps_gpio_irq_handler(int irq, void *data)
 
        info = data;
 
-       rising_edge = gpiod_get_value(info->gpio_pin);
+       /* Small trick to bypass the check on edge's direction when capture_clear is unset */
+       rising_edge = info->capture_clear ?
+                     gpiod_get_value(info->gpio_pin) : !info->assert_falling_edge;
        if ((rising_edge && !info->assert_falling_edge) ||
                        (!rising_edge && info->assert_falling_edge))
                pps_event(info->pps, &ts, PPS_CAPTUREASSERT, data);
@@ -60,6 +62,8 @@ static irqreturn_t pps_gpio_irq_handler(int irq, void *data)
                        ((rising_edge && info->assert_falling_edge) ||
                        (!rising_edge && !info->assert_falling_edge)))
                pps_event(info->pps, &ts, PPS_CAPTURECLEAR, data);
+       else
+               dev_warn_ratelimited(&info->pps->dev, "IRQ did not trigger any PPS event\n");
 
        return IRQ_HANDLED;
 }