Commit a71b9412 authored by Thomas Petazzoni's avatar Thomas Petazzoni Committed by Jason Cooper

irqchip/armada-370-xp: Allow allocation of multiple MSIs

Add support for allocating multiple MSIs at the same time, so that the
MSI_FLAG_MULTI_PCI_MSI flag can be added to the msi_domain_info
structure.
Signed-off-by: default avatarThomas Petazzoni <thomas.petazzoni@free-electrons.com>
Reviewed-by: default avatarGregory CLEMENT <gregory.clement@free-electrons.com>
Link: https://lkml.kernel.org/r/1455115621-22846-6-git-send-email-thomas.petazzoni@free-electrons.comSigned-off-by: default avatarJason Cooper <jason@lakedaemon.net>
parent f692a172
...@@ -123,7 +123,8 @@ static struct irq_chip armada_370_xp_msi_irq_chip = { ...@@ -123,7 +123,8 @@ static struct irq_chip armada_370_xp_msi_irq_chip = {
}; };
static struct msi_domain_info armada_370_xp_msi_domain_info = { static struct msi_domain_info armada_370_xp_msi_domain_info = {
.flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS), .flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
MSI_FLAG_MULTI_PCI_MSI),
.chip = &armada_370_xp_msi_irq_chip, .chip = &armada_370_xp_msi_irq_chip,
}; };
...@@ -149,21 +150,26 @@ static struct irq_chip armada_370_xp_msi_bottom_irq_chip = { ...@@ -149,21 +150,26 @@ static struct irq_chip armada_370_xp_msi_bottom_irq_chip = {
static int armada_370_xp_msi_alloc(struct irq_domain *domain, unsigned int virq, static int armada_370_xp_msi_alloc(struct irq_domain *domain, unsigned int virq,
unsigned int nr_irqs, void *args) unsigned int nr_irqs, void *args)
{ {
int hwirq; int hwirq, i;
mutex_lock(&msi_used_lock); mutex_lock(&msi_used_lock);
hwirq = find_first_zero_bit(&msi_used, PCI_MSI_DOORBELL_NR);
hwirq = bitmap_find_next_zero_area(msi_used, PCI_MSI_DOORBELL_NR,
0, nr_irqs, 0);
if (hwirq >= PCI_MSI_DOORBELL_NR) { if (hwirq >= PCI_MSI_DOORBELL_NR) {
mutex_unlock(&msi_used_lock); mutex_unlock(&msi_used_lock);
return -ENOSPC; return -ENOSPC;
} }
set_bit(hwirq, msi_used); bitmap_set(msi_used, hwirq, nr_irqs);
mutex_unlock(&msi_used_lock); mutex_unlock(&msi_used_lock);
irq_domain_set_info(domain, virq, hwirq, &armada_370_xp_msi_bottom_irq_chip, for (i = 0; i < nr_irqs; i++) {
domain->host_data, handle_simple_irq, irq_domain_set_info(domain, virq + i, hwirq + i,
NULL, NULL); &armada_370_xp_msi_bottom_irq_chip,
domain->host_data, handle_simple_irq,
NULL, NULL);
}
return hwirq; return hwirq;
} }
...@@ -174,10 +180,7 @@ static void armada_370_xp_msi_free(struct irq_domain *domain, ...@@ -174,10 +180,7 @@ static void armada_370_xp_msi_free(struct irq_domain *domain,
struct irq_data *d = irq_domain_get_irq_data(domain, virq); struct irq_data *d = irq_domain_get_irq_data(domain, virq);
mutex_lock(&msi_used_lock); mutex_lock(&msi_used_lock);
if (!test_bit(d->hwirq, msi_used)) bitmap_clear(msi_used, d->hwirq, nr_irqs);
pr_err("trying to free unused MSI#%lu\n", d->hwirq);
else
clear_bit(d->hwirq, msi_used);
mutex_unlock(&msi_used_lock); mutex_unlock(&msi_used_lock);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment