From: Alan Douglas <adoug...@cadence.com>

[ Upstream commit 0652d4b6b56f73c81abbdbc7e26f772cb2dfe370 ]

The IRQ physical address is allocated from region 0, rather than
the highest region. Update the driver to reserve this region in
the bitmap and to use region 0 for all types of interrupt.

This corrects a problem which prevents the interrupt being
signalled correctly if using the first address in the AXI region,
since an offset of zero will always be mapped to region 0.

Fixes: 37dddf14f1ae ("PCI: cadence: Add EndPoint Controller driver for Cadence 
PCIe controller")
Signed-off-by: Alan Douglas <adoug...@cadence.com>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieral...@arm.com>
Signed-off-by: Sasha Levin <sas...@kernel.org>
---
 drivers/pci/controller/pcie-cadence-ep.c | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/pci/controller/pcie-cadence-ep.c 
b/drivers/pci/controller/pcie-cadence-ep.c
index 9e87dd7f9ac3..6692654798d4 100644
--- a/drivers/pci/controller/pcie-cadence-ep.c
+++ b/drivers/pci/controller/pcie-cadence-ep.c
@@ -258,7 +258,6 @@ static void cdns_pcie_ep_assert_intx(struct cdns_pcie_ep 
*ep, u8 fn,
                                     u8 intx, bool is_asserted)
 {
        struct cdns_pcie *pcie = &ep->pcie;
-       u32 r = ep->max_regions - 1;
        u32 offset;
        u16 status;
        u8 msg_code;
@@ -268,8 +267,8 @@ static void cdns_pcie_ep_assert_intx(struct cdns_pcie_ep 
*ep, u8 fn,
        /* Set the outbound region if needed. */
        if (unlikely(ep->irq_pci_addr != CDNS_PCIE_EP_IRQ_PCI_ADDR_LEGACY ||
                     ep->irq_pci_fn != fn)) {
-               /* Last region was reserved for IRQ writes. */
-               cdns_pcie_set_outbound_region_for_normal_msg(pcie, fn, r,
+               /* First region was reserved for IRQ writes. */
+               cdns_pcie_set_outbound_region_for_normal_msg(pcie, fn, 0,
                                                             ep->irq_phys_addr);
                ep->irq_pci_addr = CDNS_PCIE_EP_IRQ_PCI_ADDR_LEGACY;
                ep->irq_pci_fn = fn;
@@ -347,8 +346,8 @@ static int cdns_pcie_ep_send_msi_irq(struct cdns_pcie_ep 
*ep, u8 fn,
        /* Set the outbound region if needed. */
        if (unlikely(ep->irq_pci_addr != (pci_addr & ~pci_addr_mask) ||
                     ep->irq_pci_fn != fn)) {
-               /* Last region was reserved for IRQ writes. */
-               cdns_pcie_set_outbound_region(pcie, fn, ep->max_regions - 1,
+               /* First region was reserved for IRQ writes. */
+               cdns_pcie_set_outbound_region(pcie, fn, 0,
                                              false,
                                              ep->irq_phys_addr,
                                              pci_addr & ~pci_addr_mask,
@@ -517,6 +516,8 @@ static int cdns_pcie_ep_probe(struct platform_device *pdev)
                goto free_epc_mem;
        }
        ep->irq_pci_addr = CDNS_PCIE_EP_IRQ_PCI_ADDR_NONE;
+       /* Reserve region 0 for IRQs */
+       set_bit(0, &ep->ob_region_map);
 
        return 0;
 
-- 
2.17.1

Reply via email to