static int sprd_eic_probe()

in gpio-eic-sprd.c [567:653]


static int sprd_eic_probe(struct platform_device *pdev)
{
	const struct sprd_eic_variant_data *pdata;
	struct gpio_irq_chip *irq;
	struct sprd_eic *sprd_eic;
	struct resource *res;
	int ret, i;

	pdata = of_device_get_match_data(&pdev->dev);
	if (!pdata) {
		dev_err(&pdev->dev, "No matching driver data found.\n");
		return -EINVAL;
	}

	sprd_eic = devm_kzalloc(&pdev->dev, sizeof(*sprd_eic), GFP_KERNEL);
	if (!sprd_eic)
		return -ENOMEM;

	spin_lock_init(&sprd_eic->lock);
	sprd_eic->type = pdata->type;

	sprd_eic->irq = platform_get_irq(pdev, 0);
	if (sprd_eic->irq < 0)
		return sprd_eic->irq;

	for (i = 0; i < SPRD_EIC_MAX_BANK; i++) {
		/*
		 * We can have maximum 3 banks EICs, and each EIC has
		 * its own base address. But some platform maybe only
		 * have one bank EIC, thus base[1] and base[2] can be
		 * optional.
		 */
		res = platform_get_resource(pdev, IORESOURCE_MEM, i);
		if (!res)
			break;

		sprd_eic->base[i] = devm_ioremap_resource(&pdev->dev, res);
		if (IS_ERR(sprd_eic->base[i]))
			return PTR_ERR(sprd_eic->base[i]);
	}

	sprd_eic->chip.label = sprd_eic_label_name[sprd_eic->type];
	sprd_eic->chip.ngpio = pdata->num_eics;
	sprd_eic->chip.base = -1;
	sprd_eic->chip.parent = &pdev->dev;
	sprd_eic->chip.direction_input = sprd_eic_direction_input;
	switch (sprd_eic->type) {
	case SPRD_EIC_DEBOUNCE:
		sprd_eic->chip.request = sprd_eic_request;
		sprd_eic->chip.free = sprd_eic_free;
		sprd_eic->chip.set_config = sprd_eic_set_config;
		sprd_eic->chip.set = sprd_eic_set;
		fallthrough;
	case SPRD_EIC_ASYNC:
	case SPRD_EIC_SYNC:
		sprd_eic->chip.get = sprd_eic_get;
		break;
	case SPRD_EIC_LATCH:
	default:
		break;
	}

	sprd_eic->intc.name = dev_name(&pdev->dev);
	sprd_eic->intc.irq_ack = sprd_eic_irq_ack;
	sprd_eic->intc.irq_mask = sprd_eic_irq_mask;
	sprd_eic->intc.irq_unmask = sprd_eic_irq_unmask;
	sprd_eic->intc.irq_set_type = sprd_eic_irq_set_type;
	sprd_eic->intc.flags = IRQCHIP_SKIP_SET_WAKE;

	irq = &sprd_eic->chip.irq;
	irq->chip = &sprd_eic->intc;
	irq->handler = handle_bad_irq;
	irq->default_type = IRQ_TYPE_NONE;
	irq->parent_handler = sprd_eic_irq_handler;
	irq->parent_handler_data = sprd_eic;
	irq->num_parents = 1;
	irq->parents = &sprd_eic->irq;

	ret = devm_gpiochip_add_data(&pdev->dev, &sprd_eic->chip, sprd_eic);
	if (ret < 0) {
		dev_err(&pdev->dev, "Could not register gpiochip %d.\n", ret);
		return ret;
	}

	platform_set_drvdata(pdev, sprd_eic);
	return 0;
}