summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexey Charkov <alchark@gmail.com>2025-05-06 16:46:18 +0400
committerThomas Gleixner <tglx@linutronix.de>2025-05-06 15:58:27 +0200
commit99ad153fbd22fcf7c2bdd774d08fc4bf70029fa6 (patch)
tree603f1c5f98eb834d617015f5c32594da2f41f77f
parent49f92d3859cdd8534a1cd15037f950c483a5de40 (diff)
irqchip/irq-vt8500: Use fewer global variables and add error handling
Controller private data doesn't really need to be in a global statically allocated array - kzalloc it per controller instead, keeping only one pointer to the primary controller global. While at that, also add proper error return statuses in the init path and respective cleanup of resources on errors. Signed-off-by: Alexey Charkov <alchark@gmail.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Link: https://lore.kernel.org/all/20250506-vt8500-intc-updates-v2-5-a3a0606cf92d@gmail.com
-rw-r--r--drivers/irqchip/irq-vt8500.c48
1 files changed, 25 insertions, 23 deletions
diff --git a/drivers/irqchip/irq-vt8500.c b/drivers/irqchip/irq-vt8500.c
index 15134cb2fbe5..40c2cff0df11 100644
--- a/drivers/irqchip/irq-vt8500.c
+++ b/drivers/irqchip/irq-vt8500.c
@@ -64,9 +64,6 @@ struct vt8500_irq_data {
struct irq_domain *domain; /* Domain for this controller */
};
-/* Global variable for accessing io-mem addresses */
-static struct vt8500_irq_data intc[VT8500_INTC_MAX];
-static u32 active_cnt = 0;
/* Primary interrupt controller data */
static struct vt8500_irq_data *primary_intc;
@@ -203,49 +200,54 @@ static void vt8500_handle_irq_chained(struct irq_desc *desc)
static int __init vt8500_irq_init(struct device_node *node,
struct device_node *parent)
{
- int irq, i;
+ struct vt8500_irq_data *intc;
+ int irq, i, ret = 0;
- if (active_cnt == VT8500_INTC_MAX) {
- pr_err("%s: Interrupt controllers > VT8500_INTC_MAX\n",
- __func__);
- goto out;
- }
-
- intc[active_cnt].base = of_iomap(node, 0);
- intc[active_cnt].domain = irq_domain_add_linear(node, 64,
- &vt8500_irq_domain_ops, &intc[active_cnt]);
+ intc = kzalloc(sizeof(*intc), GFP_KERNEL);
+ if (!intc)
+ return -ENOMEM;
- if (!intc[active_cnt].base) {
+ intc->base = of_iomap(node, 0);
+ if (!intc->base) {
pr_err("%s: Unable to map IO memory\n", __func__);
- goto out;
+ ret = -ENOMEM;
+ goto err_free;
}
- if (!intc[active_cnt].domain) {
+ intc->domain = irq_domain_add_linear(node,
+ 64,
+ &vt8500_irq_domain_ops,
+ intc);
+ if (!intc->domain) {
pr_err("%s: Unable to add irq domain!\n", __func__);
- goto out;
+ ret = -ENOMEM;
+ goto err_unmap;
}
- vt8500_init_irq_hw(intc[active_cnt].base);
+ vt8500_init_irq_hw(intc->base);
pr_info("vt8500-irq: Added interrupt controller\n");
- active_cnt++;
-
/* check if this is a chained controller */
if (of_irq_count(node) != 0) {
for (i = 0; i < of_irq_count(node); i++) {
irq = irq_of_parse_and_map(node, i);
irq_set_chained_handler_and_data(irq, vt8500_handle_irq_chained,
- &intc[active_cnt]);
+ intc);
}
pr_info("vt8500-irq: Enabled slave->parent interrupts\n");
} else {
- primary_intc = &intc[active_cnt];
+ primary_intc = intc;
set_handle_irq(vt8500_handle_irq);
}
-out:
return 0;
+
+err_unmap:
+ iounmap(intc->base);
+err_free:
+ kfree(intc);
+ return ret;
}
IRQCHIP_DECLARE(vt8500_irq, "via,vt8500-intc", vt8500_irq_init);