Commit 19a41f99 authored by Bjorn Helgaas's avatar Bjorn Helgaas
Browse files

Merge branch 'remotes/lorenzo/pci/iproc'

- Fix multi-MSI base vector number allocation (Sandor Bodo-Merle)

- Restrict multi-MSI support to uniprocessor kernel (Sandor Bodo-Merle)

* remotes/lorenzo/pci/iproc:
  PCI: iproc: Support multi-MSI only on uniprocessor kernel
  PCI: iproc: Fix multi-MSI base vector number allocation
parents 02722a84 2dc0a201
Loading
Loading
Loading
Loading
+18 −11
Original line number Diff line number Diff line
@@ -171,7 +171,7 @@ static struct irq_chip iproc_msi_irq_chip = {

static struct msi_domain_info iproc_msi_domain_info = {
	.flags = MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
		MSI_FLAG_MULTI_PCI_MSI | MSI_FLAG_PCI_MSIX,
		MSI_FLAG_PCI_MSIX,
	.chip = &iproc_msi_irq_chip,
};

@@ -250,20 +250,23 @@ static int iproc_msi_irq_domain_alloc(struct irq_domain *domain,
	struct iproc_msi *msi = domain->host_data;
	int hwirq, i;

	if (msi->nr_cpus > 1 && nr_irqs > 1)
		return -EINVAL;

	mutex_lock(&msi->bitmap_lock);

	/* Allocate 'nr_cpus' number of MSI vectors each time */
	hwirq = bitmap_find_next_zero_area(msi->bitmap, msi->nr_msi_vecs, 0,
					   msi->nr_cpus, 0);
	if (hwirq < msi->nr_msi_vecs) {
		bitmap_set(msi->bitmap, hwirq, msi->nr_cpus);
	} else {
		mutex_unlock(&msi->bitmap_lock);
		return -ENOSPC;
	}
	/*
	 * Allocate 'nr_irqs' multiplied by 'nr_cpus' number of MSI vectors
	 * each time
	 */
	hwirq = bitmap_find_free_region(msi->bitmap, msi->nr_msi_vecs,
					order_base_2(msi->nr_cpus * nr_irqs));

	mutex_unlock(&msi->bitmap_lock);

	if (hwirq < 0)
		return -ENOSPC;

	for (i = 0; i < nr_irqs; i++) {
		irq_domain_set_info(domain, virq + i, hwirq + i,
				    &iproc_msi_bottom_irq_chip,
@@ -284,7 +287,8 @@ static void iproc_msi_irq_domain_free(struct irq_domain *domain,
	mutex_lock(&msi->bitmap_lock);

	hwirq = hwirq_to_canonical_hwirq(msi, data->hwirq);
	bitmap_clear(msi->bitmap, hwirq, msi->nr_cpus);
	bitmap_release_region(msi->bitmap, hwirq,
			      order_base_2(msi->nr_cpus * nr_irqs));

	mutex_unlock(&msi->bitmap_lock);

@@ -539,6 +543,9 @@ int iproc_msi_init(struct iproc_pcie *pcie, struct device_node *node)
	mutex_init(&msi->bitmap_lock);
	msi->nr_cpus = num_possible_cpus();

	if (msi->nr_cpus == 1)
		iproc_msi_domain_info.flags |=  MSI_FLAG_MULTI_PCI_MSI;

	msi->nr_irqs = of_irq_count(node);
	if (!msi->nr_irqs) {
		dev_err(pcie->dev, "found no MSI GIC interrupt\n");