* [PATCH 2/4] gpio: mt7621: more robust management of IRQ domain teardown
2026-06-20 12:01 [PATCH 0/4] gpio: mt7621: address Sashiko complains and other cleanups Sergio Paracuellos
2026-06-20 12:01 ` [PATCH 1/4] gpio: mt7621: avoid corruption of shared interrupt trigger state Sergio Paracuellos
@ 2026-06-20 12:01 ` Sergio Paracuellos
2026-06-22 8:12 ` Bartosz Golaszewski
2026-06-20 12:01 ` [PATCH 3/4] gpio: mt7621: be sure IRQ domain is created before exposing GPIO chips Sergio Paracuellos
2026-06-20 12:01 ` [PATCH 4/4] gpio: mt7621: unify naming style in driver code Sergio Paracuellos
3 siblings, 1 reply; 8+ messages in thread
From: Sergio Paracuellos @ 2026-06-20 12:01 UTC (permalink / raw)
To: linux-gpio; +Cc: linusw, brgl, vicencb, linux-kernel, Sashiko
The driver uses devm_gpiochip_add_data() to register the GPIO chips which
means the devres subsystem will unregister them only after the function
'mt7621_gpio_remove()' returns. During the window between domain destruction
and devres unregistering the GPIO chips, the chips are still fully active.
If a consumer or userspace invokes gpiod_to_irq() during this window,
'mt7621_gpio_to_irq()' can dereference the already-freed irq domain pointer.
Thus, manage the IRQ domain teardown using 'devm_add_action_or_reset()' to
guarantee it is destroyed strictly after the GPIO chips are removed.
Reported-by: Sashiko <sashiko-bot@kernel.org>
Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
---
drivers/gpio/gpio-mt7621.c | 15 +++++++--------
1 file changed, 7 insertions(+), 8 deletions(-)
diff --git a/drivers/gpio/gpio-mt7621.c b/drivers/gpio/gpio-mt7621.c
index ceb99641baee..57384ef74703 100644
--- a/drivers/gpio/gpio-mt7621.c
+++ b/drivers/gpio/gpio-mt7621.c
@@ -272,9 +272,9 @@ static const struct irq_chip mt7621_irq_chip = {
};
static void
-mt7621_gpio_remove(struct platform_device *pdev)
+mt7621_gpio_remove(void *data)
{
- struct mtk *priv = platform_get_drvdata(pdev);
+ struct mtk *priv = data;
int offset, virq;
if (priv->gpio_irq > 0)
@@ -475,14 +475,14 @@ mediatek_gpio_probe(struct platform_device *pdev)
if (mtk->gpio_irq > 0) {
ret = mt7621_gpio_irq_setup(pdev, mtk);
if (ret)
- goto fail;
+ return ret;
}
- return 0;
+ ret = devm_add_action_or_reset(dev, mt7621_gpio_remove, mtk);
+ if (ret)
+ return ret;
-fail:
- mt7621_gpio_remove(pdev);
- return ret;
+ return 0;
}
static const struct of_device_id mediatek_gpio_match[] = {
@@ -493,7 +493,6 @@ MODULE_DEVICE_TABLE(of, mediatek_gpio_match);
static struct platform_driver mediatek_gpio_driver = {
.probe = mediatek_gpio_probe,
- .remove = mt7621_gpio_remove,
.driver = {
.name = "mt7621_gpio",
.of_match_table = mediatek_gpio_match,
--
2.43.0
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH 3/4] gpio: mt7621: be sure IRQ domain is created before exposing GPIO chips
2026-06-20 12:01 [PATCH 0/4] gpio: mt7621: address Sashiko complains and other cleanups Sergio Paracuellos
2026-06-20 12:01 ` [PATCH 1/4] gpio: mt7621: avoid corruption of shared interrupt trigger state Sergio Paracuellos
2026-06-20 12:01 ` [PATCH 2/4] gpio: mt7621: more robust management of IRQ domain teardown Sergio Paracuellos
@ 2026-06-20 12:01 ` Sergio Paracuellos
2026-06-20 12:01 ` [PATCH 4/4] gpio: mt7621: unify naming style in driver code Sergio Paracuellos
3 siblings, 0 replies; 8+ messages in thread
From: Sergio Paracuellos @ 2026-06-20 12:01 UTC (permalink / raw)
To: linux-gpio; +Cc: linusw, brgl, vicencb, linux-kernel, Sashiko
Function 'mediatek_gpio_bank_probe()' registers three GPIO chips using
'devm_gpiochip_add_data()'. At this point, the chips become live and visible
to consumers. However, the IRQ domain isn't allocated and set up until
'mt7621_gpio_irq_setup()' is called after the GPIO chips setup finishes.
If a consumer requests a GPIO IRQ concurrently 'mt7621_gpio_to_irq()' can
be called and pass a NULL irq domain pointer irq_create_mapping(), that can
corrupt the mappings or cause a crash. Fix this possible problem seting up
irq domain before GPIO chips setup is performed.
Reported-by: Sashiko <sashiko-bot@kernel.org>
Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
---
drivers/gpio/gpio-mt7621.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/gpio/gpio-mt7621.c b/drivers/gpio/gpio-mt7621.c
index 57384ef74703..1b0b5247d3c9 100644
--- a/drivers/gpio/gpio-mt7621.c
+++ b/drivers/gpio/gpio-mt7621.c
@@ -466,12 +466,6 @@ mediatek_gpio_probe(struct platform_device *pdev)
mtk->num_gpios = MTK_BANK_WIDTH * MTK_BANK_CNT;
platform_set_drvdata(pdev, mtk);
- for (i = 0; i < MTK_BANK_CNT; i++) {
- ret = mediatek_gpio_bank_probe(dev, i);
- if (ret)
- return ret;
- }
-
if (mtk->gpio_irq > 0) {
ret = mt7621_gpio_irq_setup(pdev, mtk);
if (ret)
@@ -482,6 +476,12 @@ mediatek_gpio_probe(struct platform_device *pdev)
if (ret)
return ret;
+ for (i = 0; i < MTK_BANK_CNT; i++) {
+ ret = mediatek_gpio_bank_probe(dev, i);
+ if (ret)
+ return ret;
+ }
+
return 0;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH 4/4] gpio: mt7621: unify naming style in driver code
2026-06-20 12:01 [PATCH 0/4] gpio: mt7621: address Sashiko complains and other cleanups Sergio Paracuellos
` (2 preceding siblings ...)
2026-06-20 12:01 ` [PATCH 3/4] gpio: mt7621: be sure IRQ domain is created before exposing GPIO chips Sergio Paracuellos
@ 2026-06-20 12:01 ` Sergio Paracuellos
3 siblings, 0 replies; 8+ messages in thread
From: Sergio Paracuellos @ 2026-06-20 12:01 UTC (permalink / raw)
To: linux-gpio; +Cc: linusw, brgl, vicencb, linux-kernel
There is a mix of 'mediatek' and 'mt7621' mix of prefix in different
function names along the code of the driver. Be consistent using 'mt7621'
for all function prefixes.
Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
---
drivers/gpio/gpio-mt7621.c | 40 +++++++++++++++++++-------------------
1 file changed, 20 insertions(+), 20 deletions(-)
diff --git a/drivers/gpio/gpio-mt7621.c b/drivers/gpio/gpio-mt7621.c
index 1b0b5247d3c9..87086c322f08 100644
--- a/drivers/gpio/gpio-mt7621.c
+++ b/drivers/gpio/gpio-mt7621.c
@@ -68,7 +68,7 @@ mt7621_gpio_gc_to_priv(struct gpio_chip *gc)
}
static inline struct mtk_gc *
-to_mediatek_gpio(struct gpio_chip *chip)
+to_mt7621_gpio(struct gpio_chip *chip)
{
struct gpio_generic_chip *gen_gc = to_gpio_generic_chip(chip);
@@ -137,7 +137,7 @@ mt7621_gpio_hwirq_to_offset(irq_hw_number_t hwirq, struct mtk_gc *bank)
}
static void
-mediatek_gpio_irq_unmask(struct irq_data *d)
+mt7621_gpio_irq_unmask(struct irq_data *d)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct mtk_gc *rg = gpiochip_get_data(gc);
@@ -159,7 +159,7 @@ mediatek_gpio_irq_unmask(struct irq_data *d)
}
static void
-mediatek_gpio_irq_mask(struct irq_data *d)
+mt7621_gpio_irq_mask(struct irq_data *d)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct mtk_gc *rg = gpiochip_get_data(gc);
@@ -181,7 +181,7 @@ mediatek_gpio_irq_mask(struct irq_data *d)
}
static int
-mediatek_gpio_irq_type(struct irq_data *d, unsigned int type)
+mt7621_gpio_irq_type(struct irq_data *d, unsigned int type)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct mtk_gc *rg = gpiochip_get_data(gc);
@@ -245,11 +245,11 @@ mt7621_gpio_irq_relres(struct irq_data *d)
}
static int
-mediatek_gpio_xlate(struct gpio_chip *chip,
+mt7621_gpio_xlate(struct gpio_chip *chip,
const struct of_phandle_args *spec, u32 *flags)
{
int gpio = spec->args[0];
- struct mtk_gc *rg = to_mediatek_gpio(chip);
+ struct mtk_gc *rg = to_mt7621_gpio(chip);
if (rg->bank != gpio / MTK_BANK_WIDTH)
return -EINVAL;
@@ -264,10 +264,10 @@ static const struct irq_chip mt7621_irq_chip = {
.name = "mt7621-gpio",
.irq_request_resources = mt7621_gpio_irq_reqres,
.irq_release_resources = mt7621_gpio_irq_relres,
- .irq_mask_ack = mediatek_gpio_irq_mask,
- .irq_mask = mediatek_gpio_irq_mask,
- .irq_unmask = mediatek_gpio_irq_unmask,
- .irq_set_type = mediatek_gpio_irq_type,
+ .irq_mask_ack = mt7621_gpio_irq_mask,
+ .irq_mask = mt7621_gpio_irq_mask,
+ .irq_unmask = mt7621_gpio_irq_unmask,
+ .irq_set_type = mt7621_gpio_irq_type,
.flags = IRQCHIP_IMMUTABLE,
};
@@ -380,7 +380,7 @@ mt7621_gpio_to_irq(struct gpio_chip *gc, unsigned int offset)
}
static int
-mediatek_gpio_bank_probe(struct device *dev, int bank)
+mt7621_gpio_bank_probe(struct device *dev, int bank)
{
struct gpio_generic_chip_config config;
struct mtk *mtk = dev_get_drvdata(dev);
@@ -416,7 +416,7 @@ mediatek_gpio_bank_probe(struct device *dev, int bank)
}
rg->chip.gc.of_gpio_n_cells = 2;
- rg->chip.gc.of_xlate = mediatek_gpio_xlate;
+ rg->chip.gc.of_xlate = mt7621_gpio_xlate;
rg->chip.gc.ngpio = MTK_BANK_WIDTH;
rg->chip.gc.label = devm_kasprintf(dev, GFP_KERNEL, "%s-bank%d",
dev_name(dev), bank);
@@ -443,7 +443,7 @@ mediatek_gpio_bank_probe(struct device *dev, int bank)
}
static int
-mediatek_gpio_probe(struct platform_device *pdev)
+mt7621_gpio_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct mtk *mtk;
@@ -477,7 +477,7 @@ mediatek_gpio_probe(struct platform_device *pdev)
return ret;
for (i = 0; i < MTK_BANK_CNT; i++) {
- ret = mediatek_gpio_bank_probe(dev, i);
+ ret = mt7621_gpio_bank_probe(dev, i);
if (ret)
return ret;
}
@@ -485,18 +485,18 @@ mediatek_gpio_probe(struct platform_device *pdev)
return 0;
}
-static const struct of_device_id mediatek_gpio_match[] = {
+static const struct of_device_id mt7621_gpio_match[] = {
{ .compatible = "mediatek,mt7621-gpio" },
{},
};
-MODULE_DEVICE_TABLE(of, mediatek_gpio_match);
+MODULE_DEVICE_TABLE(of, mt7621_gpio_match);
-static struct platform_driver mediatek_gpio_driver = {
- .probe = mediatek_gpio_probe,
+static struct platform_driver mt7621_gpio_driver = {
+ .probe = mt7621_gpio_probe,
.driver = {
.name = "mt7621_gpio",
- .of_match_table = mediatek_gpio_match,
+ .of_match_table = mt7621_gpio_match,
},
};
-builtin_platform_driver(mediatek_gpio_driver);
+builtin_platform_driver(mt7621_gpio_driver);
--
2.43.0
^ permalink raw reply related [flat|nested] 8+ messages in thread