static int __init mmp2_mux_of_init()

in irq-mmp.c [482:549]


static int __init mmp2_mux_of_init(struct device_node *node,
				   struct device_node *parent)
{
	int i, ret, irq, j = 0;
	u32 nr_irqs, mfp_irq;
	u32 reg[4];

	if (!parent)
		return -ENODEV;

	i = max_icu_nr;
	ret = of_property_read_u32(node, "mrvl,intc-nr-irqs",
				   &nr_irqs);
	if (ret) {
		pr_err("Not found mrvl,intc-nr-irqs property\n");
		return -EINVAL;
	}

	/*
	 * For historical reasons, the "regs" property of the
	 * mrvl,mmp2-mux-intc is not a regular "regs" property containing
	 * addresses on the parent bus, but offsets from the intc's base.
	 * That is why we can't use of_address_to_resource() here.
	 */
	ret = of_property_read_variable_u32_array(node, "reg", reg,
						  ARRAY_SIZE(reg),
						  ARRAY_SIZE(reg));
	if (ret < 0) {
		pr_err("Not found reg property\n");
		return -EINVAL;
	}
	icu_data[i].reg_status = mmp_icu_base + reg[0];
	icu_data[i].reg_mask = mmp_icu_base + reg[2];
	icu_data[i].cascade_irq = irq_of_parse_and_map(node, 0);
	if (!icu_data[i].cascade_irq)
		return -EINVAL;

	icu_data[i].virq_base = 0;
	icu_data[i].domain = irq_domain_add_linear(node, nr_irqs,
						   &mmp_irq_domain_ops,
						   &icu_data[i]);
	for (irq = 0; irq < nr_irqs; irq++) {
		ret = irq_create_mapping(icu_data[i].domain, irq);
		if (!ret) {
			pr_err("Failed to mapping hwirq\n");
			goto err;
		}
		if (!irq)
			icu_data[i].virq_base = ret;
	}
	icu_data[i].nr_irqs = nr_irqs;
	if (!of_property_read_u32(node, "mrvl,clr-mfp-irq",
				  &mfp_irq)) {
		icu_data[i].clr_mfp_irq_base = icu_data[i].virq_base;
		icu_data[i].clr_mfp_hwirq = mfp_irq;
	}
	irq_set_chained_handler(icu_data[i].cascade_irq,
				icu_mux_irq_demux);
	max_icu_nr++;
	return 0;
err:
	if (icu_data[i].virq_base) {
		for (j = 0; j < irq; j++)
			irq_dispose_mapping(icu_data[i].virq_base + j);
	}
	irq_domain_remove(icu_data[i].domain);
	return -EINVAL;
}