]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
gpio: mt7621: use the generic GPIO chip lock for IRQ handling
authorBartosz Golaszewski <bartosz.golaszewski@linaro.org>
Wed, 10 Sep 2025 07:12:45 +0000 (09:12 +0200)
committerBartosz Golaszewski <bartosz.golaszewski@linaro.org>
Fri, 12 Sep 2025 07:22:44 +0000 (09:22 +0200)
This driver uses its own spinlock in interrupt routines while the
generic GPIO chip callbacks use a separate one. This is, of course, racy
so use the fact that the lock in generic GPIO chip is also a spinlock and
convert the interrupt handling functions in this module to using the
provided generic GPIO chip locking API.

Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Link: https://lore.kernel.org/r/20250910-gpio-mmio-gpio-conv-part4-v2-9-f3d1a4c57124@linaro.org
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
drivers/gpio/gpio-mt7621.c

index e56812a1721151c8f3b32b5093aee5c74bb798bc..e7bb9b2cd6cf32baa71b4185ea274075a7bc2d8f 100644 (file)
@@ -11,7 +11,6 @@
 #include <linux/io.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
-#include <linux/spinlock.h>
 
 #define MTK_BANK_CNT   3
 #define MTK_BANK_WIDTH 32
@@ -32,7 +31,6 @@
 struct mtk_gc {
        struct irq_chip irq_chip;
        struct gpio_generic_chip chip;
-       spinlock_t lock;
        int bank;
        u32 rising;
        u32 falling;
@@ -111,12 +109,12 @@ mediatek_gpio_irq_unmask(struct irq_data *d)
        struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
        struct mtk_gc *rg = to_mediatek_gpio(gc);
        int pin = d->hwirq;
-       unsigned long flags;
        u32 rise, fall, high, low;
 
        gpiochip_enable_irq(gc, d->hwirq);
 
-       spin_lock_irqsave(&rg->lock, flags);
+       guard(gpio_generic_lock_irqsave)(&rg->chip);
+
        rise = mtk_gpio_r32(rg, GPIO_REG_REDGE);
        fall = mtk_gpio_r32(rg, GPIO_REG_FEDGE);
        high = mtk_gpio_r32(rg, GPIO_REG_HLVL);
@@ -125,7 +123,6 @@ mediatek_gpio_irq_unmask(struct irq_data *d)
        mtk_gpio_w32(rg, GPIO_REG_FEDGE, fall | (BIT(pin) & rg->falling));
        mtk_gpio_w32(rg, GPIO_REG_HLVL, high | (BIT(pin) & rg->hlevel));
        mtk_gpio_w32(rg, GPIO_REG_LLVL, low | (BIT(pin) & rg->llevel));
-       spin_unlock_irqrestore(&rg->lock, flags);
 }
 
 static void
@@ -134,19 +131,18 @@ mediatek_gpio_irq_mask(struct irq_data *d)
        struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
        struct mtk_gc *rg = to_mediatek_gpio(gc);
        int pin = d->hwirq;
-       unsigned long flags;
        u32 rise, fall, high, low;
 
-       spin_lock_irqsave(&rg->lock, flags);
-       rise = mtk_gpio_r32(rg, GPIO_REG_REDGE);
-       fall = mtk_gpio_r32(rg, GPIO_REG_FEDGE);
-       high = mtk_gpio_r32(rg, GPIO_REG_HLVL);
-       low = mtk_gpio_r32(rg, GPIO_REG_LLVL);
-       mtk_gpio_w32(rg, GPIO_REG_FEDGE, fall & ~BIT(pin));
-       mtk_gpio_w32(rg, GPIO_REG_REDGE, rise & ~BIT(pin));
-       mtk_gpio_w32(rg, GPIO_REG_HLVL, high & ~BIT(pin));
-       mtk_gpio_w32(rg, GPIO_REG_LLVL, low & ~BIT(pin));
-       spin_unlock_irqrestore(&rg->lock, flags);
+       scoped_guard(gpio_generic_lock_irqsave, &rg->chip) {
+               rise = mtk_gpio_r32(rg, GPIO_REG_REDGE);
+               fall = mtk_gpio_r32(rg, GPIO_REG_FEDGE);
+               high = mtk_gpio_r32(rg, GPIO_REG_HLVL);
+               low = mtk_gpio_r32(rg, GPIO_REG_LLVL);
+               mtk_gpio_w32(rg, GPIO_REG_FEDGE, fall & ~BIT(pin));
+               mtk_gpio_w32(rg, GPIO_REG_REDGE, rise & ~BIT(pin));
+               mtk_gpio_w32(rg, GPIO_REG_HLVL, high & ~BIT(pin));
+               mtk_gpio_w32(rg, GPIO_REG_LLVL, low & ~BIT(pin));
+       }
 
        gpiochip_disable_irq(gc, d->hwirq);
 }
@@ -232,7 +228,6 @@ mediatek_gpio_bank_probe(struct device *dev, int bank)
        rg = &mtk->gc_map[bank];
        memset(rg, 0, sizeof(*rg));
 
-       spin_lock_init(&rg->lock);
        rg->bank = bank;
 
        dat = mtk->base + GPIO_REG_DATA + (rg->bank * GPIO_BANK_STRIDE);