]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
gpio: core: fix const-correctness of gpio_chip_guard
authorMarco Scardovi (scardracs) <scardracs@disroot.org>
Sun, 24 May 2026 16:27:07 +0000 (18:27 +0200)
committerBartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Thu, 4 Jun 2026 13:51:31 +0000 (15:51 +0200)
The DEFINE_CLASS macro for gpio_chip_guard currently expects a non-const
struct gpio_desc pointer. This prevents the guard from being used cleanly
in fast paths that receive a const descriptor, forcing developers to fall
back to open-coding the SRCU locks.

Update the macro to accept a const struct gpio_desc pointer. This is valid
because the actual targeted gpio_device pointer assignment does not drop
const qualifiers on the target structure.

Convert the open-coded SRCU locks in gpiod_get_raw_value_commit() and
gpiod_to_irq() to use the guard, removing their legacy FIXME comments.

Assisted-by: Antigravity:gemini-3.5-flash
Signed-off-by: Marco Scardovi <scardracs@disroot.org>
Acked-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Link: https://patch.msgid.link/20260524162708.62949-2-scardracs@disroot.org
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
drivers/gpio/gpiolib.c
drivers/gpio/gpiolib.h

index c72eec54cb196f5268ec482074a0fad2b2631650..ac2779dbe42b5768fb4460b9cbbe3d0135da03a5 100644 (file)
@@ -3428,20 +3428,13 @@ static int gpio_chip_get_value(struct gpio_chip *gc, const struct gpio_desc *des
 
 static int gpiod_get_raw_value_commit(const struct gpio_desc *desc)
 {
-       struct gpio_device *gdev;
-       struct gpio_chip *gc;
        int value;
 
-       /* FIXME Unable to use gpio_chip_guard due to const desc. */
-       gdev = desc->gdev;
-
-       guard(srcu)(&gdev->srcu);
-
-       gc = srcu_dereference(gdev->chip, &gdev->srcu);
-       if (!gc)
+       CLASS(gpio_chip_guard, guard)(desc);
+       if (!guard.gc)
                return -ENODEV;
 
-       value = gpio_chip_get_value(gc, desc);
+       value = gpio_chip_get_value(guard.gc, desc);
        value = value < 0 ? value : !!value;
        trace_gpio_value(desc_to_gpio(desc), 1, value);
        return value;
@@ -4148,8 +4141,6 @@ EXPORT_SYMBOL_GPL(gpiod_is_shared);
  */
 int gpiod_to_irq(const struct gpio_desc *desc)
 {
-       struct gpio_device *gdev;
-       struct gpio_chip *gc;
        int offset;
        int ret;
 
@@ -4157,16 +4148,13 @@ int gpiod_to_irq(const struct gpio_desc *desc)
        if (ret <= 0)
                return -EINVAL;
 
-       gdev = desc->gdev;
-       /* FIXME Cannot use gpio_chip_guard due to const desc. */
-       guard(srcu)(&gdev->srcu);
-       gc = srcu_dereference(gdev->chip, &gdev->srcu);
-       if (!gc)
+       CLASS(gpio_chip_guard, guard)(desc);
+       if (!guard.gc)
                return -ENODEV;
 
        offset = gpiod_hwgpio(desc);
-       if (gc->to_irq) {
-               ret = gc->to_irq(gc, offset);
+       if (guard.gc->to_irq) {
+               ret = guard.gc->to_irq(guard.gc, offset);
                if (ret)
                        return ret;
 
@@ -4174,7 +4162,7 @@ int gpiod_to_irq(const struct gpio_desc *desc)
                return -ENXIO;
        }
 #ifdef CONFIG_GPIOLIB_IRQCHIP
-       if (gc->irq.chip) {
+       if (guard.gc->irq.chip) {
                /*
                 * Avoid race condition with other code, which tries to lookup
                 * an IRQ before the irqchip has been properly registered,
index dc4cb61a93187659d943f4ce3622bc1755e9fd42..650a702741dfb938fbdf11db65a46ac85b6af512 100644 (file)
@@ -244,7 +244,7 @@ DEFINE_CLASS(gpio_chip_guard,
 
                _guard;
             }),
-            struct gpio_desc *desc)
+            const struct gpio_desc *desc)
 
 int gpiod_request(struct gpio_desc *desc, const char *label);
 int gpiod_request_commit(struct gpio_desc *desc, const char *label);