[PATCH 10/16] irqchip/aspeed-vic: publish handler only after domain creation
Haofeng Li <[email protected]> Tue, 14 Jul 2026 21:24:46 +0800
| Newsgroups | org.ozlabs.lists.linux-aspeed,org.infradead.lists.linux-arm-kernel,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
From: Haofeng Li <[email protected]> avic_of_init() publishes system_avic and installs the root IRQ handler before creating the IRQ domain, then returns success even if irq_domain_create_simple() fails. Freeing the VIC after the root handler has been installed would leave avic_handle_irq() pointing at a cleared or freed controller. Create the domain first, then publish the controller and install the handler. Also handle set_handle_irq() failure by removing the domain and releasing all resources before the handler has been changed. Fixes: 5952884258e5 ("irqchip/aspeed-vic: Add irq controller for Aspeed") Signed-off-by: Haofeng Li <[email protected]> --- drivers/irqchip/irq-aspeed-vic.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/drivers/irqchip/irq-aspeed-vic.c b/drivers/irqchip/irq-aspeed-vic.c index 6649b893f39c..bb3cceec375f 100644 --- a/drivers/irqchip/irq-aspeed-vic.c +++ b/drivers/irqchip/irq-aspeed-vic.c @@ -186,6 +186,7 @@ static int __init avic_of_init(struct device_node *node, { void __iomem *regs; struct aspeed_vic *vic; + int ret; if (WARN(parent, "non-root Aspeed VIC not supported")) return -EINVAL; @@ -206,15 +207,29 @@ static int __init avic_of_init(struct device_node *node, /* Initialize sources, all masked */ vic_init_hw(vic); - /* Ready to receive interrupts */ - system_avic = vic; - set_handle_irq(avic_handle_irq); - /* Register our domain */ vic->dom = irq_domain_create_simple(of_fwnode_handle(node), NUM_IRQS, 0, &avic_dom_ops, vic); + if (!vic->dom) { + ret = -ENOMEM; + goto err_free_vic; + } + + /* Ready to receive interrupts */ + system_avic = vic; + ret = set_handle_irq(avic_handle_irq); + if (ret) + goto err_remove_domain; return 0; + +err_remove_domain: + system_avic = NULL; + irq_domain_remove(vic->dom); +err_free_vic: + iounmap(regs); + kfree(vic); + return ret; } IRQCHIP_DECLARE(ast2400_vic, "aspeed,ast2400-vic", avic_of_init); -- 2.25.1