lkml.org 
[lkml]   [2022]   [Apr]   [14]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.4 385/475] PCI: aardvark: Fix support for MSI interrupts
    Date
    From: Pali Rohár <pali@kernel.org>

    [ Upstream commit b0b0b8b897f8e12b2368e868bd7cdc5742d5c5a9 ]

    Aardvark hardware supports Multi-MSI and MSI_FLAG_MULTI_PCI_MSI is already
    set for the MSI chip. But when allocating MSI interrupt numbers for
    Multi-MSI, the numbers need to be properly aligned, otherwise endpoint
    devices send MSI interrupt with incorrect numbers.

    Fix this issue by using function bitmap_find_free_region() instead of
    bitmap_find_next_zero_area().

    To ensure that aligned MSI interrupt numbers are used by endpoint devices,
    we cannot use Linux virtual irq numbers (as they are random and not
    properly aligned). Instead we need to use the aligned hwirq numbers.

    This change fixes receiving MSI interrupts on Armada 3720 boards and
    allows using NVMe disks which use Multi-MSI feature with 3 interrupts.

    Without this NVMe disks freeze booting as linux nvme-core.c is waiting
    60s for an interrupt.

    Link: https://lore.kernel.org/r/20220110015018.26359-4-kabel@kernel.org
    Signed-off-by: Pali Rohár <pali@kernel.org>
    Signed-off-by: Marek Behún <kabel@kernel.org>
    Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/pci/controller/pci-aardvark.c | 16 ++++++----------
    1 file changed, 6 insertions(+), 10 deletions(-)

    diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c
    index 5958316651e4..721d2652319c 100644
    --- a/drivers/pci/controller/pci-aardvark.c
    +++ b/drivers/pci/controller/pci-aardvark.c
    @@ -1170,7 +1170,7 @@ static void advk_msi_irq_compose_msi_msg(struct irq_data *data,

    msg->address_lo = lower_32_bits(msi_msg);
    msg->address_hi = upper_32_bits(msi_msg);
    - msg->data = data->irq;
    + msg->data = data->hwirq;
    }

    static int advk_msi_set_affinity(struct irq_data *irq_data,
    @@ -1187,15 +1187,11 @@ static int advk_msi_irq_domain_alloc(struct irq_domain *domain,
    int hwirq, i;

    mutex_lock(&pcie->msi_used_lock);
    - hwirq = bitmap_find_next_zero_area(pcie->msi_used, MSI_IRQ_NUM,
    - 0, nr_irqs, 0);
    - if (hwirq >= MSI_IRQ_NUM) {
    - mutex_unlock(&pcie->msi_used_lock);
    - return -ENOSPC;
    - }
    -
    - bitmap_set(pcie->msi_used, hwirq, nr_irqs);
    + hwirq = bitmap_find_free_region(pcie->msi_used, MSI_IRQ_NUM,
    + order_base_2(nr_irqs));
    mutex_unlock(&pcie->msi_used_lock);
    + if (hwirq < 0)
    + return -ENOSPC;

    for (i = 0; i < nr_irqs; i++)
    irq_domain_set_info(domain, virq + i, hwirq + i,
    @@ -1213,7 +1209,7 @@ static void advk_msi_irq_domain_free(struct irq_domain *domain,
    struct advk_pcie *pcie = domain->host_data;

    mutex_lock(&pcie->msi_used_lock);
    - bitmap_clear(pcie->msi_used, d->hwirq, nr_irqs);
    + bitmap_release_region(pcie->msi_used, d->hwirq, order_base_2(nr_irqs));
    mutex_unlock(&pcie->msi_used_lock);
    }

    --
    2.35.1


    \
     
     \ /
      Last update: 2022-04-14 17:25    [W:4.327 / U:0.580 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site