int __init mbi_init()

in irq-gic-v3-mbi.c [262:335]


int __init mbi_init(struct fwnode_handle *fwnode, struct irq_domain *parent)
{
	struct device_node *np;
	const __be32 *reg;
	int ret, n;

	np = to_of_node(fwnode);

	if (!of_property_read_bool(np, "msi-controller"))
		return 0;

	n = of_property_count_elems_of_size(np, "mbi-ranges", sizeof(u32));
	if (n <= 0 || n % 2)
		return -EINVAL;

	mbi_range_nr = n / 2;
	mbi_ranges = kcalloc(mbi_range_nr, sizeof(*mbi_ranges), GFP_KERNEL);
	if (!mbi_ranges)
		return -ENOMEM;

	for (n = 0; n < mbi_range_nr; n++) {
		ret = of_property_read_u32_index(np, "mbi-ranges", n * 2,
						 &mbi_ranges[n].spi_start);
		if (ret)
			goto err_free_mbi;
		ret = of_property_read_u32_index(np, "mbi-ranges", n * 2 + 1,
						 &mbi_ranges[n].nr_spis);
		if (ret)
			goto err_free_mbi;

		mbi_ranges[n].bm = bitmap_zalloc(mbi_ranges[n].nr_spis, GFP_KERNEL);
		if (!mbi_ranges[n].bm) {
			ret = -ENOMEM;
			goto err_free_mbi;
		}
		pr_info("MBI range [%d:%d]\n", mbi_ranges[n].spi_start,
			mbi_ranges[n].spi_start + mbi_ranges[n].nr_spis - 1);
	}

	reg = of_get_property(np, "mbi-alias", NULL);
	if (reg) {
		mbi_phys_base = of_translate_address(np, reg);
		if (mbi_phys_base == (phys_addr_t)OF_BAD_ADDR) {
			ret = -ENXIO;
			goto err_free_mbi;
		}
	} else {
		struct resource res;

		if (of_address_to_resource(np, 0, &res)) {
			ret = -ENXIO;
			goto err_free_mbi;
		}

		mbi_phys_base = res.start;
	}

	pr_info("Using MBI frame %pa\n", &mbi_phys_base);

	ret = mbi_allocate_domains(parent);
	if (ret)
		goto err_free_mbi;

	return 0;

err_free_mbi:
	if (mbi_ranges) {
		for (n = 0; n < mbi_range_nr; n++)
			bitmap_free(mbi_ranges[n].bm);
		kfree(mbi_ranges);
	}

	return ret;
}