in irq-mvebu-gicp.c [168:248]
static int mvebu_gicp_probe(struct platform_device *pdev)
{
struct mvebu_gicp *gicp;
struct irq_domain *inner_domain, *plat_domain, *parent_domain;
struct device_node *node = pdev->dev.of_node;
struct device_node *irq_parent_dn;
int ret, i;
gicp = devm_kzalloc(&pdev->dev, sizeof(*gicp), GFP_KERNEL);
if (!gicp)
return -ENOMEM;
gicp->dev = &pdev->dev;
spin_lock_init(&gicp->spi_lock);
gicp->res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!gicp->res)
return -ENODEV;
ret = of_property_count_u32_elems(node, "marvell,spi-ranges");
if (ret < 0)
return ret;
gicp->spi_ranges_cnt = ret / 2;
gicp->spi_ranges =
devm_kcalloc(&pdev->dev,
gicp->spi_ranges_cnt,
sizeof(struct mvebu_gicp_spi_range),
GFP_KERNEL);
if (!gicp->spi_ranges)
return -ENOMEM;
for (i = 0; i < gicp->spi_ranges_cnt; i++) {
of_property_read_u32_index(node, "marvell,spi-ranges",
i * 2,
&gicp->spi_ranges[i].start);
of_property_read_u32_index(node, "marvell,spi-ranges",
i * 2 + 1,
&gicp->spi_ranges[i].count);
gicp->spi_cnt += gicp->spi_ranges[i].count;
}
gicp->spi_bitmap = devm_bitmap_zalloc(&pdev->dev, gicp->spi_cnt, GFP_KERNEL);
if (!gicp->spi_bitmap)
return -ENOMEM;
irq_parent_dn = of_irq_find_parent(node);
if (!irq_parent_dn) {
dev_err(&pdev->dev, "failed to find parent IRQ node\n");
return -ENODEV;
}
parent_domain = irq_find_host(irq_parent_dn);
if (!parent_domain) {
dev_err(&pdev->dev, "failed to find parent IRQ domain\n");
return -ENODEV;
}
inner_domain = irq_domain_create_hierarchy(parent_domain, 0,
gicp->spi_cnt,
of_node_to_fwnode(node),
&gicp_domain_ops, gicp);
if (!inner_domain)
return -ENOMEM;
plat_domain = platform_msi_create_irq_domain(of_node_to_fwnode(node),
&gicp_msi_domain_info,
inner_domain);
if (!plat_domain) {
irq_domain_remove(inner_domain);
return -ENOMEM;
}
platform_set_drvdata(pdev, gicp);
return 0;
}