diff options
author | Gavin Shan <shangw@linux.vnet.ibm.com> | 2013-04-25 15:21:02 -0400 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2013-04-26 02:10:00 -0400 |
commit | 959c9bdd5828981d3d226873aba930019798fa65 (patch) | |
tree | 944f6ccb4e992c2a700653cd9271cfde4642372f /arch/powerpc/platforms | |
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')
-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) | |||
434 | } | 434 | } |
435 | } | 435 | } |
436 | 436 | ||
437 | static void pnv_pci_ioda_dma_dev_setup(struct pnv_phb *phb, struct pci_dev *dev) | 437 | static 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 | ||
442 | static 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 | ||
453 | static void pnv_pci_ioda1_tce_invalidate(struct iommu_table *tbl, | 454 | 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, | |||
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; |
690 | fail: | 681 | fail: |
691 | if (pe->tce32_seg >= 0) | 682 | if (pe->tce32_seg >= 0) |