示例#1
0
int mcp2210_irq_probe(struct mcp2210_device *dev)
{
    uint i;
    mutex_init(&dev->irq_lock);

    dev->nr_irqs = 0;
    for (i = 0; i < 9; ++i) {
        struct mcp2210_pin_config *pin = &dev->config->pins[i];

        if (!pin->has_irq)
            continue;

        switch (pin->mode) {
        case MCP2210_PIN_DEDICATED:
            if (i != 6)
                return -EINVAL;

            dev->s.poll_intr = 1;
            break;

        case MCP2210_PIN_GPIO:
            dev->s.poll_gpio = 1;
            break;
        };

        if (pin->irq + 1> dev->nr_irqs)
            dev->nr_irqs = pin->irq + 1;
    }

    BUG_ON(dev->nr_irqs > 7);


#ifdef CONFIG_MCP2210_GPIO
    if (dev->s.poll_gpio) {
        ctl_cmd_init(dev, &dev->cmd_poll_gpio,
                     MCP2210_CMD_GET_PIN_VALUE, 0, NULL, 0, false);
        dev->cmd_poll_gpio.head.complete = complete_poll;
        mcp2210_add_cmd(&dev->cmd_poll_gpio.head, false);
    }
#endif /* CONFIG_MCP2210_GPIO */

    if (dev->s.poll_intr) {
        ctl_cmd_init(dev, &dev->cmd_poll_intr,
                     MCP2210_CMD_GET_INTERRUPTS, 0, NULL, 0, false);
        dev->cmd_poll_intr.head.complete = complete_poll;
        mcp2210_add_cmd(&dev->cmd_poll_intr.head, false);
    }

    return 0;
}
示例#2
0
/******************************************************************************
 * probe & remove
 */
int mcp2210_irq_probe(struct mcp2210_device *dev)
{
	uint i;
	int ret;

	mcp2210_info();
	mutex_init(&dev->irq_lock);

	dev->nr_irqs = 0;
	dev->poll_intr = 0;
	dev->poll_gpio = 0;

	for (i = 0; i < MCP2210_NUM_PINS; ++i) {
		const struct mcp2210_pin_config *pin = &dev->config->pins[i];

		if (pin->mode == MCP2210_PIN_SPI || !pin->has_irq)
			continue;

		++dev->nr_irqs;
		BUG_ON(dev->irq_revmap[i]);
		dev->irq_revmap[i] = pin->irq;

		if (pin->mode == MCP2210_PIN_DEDICATED)
			dev->poll_intr = 1;
		else if (pin->mode == MCP2210_PIN_GPIO) {
			dev->poll_gpio = 1;
			dev->irq_type[i] = pin->irq_type;
		}
	}

	if (!dev->nr_irqs)
		return 0;

	ret = irq_alloc_descs(-1, 0, dev->nr_irqs, 0);
	if (ret < 0) {
		/* CONFIG_SPARSE_IRQ needed? */
		mcp2210_err("Failed to allocate %u irq descriptors: %d", dev->nr_irqs, ret);
		return ret;
	}
	dev->irq_base = ret;

	for (i = 0; i < dev->nr_irqs; ++i) {
		int virq = dev->irq_base + i;

		dev->irq_descs[i] = irq_to_desc(virq);
		BUG_ON(!dev->irq_descs[i]);
		irq_set_chip_data(virq, dev);
		irq_set_chip(virq, &mcp2210_irq_chip);

#if defined(CONFIG_ARM) && LINUX_VERSION_CODE < KERNEL_VERSION(4,3,0)
		set_irq_flags(virq, 0);
#else
		irq_set_noprobe(virq);
#endif
	}

#ifdef CONFIG_MCP2210_GPIO
	if (dev->poll_gpio) {
		ctl_cmd_init(dev, &dev->cmd_poll_gpio,
			     MCP2210_CMD_GET_PIN_VALUE, 0, NULL, 0, false);
		dev->cmd_poll_gpio.head.complete = complete_poll;
		mcp2210_add_cmd(&dev->cmd_poll_gpio.head, false);
	}
#endif /* CONFIG_MCP2210_GPIO */

	if (dev->poll_intr) {
		/* read and then reset */
		ctl_cmd_init(dev, &dev->cmd_poll_intr,
			     MCP2210_CMD_GET_INTERRUPTS, 0, NULL, 0, false);
		dev->cmd_poll_intr.head.complete = complete_poll;
		mcp2210_add_cmd(&dev->cmd_poll_intr.head, false);
	}

	dev->is_irq_probed = 1;
	dev->suppress_poll_warn = 0;

	return 0;
}