static int pruss_intc_probe()

in irq-pruss-intc.c [517:600]


static int pruss_intc_probe(struct platform_device *pdev)
{
	const struct pruss_intc_match_data *data;
	struct device *dev = &pdev->dev;
	struct pruss_intc *intc;
	struct pruss_host_irq_data *host_data;
	int i, irq, ret;
	u8 max_system_events, irqs_reserved = 0;

	data = of_device_get_match_data(dev);
	if (!data)
		return -ENODEV;

	max_system_events = data->num_system_events;

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

	intc->soc_config = data;
	intc->dev = dev;
	platform_set_drvdata(pdev, intc);

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

	ret = of_property_read_u8(dev->of_node, "ti,irqs-reserved",
				  &irqs_reserved);

	/*
	 * The irqs-reserved is used only for some SoC's therefore not having
	 * this property is still valid
	 */
	if (ret < 0 && ret != -EINVAL)
		return ret;

	pruss_intc_init(intc);

	mutex_init(&intc->lock);

	intc->domain = irq_domain_add_linear(dev->of_node, max_system_events,
					     &pruss_intc_irq_domain_ops, intc);
	if (!intc->domain)
		return -ENOMEM;

	for (i = 0; i < MAX_NUM_HOST_IRQS; i++) {
		if (irqs_reserved & BIT(i))
			continue;

		irq = platform_get_irq_byname(pdev, irq_names[i]);
		if (irq <= 0) {
			ret = (irq == 0) ? -EINVAL : irq;
			goto fail_irq;
		}

		intc->irqs[i] = irq;

		host_data = devm_kzalloc(dev, sizeof(*host_data), GFP_KERNEL);
		if (!host_data) {
			ret = -ENOMEM;
			goto fail_irq;
		}

		host_data->intc = intc;
		host_data->host_irq = i;

		irq_set_handler_data(irq, host_data);
		irq_set_chained_handler(irq, pruss_intc_irq_handler);
	}

	return 0;

fail_irq:
	while (--i >= 0) {
		if (intc->irqs[i])
			irq_set_chained_handler_and_data(intc->irqs[i], NULL,
							 NULL);
	}

	irq_domain_remove(intc->domain);

	return ret;
}