diff options
Diffstat (limited to 'arch/powerpc/platforms/iseries/iommu.c')
-rw-r--r-- | arch/powerpc/platforms/iseries/iommu.c | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/arch/powerpc/platforms/iseries/iommu.c b/arch/powerpc/platforms/iseries/iommu.c index 3b6a9666c2..49e9c664ea 100644 --- a/arch/powerpc/platforms/iseries/iommu.c +++ b/arch/powerpc/platforms/iseries/iommu.c | |||
@@ -28,14 +28,17 @@ | |||
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 | #include <linux/pci.h> |
31 | #include <linux/module.h> | ||
31 | 32 | ||
32 | #include <asm/iommu.h> | 33 | #include <asm/iommu.h> |
34 | #include <asm/vio.h> | ||
33 | #include <asm/tce.h> | 35 | #include <asm/tce.h> |
34 | #include <asm/machdep.h> | 36 | #include <asm/machdep.h> |
35 | #include <asm/abs_addr.h> | 37 | #include <asm/abs_addr.h> |
36 | #include <asm/prom.h> | 38 | #include <asm/prom.h> |
37 | #include <asm/pci-bridge.h> | 39 | #include <asm/pci-bridge.h> |
38 | #include <asm/iseries/hv_call_xm.h> | 40 | #include <asm/iseries/hv_call_xm.h> |
41 | #include <asm/iseries/hv_call_event.h> | ||
39 | #include <asm/iseries/iommu.h> | 42 | #include <asm/iseries/iommu.h> |
40 | 43 | ||
41 | static void tce_build_iSeries(struct iommu_table *tbl, long index, long npages, | 44 | static void tce_build_iSeries(struct iommu_table *tbl, long index, long npages, |
@@ -189,6 +192,55 @@ void iommu_devnode_init_iSeries(struct pci_dev *pdev, struct device_node *dn) | |||
189 | } | 192 | } |
190 | #endif | 193 | #endif |
191 | 194 | ||
195 | static struct iommu_table veth_iommu_table; | ||
196 | static struct iommu_table vio_iommu_table; | ||
197 | |||
198 | void *iseries_hv_alloc(size_t size, dma_addr_t *dma_handle, gfp_t flag) | ||
199 | { | ||
200 | return iommu_alloc_coherent(&vio_iommu_table, size, dma_handle, | ||
201 | DMA_32BIT_MASK, flag, -1); | ||
202 | } | ||
203 | EXPORT_SYMBOL_GPL(iseries_hv_alloc); | ||
204 | |||
205 | void iseries_hv_free(size_t size, void *vaddr, dma_addr_t dma_handle) | ||
206 | { | ||
207 | iommu_free_coherent(&vio_iommu_table, size, vaddr, dma_handle); | ||
208 | } | ||
209 | EXPORT_SYMBOL_GPL(iseries_hv_free); | ||
210 | |||
211 | dma_addr_t iseries_hv_map(void *vaddr, size_t size, | ||
212 | enum dma_data_direction direction) | ||
213 | { | ||
214 | return iommu_map_single(&vio_iommu_table, vaddr, size, | ||
215 | DMA_32BIT_MASK, direction); | ||
216 | } | ||
217 | |||
218 | void iseries_hv_unmap(dma_addr_t dma_handle, size_t size, | ||
219 | enum dma_data_direction direction) | ||
220 | { | ||
221 | iommu_unmap_single(&vio_iommu_table, dma_handle, size, direction); | ||
222 | } | ||
223 | |||
224 | void __init iommu_vio_init(void) | ||
225 | { | ||
226 | iommu_table_getparms_iSeries(255, 0, 0xff, &veth_iommu_table); | ||
227 | veth_iommu_table.it_size /= 2; | ||
228 | vio_iommu_table = veth_iommu_table; | ||
229 | vio_iommu_table.it_offset += veth_iommu_table.it_size; | ||
230 | |||
231 | if (!iommu_init_table(&veth_iommu_table, -1)) | ||
232 | printk("Virtual Bus VETH TCE table failed.\n"); | ||
233 | if (!iommu_init_table(&vio_iommu_table, -1)) | ||
234 | printk("Virtual Bus VIO TCE table failed.\n"); | ||
235 | } | ||
236 | |||
237 | struct iommu_table *vio_build_iommu_table_iseries(struct vio_dev *dev) | ||
238 | { | ||
239 | if (strcmp(dev->type, "network") == 0) | ||
240 | return &veth_iommu_table; | ||
241 | return &vio_iommu_table; | ||
242 | } | ||
243 | |||
192 | void iommu_init_early_iSeries(void) | 244 | void iommu_init_early_iSeries(void) |
193 | { | 245 | { |
194 | ppc_md.tce_build = tce_build_iSeries; | 246 | ppc_md.tce_build = tce_build_iSeries; |