static int ti_sci_inta_irq_domain_probe()

in irq-ti-sci-inta.c [647:727]


static int ti_sci_inta_irq_domain_probe(struct platform_device *pdev)
{
	struct irq_domain *parent_domain, *domain, *msi_domain;
	struct device_node *parent_node, *node;
	struct ti_sci_inta_irq_domain *inta;
	struct device *dev = &pdev->dev;
	int ret;

	node = dev_of_node(dev);
	parent_node = of_irq_find_parent(node);
	if (!parent_node) {
		dev_err(dev, "Failed to get IRQ parent node\n");
		return -ENODEV;
	}

	parent_domain = irq_find_host(parent_node);
	if (!parent_domain)
		return -EPROBE_DEFER;

	inta = devm_kzalloc(dev, sizeof(*inta), GFP_KERNEL);
	if (!inta)
		return -ENOMEM;

	inta->pdev = pdev;
	inta->sci = devm_ti_sci_get_by_phandle(dev, "ti,sci");
	if (IS_ERR(inta->sci))
		return dev_err_probe(dev, PTR_ERR(inta->sci),
				     "ti,sci read fail\n");

	ret = of_property_read_u32(dev->of_node, "ti,sci-dev-id", &inta->ti_sci_id);
	if (ret) {
		dev_err(dev, "missing 'ti,sci-dev-id' property\n");
		return -EINVAL;
	}

	inta->vint = devm_ti_sci_get_resource(inta->sci, dev, inta->ti_sci_id,
					      TI_SCI_RESASG_SUBTYPE_IA_VINT);
	if (IS_ERR(inta->vint)) {
		dev_err(dev, "VINT resource allocation failed\n");
		return PTR_ERR(inta->vint);
	}

	inta->global_event = devm_ti_sci_get_resource(inta->sci, dev, inta->ti_sci_id,
						      TI_SCI_RESASG_SUBTYPE_GLOBAL_EVENT_SEVT);
	if (IS_ERR(inta->global_event)) {
		dev_err(dev, "Global event resource allocation failed\n");
		return PTR_ERR(inta->global_event);
	}

	inta->base = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(inta->base))
		return PTR_ERR(inta->base);

	ret = ti_sci_inta_get_unmapped_sources(inta);
	if (ret)
		return ret;

	domain = irq_domain_add_linear(dev_of_node(dev),
				       ti_sci_get_num_resources(inta->vint),
				       &ti_sci_inta_irq_domain_ops, inta);
	if (!domain) {
		dev_err(dev, "Failed to allocate IRQ domain\n");
		return -ENOMEM;
	}

	msi_domain = ti_sci_inta_msi_create_irq_domain(of_node_to_fwnode(node),
						&ti_sci_inta_msi_domain_info,
						domain);
	if (!msi_domain) {
		irq_domain_remove(domain);
		dev_err(dev, "Failed to allocate msi domain\n");
		return -ENOMEM;
	}

	INIT_LIST_HEAD(&inta->vint_list);
	mutex_init(&inta->vint_mutex);

	dev_info(dev, "Interrupt Aggregator domain %d created\n", inta->ti_sci_id);

	return 0;
}