aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms
diff options
context:
space:
mode:
authorGavin Shan <shangw@linux.vnet.ibm.com>2013-04-25 15:21:02 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2013-04-26 02:10:00 -0400
commit959c9bdd5828981d3d226873aba930019798fa65 (patch)
tree944f6ccb4e992c2a700653cd9271cfde4642372f /arch/powerpc/platforms
parent373f565741a3636954cd87034d9ebb1dc7bfd716 (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')
-rw-r--r--arch/powerpc/platforms/powernv/pci-ioda.c33
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)
434 } 434 }
435} 435}
436 436
437static void pnv_pci_ioda_dma_dev_setup(struct pnv_phb *phb, struct pci_dev *dev) 437static void pnv_pci_ioda_dma_dev_setup(struct pnv_phb *phb, struct pci_dev *pdev)
438{ 438{
439 /* We delay DMA setup after we have assigned all PE# */ 439 struct pci_dn *pdn = pnv_ioda_get_pdn(pdev);
440} 440 struct pnv_ioda_pe *pe;
441 441
442static void pnv_ioda_setup_bus_dma(struct pnv_ioda_pe *pe, struct pci_bus *bus) 442 /*
443{ 443 * The function can be called while the PE#
444 struct pci_dev *dev; 444 * hasn't been assigned. Do nothing for the
445 * case.
446 */
447 if (!pdn || pdn->pe_number == IODA_INVALID_PE)
448 return;
445 449
446 list_for_each_entry(dev, &bus->devices, bus_list) { 450 pe = &phb->ioda.pe_array[pdn->pe_number];
447 set_iommu_table_base(&dev->dev, &pe->tce32_table); 451 set_iommu_table_base(&pdev->dev, &pe->tce32_table);
448 if (dev->subordinate)
449 pnv_ioda_setup_bus_dma(pe, dev->subordinate);
450 }
451} 452}
452 453
453static void pnv_pci_ioda1_tce_invalidate(struct iommu_table *tbl, 454static 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,
605 } 606 }
606 iommu_init_table(tbl, phb->hose->node); 607 iommu_init_table(tbl, phb->hose->node);
607 608
608 if (pe->pdev)
609 set_iommu_table_base(&pe->pdev->dev, tbl);
610 else
611 pnv_ioda_setup_bus_dma(pe, pe->pbus);
612
613 return; 609 return;
614 fail: 610 fail:
615 /* XXX Failure: Try to fallback to 64-bit only ? */ 611 /* 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,
681 } 677 }
682 iommu_init_table(tbl, phb->hose->node); 678 iommu_init_table(tbl, phb->hose->node);
683 679
684 if (pe->pdev)
685 set_iommu_table_base(&pe->pdev->dev, tbl);
686 else
687 pnv_ioda_setup_bus_dma(pe, pe->pbus);
688
689 return; 680 return;
690fail: 681fail:
691 if (pe->tce32_seg >= 0) 682 if (pe->tce32_seg >= 0)