in irq-mchp-eic.c [202:272]
static int mchp_eic_init(struct device_node *node, struct device_node *parent)
{
struct irq_domain *parent_domain = NULL;
int ret, i;
eic = kzalloc(sizeof(*eic), GFP_KERNEL);
if (!eic)
return -ENOMEM;
eic->base = of_iomap(node, 0);
if (!eic->base) {
ret = -ENOMEM;
goto free;
}
parent_domain = irq_find_host(parent);
if (!parent_domain) {
ret = -ENODEV;
goto unmap;
}
eic->clk = of_clk_get_by_name(node, "pclk");
if (IS_ERR(eic->clk)) {
ret = PTR_ERR(eic->clk);
goto unmap;
}
ret = clk_prepare_enable(eic->clk);
if (ret)
goto unmap;
for (i = 0; i < MCHP_EIC_NIRQ; i++) {
struct of_phandle_args irq;
/* Disable it, if any. */
writel_relaxed(0UL, eic->base + MCHP_EIC_SCFG(i));
ret = of_irq_parse_one(node, i, &irq);
if (ret)
goto clk_unprepare;
if (WARN_ON(irq.args_count != 3)) {
ret = -EINVAL;
goto clk_unprepare;
}
eic->irqs[i] = irq.args[1];
}
eic->domain = irq_domain_add_hierarchy(parent_domain, 0, MCHP_EIC_NIRQ,
node, &mchp_eic_domain_ops, eic);
if (!eic->domain) {
pr_err("%pOF: Failed to add domain\n", node);
ret = -ENODEV;
goto clk_unprepare;
}
register_syscore_ops(&mchp_eic_syscore_ops);
pr_info("%pOF: EIC registered, nr_irqs %u\n", node, MCHP_EIC_NIRQ);
return 0;
clk_unprepare:
clk_disable_unprepare(eic->clk);
unmap:
iounmap(eic->base);
free:
kfree(eic);
return ret;
}