Example #1
0
/*
 * Dynamic irq allocate and deallocation for MSI
 */
int create_irq(void)
{
	unsigned long flags;
	int irq, vector, cpu;
	cpumask_t domain = CPU_MASK_NONE;

	irq = vector = -ENOSPC;
	spin_lock_irqsave(&vector_lock, flags);
	for_each_online_cpu(cpu) {
		domain = vector_allocation_domain(cpu);
		vector = find_unassigned_vector(domain);
		if (vector >= 0)
			break;
	}
	if (vector < 0)
		goto out;
	irq = find_unassigned_irq();
	if (irq < 0)
		goto out;
	BUG_ON(__bind_irq_vector(irq, vector, domain));
 out:
	spin_unlock_irqrestore(&vector_lock, flags);
	if (irq >= 0)
		dynamic_irq_init(irq);
	return irq;
}
Example #2
0
/*
 * Dynamic irq allocate and deallocation
 */
static int pcie_msi_create_irq(struct pcie_port *pp)
{
	int irq, pos;

	/* Find/alloc a free MSI interrupt */
	spin_lock_irqsave(&pp->conf_lock, pp->flags);
	for (pos = 0; pos < PCIE_PORT_MSI_MAX; pos++) {
		if (pp->msi_irq_base + pos >= NR_IRQS) {
			continue;
		}

		/* Take one slot if available */
		if ((pp->msi_irq_in_use & (1 << pos)) == 0) {
			pp->msi_irq_in_use |= (1 << pos);
			break;
		}
	}
	spin_unlock_irqrestore(&pp->conf_lock, pp->flags);

	if (pos >= PCIE_PORT_MSI_MAX) {
		printk(KERN_WARNING "pos %d too big\n", pos);
		return -ENOSPC;
	}

	irq = pp->msi_irq_base + pos;
	dynamic_irq_init(irq);

	PCIE_INFO("pcie port %d create irq = %d\n", pp->port, irq);
	return irq;
}
Example #3
0
File: msi.c Project: Moretti0/gg
/*
* Dynamic irq allocate and deallocation
*/
int create_irq(void)
{
	int irq, pos;

	do {
		pos = find_first_zero_bit(msi_irq_in_use, IMX_NUM_MSI_IRQS);
		if ((unsigned int)pos >= IMX_NUM_MSI_IRQS)
			return -ENOSPC;
		/* test_and_set_bit operates on 32-bits at a time */
	} while (test_and_set_bit(pos, msi_irq_in_use));

	irq = IRQ_IMX_MSI_0 + pos;
	dynamic_irq_init(irq);
	return irq;
}
Example #4
0
static int msm_pcie_create_irq(void)
{
	int irq, pos;

again:
	pos = find_first_zero_bit(msi_irq_in_use, NR_PCIE_MSI_IRQS);
	irq = MSM_PCIE_MSI_INT(pos);
	if (irq >= (MSM_PCIE_MSI_INT(0) + NR_PCIE_MSI_IRQS))
		return -ENOSPC;

	if (test_and_set_bit(pos, msi_irq_in_use))
		goto again;

	dynamic_irq_init(irq);
	return irq;
}
Example #5
0
int create_irq(void)
{
	unsigned long flags;
	int result;

	spin_lock_irqsave(&available_irqs_lock, flags);
	if (available_irqs == 0)
		result = -ENOMEM;
	else {
		result = __ffs(available_irqs);
		available_irqs &= ~(1UL << result);
		dynamic_irq_init(result);
	}
	spin_unlock_irqrestore(&available_irqs_lock, flags);

	return result;
}
Example #6
0
/*
 * Dynamic irq allocate and deallocation
 */
int create_irq(void)
{
    int irq, pos;

again:
    pos = find_first_zero_bit(msi_irq_in_use, NR_PRIVATE_MSI_IRQS);
    irq = IRQ_AURORA_MSI_START + pos;
    if (irq > NR_IRQS)
        return -ENOSPC;
    /* test_and_set_bit operates on 32-bits at a time */
    if (test_and_set_bit(pos, msi_irq_in_use))
        goto again;

    dynamic_irq_init(irq);

    return irq;
}
/**
 * arch_setup_msi_irq() - Set up an MSI for Endpoint
 * @pdev: Pointer to PCI device structure of requesting EP
 * @desc: Pointer to MSI descriptor data
 *
 * Assigns an MSI to endpoint and sets up corresponding irq. Also passes the MSI
 * information to the endpont.
 */
int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
{
	int ret, irq;
	struct msi_msg msg;

	if (msi_irq < 0) {
		printk(KERN_ERR "PCI: MSI irq pin not specified\n");
		return msi_irq;
	}

	ret = get_free_msi();
	if (ret < 0) {
		printk(KERN_ERR "PCI: Failed to get free MSI\n");
	} else {
		irq = msi_irq_base + ret;
#if defined(MSI_SUPPORT_1_DEV_1_BIT)
		msg.data = ret;
#elif defined(MSI_SUPPORT_1_DEV_32_BIT)
        msg.data = (ret&0x7)<<5;
#endif
		dynamic_irq_init(irq);
		ret = irq_set_msi_desc(irq, desc);

		if (!ret) {
			msg.address_hi = MSI_LOCAL_UPPER_ADDR;
			msg.address_lo = MSI_LOCAL_LOWER_ADDR;
#if defined(MSI_SUPPORT_1_DEV_1_BIT)
			printk(KERN_ERR "PCI:MSI %d @%x:%x, irq = %d\n",
					msg.data, msg.address_hi,
					msg.address_lo, irq);
#elif defined(MSI_SUPPORT_1_DEV_32_BIT)
			printk(KERN_ERR "PCI:MSI#%d[0-31] @%x:%x, irq = %d\n",
					(msg.data>>5)&0x7, msg.address_hi,
					msg.address_lo, irq);
#endif
			write_msi_msg(irq, &msg);
			irq_set_chip_and_handler_name(irq, &balong_msi_chip,
						handle_level_irq,NULL);
			set_irq_flags(irq, IRQF_VALID);
		}
	}