aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/pseries/iommu.c
diff options
context:
space:
mode:
authorAlexey Kardashevskiy <aik@ozlabs.ru>2013-11-21 01:43:14 -0500
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2013-12-05 00:08:17 -0500
commitd905c5df9aef38d63df268f6f5e7b13894f626d3 (patch)
tree621cbfdcb57729e5ec60c6ffe19aa670818381b8 /arch/powerpc/platforms/pseries/iommu.c
parent7e1ce5a492e18449fd47ef6305b26e0c572d26e9 (diff)
PPC: POWERNV: move iommu_add_device earlier
The current implementation of IOMMU on sPAPR does not use iommu_ops and therefore does not call IOMMU API's bus_set_iommu() which 1) sets iommu_ops for a bus 2) registers a bus notifier Instead, PCI devices are added to IOMMU groups from subsys_initcall_sync(tce_iommu_init) which does basically the same thing without using iommu_ops callbacks. However Freescale PAMU driver (https://lkml.org/lkml/2013/7/1/158) implements iommu_ops and when tce_iommu_init is called, every PCI device is already added to some group so there is a conflict. This patch does 2 things: 1. removes the loop in which PCI devices were added to groups and adds explicit iommu_add_device() calls to add devices as soon as they get the iommu_table pointer assigned to them. 2. moves a bus notifier to powernv code in order to avoid conflict with the notifier from Freescale driver. iommu_add_device() and iommu_del_device() are public now. Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/platforms/pseries/iommu.c')
-rw-r--r--arch/powerpc/platforms/pseries/iommu.c8
1 files changed, 5 insertions, 3 deletions
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
index f253361552ae..a80af6c20cba 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -687,7 +687,8 @@ static void pci_dma_dev_setup_pSeries(struct pci_dev *dev)
687 iommu_table_setparms(phb, dn, tbl); 687 iommu_table_setparms(phb, dn, tbl);
688 PCI_DN(dn)->iommu_table = iommu_init_table(tbl, phb->node); 688 PCI_DN(dn)->iommu_table = iommu_init_table(tbl, phb->node);
689 iommu_register_group(tbl, pci_domain_nr(phb->bus), 0); 689 iommu_register_group(tbl, pci_domain_nr(phb->bus), 0);
690 set_iommu_table_base(&dev->dev, PCI_DN(dn)->iommu_table); 690 set_iommu_table_base_and_group(&dev->dev,
691 PCI_DN(dn)->iommu_table);
691 return; 692 return;
692 } 693 }
693 694
@@ -699,7 +700,8 @@ static void pci_dma_dev_setup_pSeries(struct pci_dev *dev)
699 dn = dn->parent; 700 dn = dn->parent;
700 701
701 if (dn && PCI_DN(dn)) 702 if (dn && PCI_DN(dn))
702 set_iommu_table_base(&dev->dev, PCI_DN(dn)->iommu_table); 703 set_iommu_table_base_and_group(&dev->dev,
704 PCI_DN(dn)->iommu_table);
703 else 705 else
704 printk(KERN_WARNING "iommu: Device %s has no iommu table\n", 706 printk(KERN_WARNING "iommu: Device %s has no iommu table\n",
705 pci_name(dev)); 707 pci_name(dev));
@@ -1193,7 +1195,7 @@ static void pci_dma_dev_setup_pSeriesLP(struct pci_dev *dev)
1193 pr_debug(" found DMA window, table: %p\n", pci->iommu_table); 1195 pr_debug(" found DMA window, table: %p\n", pci->iommu_table);
1194 } 1196 }
1195 1197
1196 set_iommu_table_base(&dev->dev, pci->iommu_table); 1198 set_iommu_table_base_and_group(&dev->dev, pci->iommu_table);
1197} 1199}
1198 1200
1199static int dma_set_mask_pSeriesLP(struct device *dev, u64 dma_mask) 1201static int dma_set_mask_pSeriesLP(struct device *dev, u64 dma_mask)