Ben found the root cause. Commit 37f02195bee9c25ce44e25204f40b7961a6d7c9d
("powerpc/pci: fix PCI-e devices rescan issue on powerpc platform")
overwrites the IOMMU table of PCI device while enabling PCI device.
The patch intends to fix the IOMMU table after that point.

Signed-off-by: Gavin Shan <sha...@linux.vnet.ibm.com>
---
 arch/powerpc/platforms/powernv/pci-ioda.c |   33 ++++++++++------------------
 1 files changed, 12 insertions(+), 21 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c 
b/arch/powerpc/platforms/powernv/pci-ioda.c
index 04a37dc..8c6c9cf 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -434,20 +434,21 @@ static void pnv_pci_ioda_setup_PEs(void)
        }
 }
 
-static void pnv_pci_ioda_dma_dev_setup(struct pnv_phb *phb, struct pci_dev 
*dev)
+static void pnv_pci_ioda_dma_dev_setup(struct pnv_phb *phb, struct pci_dev 
*pdev)
 {
-       /* We delay DMA setup after we have assigned all PE# */
-}
+       struct pci_dn *pdn = pnv_ioda_get_pdn(pdev);
+       struct pnv_ioda_pe *pe;
 
-static void pnv_ioda_setup_bus_dma(struct pnv_ioda_pe *pe, struct pci_bus *bus)
-{
-       struct pci_dev *dev;
+       /*
+        * The function can be called while the PE#
+        * hasn't been assigned. Do nothing for the
+        * case.
+        */
+       if (!pdn || pdn->pe_number == IODA_INVALID_PE)
+               return;
 
-       list_for_each_entry(dev, &bus->devices, bus_list) {
-               set_iommu_table_base(&dev->dev, &pe->tce32_table);
-               if (dev->subordinate)
-                       pnv_ioda_setup_bus_dma(pe, dev->subordinate);
-       }
+       pe = &phb->ioda.pe_array[pdn->pe_number];
+       set_iommu_table_base(&pdev->dev, &pe->tce32_table);
 }
 
 static void pnv_pci_ioda1_tce_invalidate(struct iommu_table *tbl,
@@ -605,11 +606,6 @@ static void pnv_pci_ioda_setup_dma_pe(struct pnv_phb *phb,
        }
        iommu_init_table(tbl, phb->hose->node);
 
-       if (pe->pdev)
-               set_iommu_table_base(&pe->pdev->dev, tbl);
-       else
-               pnv_ioda_setup_bus_dma(pe, pe->pbus);
-
        return;
  fail:
        /* XXX Failure: Try to fallback to 64-bit only ? */
@@ -681,11 +677,6 @@ static void pnv_pci_ioda2_setup_dma_pe(struct pnv_phb *phb,
        }
        iommu_init_table(tbl, phb->hose->node);
 
-       if (pe->pdev)
-               set_iommu_table_base(&pe->pdev->dev, tbl);
-       else
-               pnv_ioda_setup_bus_dma(pe, pe->pbus);
-
        return;
 fail:
        if (pe->tce32_seg >= 0)
-- 
1.7.5.4

_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Reply via email to