mirror of
https://github.com/torvalds/linux.git
synced 2026-05-29 17:43:52 +02:00
gpio: mt7621: use the generic GPIO chip lock for IRQ handling
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>
This commit is contained in:
parent
80fd7e96d6
commit
2c1f22fa54
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user