diff options
Diffstat (limited to 'arch/powerpc/platforms/iseries/iommu.c')
-rw-r--r-- | arch/powerpc/platforms/iseries/iommu.c | 27 |
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 | ||
178 | void iommu_devnode_init_iSeries(struct device_node *dn) | 170 | void 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 | ||
199 | static void iommu_dev_setup_iSeries(struct pci_dev *dev) { } | ||
200 | static void iommu_bus_setup_iSeries(struct pci_bus *bus) { } | ||
201 | |||
202 | void iommu_init_early_iSeries(void) | 192 | void 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 | } |