[PATCH 1/2] gpio: aspeed: Clear only the acked line's G4 interrupt status

From: Billy Tsai

Date: Tue Nov 03 2026 - 22:59:15 EST


The G4 interrupt status registers are write-1-to-clear: writing 0 to a
bit has no effect and writing 1 clears that line's status flag.
aspeed_gpio_irq_ack() clears a line's status through
aspeed_g4_reg_bit_set(), which reads the bank's status register, sets
the line's bit and writes the whole value back. That write clears every
interrupt pending in the 32-line bank, not just the acked one.

aspeed_gpio_irq_handler() reads each bank's status register once and
dispatches the lines that were set. If another line in the same bank
latches an edge after that read and before an ack in the bank, the ack
clears its status and the handler is never called for it, so the edge
is lost.

Write only the line's own bit when clearing the interrupt status on G4.

Fixes: 79fc9a2fcc45 ("gpio: aspeed: Create llops to handle hardware access")
Cc: stable@xxxxxxxxxxxxxxx
Reported-by: Aaron Antone <aae@xxxxxxxxxx>
Suggested-by: Aaron Antone <aae@xxxxxxxxxx>
Signed-off-by: Billy Tsai <billy_tsai@xxxxxxxxxxxxxx>
---
drivers/gpio/gpio-aspeed.c | 11 +++++++++++
1 file changed, 11 insertions(+)

diff --git a/drivers/gpio/gpio-aspeed.c b/drivers/gpio/gpio-aspeed.c
index dc53b2decb66..2482f2ff735d 100644
--- a/drivers/gpio/gpio-aspeed.c
+++ b/drivers/gpio/gpio-aspeed.c
@@ -1041,6 +1041,17 @@ static void aspeed_g4_reg_bit_set(struct aspeed_gpio *gpio, unsigned int offset,
void __iomem *addr = aspeed_gpio_g4_bank_reg(gpio, bank, reg);
u32 temp;

+ /*
+ * The interrupt status register is write-1-to-clear. Write only this
+ * line's bit so that interrupts pending on the other lines of the bank
+ * stay latched.
+ */
+ if (reg == reg_irq_status) {
+ if (val)
+ iowrite32(GPIO_BIT(offset), addr);
+ return;
+ }
+
if (reg == reg_val)
temp = gpio->dcache[GPIO_BANK(offset)];
else

--
2.34.1