* [PATCH v2] gpio: dwapb: Add robust error handling in interrupt handler
[not found] <20260703131833.17097-1-haohlliang@gmail.com>
@ 2026-07-03 14:27 ` Liang Hao
2026-07-03 14:38 ` [PATCH v3] " Liang Hao
0 siblings, 1 reply; 2+ messages in thread
From: Liang Hao @ 2026-07-03 14:27 UTC (permalink / raw)
To: hoan, linusw, brgl; +Cc: linux-gpio, linux-kernel, Liang Hao
The current interrupt handler silently continues if an interrupt
handling fails, which may lead to interrupt storms. Add proper
error handling to gracefully recover from failed interrupt
handling.
When generic_handle_irq() fails, the following recovery actions are
taken:
- Write EOI to clear the pending interrupt
- Mask the interrupt to prevent immediate re-triggering
- Disable the interrupt to stop further interrupts on this line
Use scoped_guard(gpio_generic_lock_irqsave) to protect the read-
modify-write sequences on shared registers (GPIO_INTMASK and
GPIO_INTEN). This prevents race conditions with irq_chip callbacks
(dwapb_irq_mask, dwapb_irq_enable, etc.) that access the same
registers from different contexts.
These measures prevent the system from being overwhelmed by repeated
unhandled interrupts while logging a rate-limited warning for
debugging purposes.
Signed-off-by: Liang Hao <haohlliang@gmail.com>
---
v1 -> v2:
- Add spinlock protection for register access in error path
- Protect against race with irq_chip callbacks accessing shared registers
---
drivers/gpio/gpio-dwapb.c | 19 +++++++++++++++++--
1 file changed, 17 insertions(+), 2 deletions(-)
diff --git a/drivers/gpio/gpio-dwapb.c b/drivers/gpio/gpio-dwapb.c
index 7b92b233fafe..dc9676eb1429 100644
--- a/drivers/gpio/gpio-dwapb.c
+++ b/drivers/gpio/gpio-dwapb.c
@@ -209,8 +209,23 @@ static u32 dwapb_do_irq(struct dwapb_gpio *gpio)
for_each_set_bit(hwirq, &irq_status, DWAPB_MAX_GPIOS) {
int gpio_irq = irq_find_mapping(gen_gc->gc.irq.domain, hwirq);
u32 irq_type = irq_get_trigger_type(gpio_irq);
-
- generic_handle_irq(gpio_irq);
+ int ret;
+ u32 val_intmask, val_inten;
+
+ ret = generic_handle_irq(gpio_irq);
+ if (ret) {
+ dev_warn_ratelimited(gpio->dev, "Failed to handle irq %d\n", gpio_irq);
+ /* Clear the interrupt */
+ scoped_guard(gpio_generic_lock_irqsave, gen_gc) {
+ /* Clear the interrupt */
+ dwapb_write(gpio, GPIO_PORTA_EOI, BIT(hwirq));
+ val_intmask = dwapb_read(gpio, GPIO_INTMASK);
+ dwapb_write(gpio, GPIO_INTMASK, val_intmask | BIT(hwirq));
+ val_inten = dwapb_read(gpio, GPIO_INTEN);
+ dwapb_write(gpio, GPIO_INTEN, val_inten & ~BIT(hwirq));
+ }
+ continue;
+ }
if ((irq_type & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH)
dwapb_toggle_trigger(gpio, hwirq);
--
2.50.1 (Apple Git-155)
^ permalink raw reply related [flat|nested] 2+ messages in thread
* [PATCH v3] gpio: dwapb: Add robust error handling in interrupt handler
2026-07-03 14:27 ` [PATCH v2] gpio: dwapb: Add robust error handling in interrupt handler Liang Hao
@ 2026-07-03 14:38 ` Liang Hao
0 siblings, 0 replies; 2+ messages in thread
From: Liang Hao @ 2026-07-03 14:38 UTC (permalink / raw)
To: hoan, linusw, brgl; +Cc: linux-gpio, linux-kernel, Liang Hao
The current interrupt handler silently continues if an interrupt
handling fails, which may lead to interrupt storms. Add proper
error handling to gracefully recover from failed interrupt
handling.
When generic_handle_irq() fails, the following recovery actions are
taken:
- Write EOI to clear the pending interrupt
- Mask the interrupt to prevent immediate re-triggering
- Disable the interrupt to stop further interrupts on this line
Use scoped_guard(gpio_generic_lock_irqsave) to protect the read-
modify-write sequences on shared registers (GPIO_INTMASK and
GPIO_INTEN). This prevents race conditions with irq_chip callbacks
(dwapb_irq_mask, dwapb_irq_enable, etc.) that access the same
registers from different contexts.
These measures prevent the system from being overwhelmed by repeated
unhandled interrupts while logging a rate-limited warning for
debugging purposes.
Signed-off-by: Liang Hao <haohlliang@gmail.com>
---
v2 -> v3:
- Remove duplicate comment
v1 -> v2:
- Add spinlock protection for register access in error path
- Protect against race with irq_chip callbacks accessing shared registers
---
drivers/gpio/gpio-dwapb.c | 19 +++++++++++++++++--
1 file changed, 17 insertions(+), 2 deletions(-)
diff --git a/drivers/gpio/gpio-dwapb.c b/drivers/gpio/gpio-dwapb.c
index 7b92b233fafe..dc9676eb1429 100644
--- a/drivers/gpio/gpio-dwapb.c
+++ b/drivers/gpio/gpio-dwapb.c
@@ -209,8 +209,23 @@ static u32 dwapb_do_irq(struct dwapb_gpio *gpio)
for_each_set_bit(hwirq, &irq_status, DWAPB_MAX_GPIOS) {
int gpio_irq = irq_find_mapping(gen_gc->gc.irq.domain, hwirq);
u32 irq_type = irq_get_trigger_type(gpio_irq);
-
- generic_handle_irq(gpio_irq);
+ int ret;
+ u32 val_intmask, val_inten;
+
+ ret = generic_handle_irq(gpio_irq);
+ if (ret) {
+ dev_warn_ratelimited(gpio->dev, "Failed to handle irq %d\n", gpio_irq);
+ /* Clear the interrupt */
+ scoped_guard(gpio_generic_lock_irqsave, gen_gc) {
+ /* Clear the interrupt */
+ dwapb_write(gpio, GPIO_PORTA_EOI, BIT(hwirq));
+ val_intmask = dwapb_read(gpio, GPIO_INTMASK);
+ dwapb_write(gpio, GPIO_INTMASK, val_intmask | BIT(hwirq));
+ val_inten = dwapb_read(gpio, GPIO_INTEN);
+ dwapb_write(gpio, GPIO_INTEN, val_inten & ~BIT(hwirq));
+ }
+ continue;
+ }
if ((irq_type & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH)
dwapb_toggle_trigger(gpio, hwirq);
--
2.50.1 (Apple Git-155)
^ permalink raw reply related [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-07-03 14:38 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <20260703131833.17097-1-haohlliang@gmail.com>
2026-07-03 14:27 ` [PATCH v2] gpio: dwapb: Add robust error handling in interrupt handler Liang Hao
2026-07-03 14:38 ` [PATCH v3] " Liang Hao
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox