From 3798abbc26fe7ac7da5cf5253d964d299b48d300 Mon Sep 17 00:00:00 2001 From: Markus Fritsche Date: Thu, 16 Apr 2026 23:53:01 +0200 Subject: [PATCH 1/9] gpio: rockchip: propagate irq_set_wake to parent GIC MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Rockchip GPIO irqchip uses irq_gc_set_wake() which only tracks the wake state locally in gc->wake_active. It never calls irq_set_irq_wake() on the parent GIC interrupt for the GPIO bank. During suspend, suspend_device_irqs() disables all non-wakeup IRQs at the GIC level, so GPIO-based wakeup sources (RTC alarm, PMIC power key) can never reach the CPU — the GPIO controller detects the interrupt but the GIC blocks it. Replace irq_gc_set_wake with rockchip_irq_set_wake that propagates the wake setting to the parent bank->irq via irq_set_irq_wake(). On failure, revert the local wake state via irq_gc_set_wake(!on) which handles gc->lock internally. Generated-by: Claude Opus 4.6 Signed-off-by: Markus Fritsche --- drivers/gpio/gpio-rockchip.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/drivers/gpio/gpio-rockchip.c b/drivers/gpio/gpio-rockchip.c index 0fff4a699f12..d3b874251efc 100644 --- a/drivers/gpio/gpio-rockchip.c +++ b/drivers/gpio/gpio-rockchip.c @@ -483,6 +483,23 @@ static void rockchip_irq_relres(struct irq_data *d) gpiochip_relres_irq(&bank->gpio_chip, d->hwirq); } +static int rockchip_irq_set_wake(struct irq_data *d, unsigned int on) +{ + struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); + struct rockchip_pin_bank *bank = gc->private; + int ret; + + ret = irq_gc_set_wake(d, on); + if (ret) + return ret; + + ret = irq_set_irq_wake(bank->irq, on); + if (ret) + irq_gc_set_wake(d, !on); + + return ret; +} + static void rockchip_irq_suspend(struct irq_data *d) { struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); @@ -550,7 +567,7 @@ static int rockchip_interrupts_register(struct rockchip_pin_bank *bank) gc->chip_types[0].chip.irq_unmask = irq_gc_mask_clr_bit; gc->chip_types[0].chip.irq_enable = rockchip_irq_enable; gc->chip_types[0].chip.irq_disable = rockchip_irq_disable; - gc->chip_types[0].chip.irq_set_wake = irq_gc_set_wake; + gc->chip_types[0].chip.irq_set_wake = rockchip_irq_set_wake; gc->chip_types[0].chip.irq_suspend = rockchip_irq_suspend; gc->chip_types[0].chip.irq_resume = rockchip_irq_resume; gc->chip_types[0].chip.irq_set_type = rockchip_irq_set_type; -- 2.54.0