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.c52
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
41static void tce_build_iSeries(struct iommu_table *tbl, long index, long npages, 44static 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
195static struct iommu_table veth_iommu_table;
196static struct iommu_table vio_iommu_table;
197
198void *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}
203EXPORT_SYMBOL_GPL(iseries_hv_alloc);
204
205void 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}
209EXPORT_SYMBOL_GPL(iseries_hv_free);
210
211dma_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
218void 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
224void __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
237struct 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
192void iommu_init_early_iSeries(void) 244void iommu_init_early_iSeries(void)
193{ 245{
194 ppc_md.tce_build = tce_build_iSeries; 246 ppc_md.tce_build = tce_build_iSeries;