[PATCH 1/2] gpio: aspeed: Clear only the acked line's G4 interrupt status
Billy Tsai
billy_tsai at aspeedtech.com
Tue Nov 3 19:58:35 PST 2026
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 at vger.kernel.org
Reported-by: Aaron Antone <aae at amazon.com>
Suggested-by: Aaron Antone <aae at amazon.com>
Signed-off-by: Billy Tsai <billy_tsai at aspeedtech.com>
---
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
More information about the linux-arm-kernel
mailing list