static int mchp_eic_init()

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;
}