/* * 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; }
/* * 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; }
/* * 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; }
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; }
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; }
/* * 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); } }