diff options
author | Gavin Shan <shangw@linux.vnet.ibm.com> | 2013-04-25 19:21:02 +0000 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2013-04-26 16:10:00 +1000 |
commit | 959c9bdd5828981d3d226873aba930019798fa65 (patch) | |
tree | 944f6ccb4e992c2a700653cd9271cfde4642372f /arch/powerpc/platforms/powernv | |
parent | 373f565741a3636954cd87034d9ebb1dc7bfd716 (diff) |
powerpc/powernv: Fix invalid IOMMU table
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 <shangw@linux.vnet.ibm.com>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/platforms/powernv')
-rw-r--r-- | 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 04a37dc06a77..8c6c9cf91c13 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) |