aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/iseries/iommu.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/platforms/iseries/iommu.c')
-rw-r--r--arch/powerpc/platforms/iseries/iommu.c27
1 files changed, 7 insertions, 20 deletions
diff --git a/arch/powerpc/platforms/iseries/iommu.c b/arch/powerpc/platforms/iseries/iommu.c
index f4cbbcf8773a..d7a756d5135c 100644
--- a/arch/powerpc/platforms/iseries/iommu.c
+++ b/arch/powerpc/platforms/iseries/iommu.c
@@ -27,6 +27,7 @@
27#include <linux/types.h> 27#include <linux/types.h>
28#include <linux/dma-mapping.h> 28#include <linux/dma-mapping.h>
29#include <linux/list.h> 29#include <linux/list.h>
30#include <linux/pci.h>
30 31
31#include <asm/iommu.h> 32#include <asm/iommu.h>
32#include <asm/tce.h> 33#include <asm/tce.h>
@@ -43,9 +44,6 @@ static void tce_build_iSeries(struct iommu_table *tbl, long index, long npages,
43 u64 rc; 44 u64 rc;
44 u64 tce, rpn; 45 u64 tce, rpn;
45 46
46 index <<= TCE_PAGE_FACTOR;
47 npages <<= TCE_PAGE_FACTOR;
48
49 while (npages--) { 47 while (npages--) {
50 rpn = virt_to_abs(uaddr) >> TCE_SHIFT; 48 rpn = virt_to_abs(uaddr) >> TCE_SHIFT;
51 tce = (rpn & TCE_RPN_MASK) << TCE_RPN_SHIFT; 49 tce = (rpn & TCE_RPN_MASK) << TCE_RPN_SHIFT;
@@ -75,9 +73,6 @@ static void tce_free_iSeries(struct iommu_table *tbl, long index, long npages)
75{ 73{
76 u64 rc; 74 u64 rc;
77 75
78 npages <<= TCE_PAGE_FACTOR;
79 index <<= TCE_PAGE_FACTOR;
80
81 while (npages--) { 76 while (npages--) {
82 rc = HvCallXm_setTce((u64)tbl->it_index, (u64)index, 0); 77 rc = HvCallXm_setTce((u64)tbl->it_index, (u64)index, 0);
83 if (rc) 78 if (rc)
@@ -120,12 +115,10 @@ void iommu_table_getparms_iSeries(unsigned long busno,
120{ 115{
121 struct iommu_table_cb *parms; 116 struct iommu_table_cb *parms;
122 117
123 parms = kmalloc(sizeof(*parms), GFP_KERNEL); 118 parms = kzalloc(sizeof(*parms), GFP_KERNEL);
124 if (parms == NULL) 119 if (parms == NULL)
125 panic("PCI_DMA: TCE Table Allocation failed."); 120 panic("PCI_DMA: TCE Table Allocation failed.");
126 121
127 memset(parms, 0, sizeof(*parms));
128
129 parms->itc_busno = busno; 122 parms->itc_busno = busno;
130 parms->itc_slotno = slotno; 123 parms->itc_slotno = slotno;
131 parms->itc_virtbus = virtbus; 124 parms->itc_virtbus = virtbus;
@@ -136,10 +129,9 @@ void iommu_table_getparms_iSeries(unsigned long busno,
136 panic("PCI_DMA: parms->size is zero, parms is 0x%p", parms); 129 panic("PCI_DMA: parms->size is zero, parms is 0x%p", parms);
137 130
138 /* itc_size is in pages worth of table, it_size is in # of entries */ 131 /* itc_size is in pages worth of table, it_size is in # of entries */
139 tbl->it_size = ((parms->itc_size * TCE_PAGE_SIZE) / 132 tbl->it_size = (parms->itc_size * TCE_PAGE_SIZE) / TCE_ENTRY_SIZE;
140 TCE_ENTRY_SIZE) >> TCE_PAGE_FACTOR;
141 tbl->it_busno = parms->itc_busno; 133 tbl->it_busno = parms->itc_busno;
142 tbl->it_offset = parms->itc_offset >> TCE_PAGE_FACTOR; 134 tbl->it_offset = parms->itc_offset;
143 tbl->it_index = parms->itc_index; 135 tbl->it_index = parms->itc_index;
144 tbl->it_blocksize = 1; 136 tbl->it_blocksize = 1;
145 tbl->it_type = virtbus ? TCE_VB : TCE_PCI; 137 tbl->it_type = virtbus ? TCE_VB : TCE_PCI;
@@ -175,7 +167,7 @@ static struct iommu_table *iommu_table_find(struct iommu_table * tbl)
175} 167}
176 168
177 169
178void iommu_devnode_init_iSeries(struct device_node *dn) 170void iommu_devnode_init_iSeries(struct pci_dev *pdev, struct device_node *dn)
179{ 171{
180 struct iommu_table *tbl; 172 struct iommu_table *tbl;
181 struct pci_dn *pdn = PCI_DN(dn); 173 struct pci_dn *pdn = PCI_DN(dn);
@@ -193,19 +185,14 @@ void iommu_devnode_init_iSeries(struct device_node *dn)
193 pdn->iommu_table = iommu_init_table(tbl, -1); 185 pdn->iommu_table = iommu_init_table(tbl, -1);
194 else 186 else
195 kfree(tbl); 187 kfree(tbl);
188 pdev->dev.archdata.dma_data = pdn->iommu_table;
196} 189}
197#endif 190#endif
198 191
199static void iommu_dev_setup_iSeries(struct pci_dev *dev) { }
200static void iommu_bus_setup_iSeries(struct pci_bus *bus) { }
201
202void iommu_init_early_iSeries(void) 192void iommu_init_early_iSeries(void)
203{ 193{
204 ppc_md.tce_build = tce_build_iSeries; 194 ppc_md.tce_build = tce_build_iSeries;
205 ppc_md.tce_free = tce_free_iSeries; 195 ppc_md.tce_free = tce_free_iSeries;
206 196
207 ppc_md.iommu_dev_setup = iommu_dev_setup_iSeries; 197 pci_dma_ops = &dma_iommu_ops;
208 ppc_md.iommu_bus_setup = iommu_bus_setup_iSeries;
209
210 pci_iommu_init();
211} 198}