aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/include/asm/device.h11
-rw-r--r--arch/powerpc/include/asm/dma-mapping.h10
-rw-r--r--arch/powerpc/include/asm/iommu.h10
-rw-r--r--arch/powerpc/kernel/dma-iommu.c16
-rw-r--r--arch/powerpc/kernel/pci-common.c2
-rw-r--r--arch/powerpc/kernel/vio.c2
-rw-r--r--arch/powerpc/platforms/cell/beat_iommu.c2
-rw-r--r--arch/powerpc/platforms/cell/iommu.c9
-rw-r--r--arch/powerpc/platforms/iseries/iommu.c2
-rw-r--r--arch/powerpc/platforms/pasemi/iommu.c2
-rw-r--r--arch/powerpc/platforms/pseries/iommu.c8
-rw-r--r--arch/powerpc/sysdev/dart_iommu.c2
12 files changed, 49 insertions, 27 deletions
diff --git a/arch/powerpc/include/asm/device.h b/arch/powerpc/include/asm/device.h
index 9dade15d1ab4..6d94d27ed850 100644
--- a/arch/powerpc/include/asm/device.h
+++ b/arch/powerpc/include/asm/device.h
@@ -15,7 +15,16 @@ struct dev_archdata {
15 15
16 /* DMA operations on that device */ 16 /* DMA operations on that device */
17 struct dma_map_ops *dma_ops; 17 struct dma_map_ops *dma_ops;
18 void *dma_data; 18
19 /*
20 * When an iommu is in use, dma_data is used as a ptr to the base of the
21 * iommu_table. Otherwise, it is a simple numerical offset.
22 */
23 union {
24 dma_addr_t dma_offset;
25 void *iommu_table_base;
26 } dma_data;
27
19#ifdef CONFIG_SWIOTLB 28#ifdef CONFIG_SWIOTLB
20 dma_addr_t max_direct_dma_addr; 29 dma_addr_t max_direct_dma_addr;
21#endif 30#endif
diff --git a/arch/powerpc/include/asm/dma-mapping.h b/arch/powerpc/include/asm/dma-mapping.h
index 34b919fe8cda..e281daebddca 100644
--- a/arch/powerpc/include/asm/dma-mapping.h
+++ b/arch/powerpc/include/asm/dma-mapping.h
@@ -97,14 +97,20 @@ static inline void set_dma_ops(struct device *dev, struct dma_map_ops *ops)
97 * swiotlb use this function, but it is typically not used by implementations 97 * swiotlb use this function, but it is typically not used by implementations
98 * with an iommu. 98 * with an iommu.
99 */ 99 */
100static inline unsigned long get_dma_offset(struct device *dev) 100static inline dma_addr_t get_dma_offset(struct device *dev)
101{ 101{
102 if (dev) 102 if (dev)
103 return (unsigned long)dev->archdata.dma_data; 103 return dev->archdata.dma_data.dma_offset;
104 104
105 return PCI_DRAM_OFFSET; 105 return PCI_DRAM_OFFSET;
106} 106}
107 107
108static inline void set_dma_offset(struct device *dev, dma_addr_t off)
109{
110 if (dev)
111 dev->archdata.dma_data.dma_offset = off;
112}
113
108/* this will be removed soon */ 114/* this will be removed soon */
109#define flush_write_buffers() 115#define flush_write_buffers()
110 116
diff --git a/arch/powerpc/include/asm/iommu.h b/arch/powerpc/include/asm/iommu.h
index 7464c0daddd1..edfc9803ec91 100644
--- a/arch/powerpc/include/asm/iommu.h
+++ b/arch/powerpc/include/asm/iommu.h
@@ -70,6 +70,16 @@ struct iommu_table {
70 70
71struct scatterlist; 71struct scatterlist;
72 72
73static inline void set_iommu_table_base(struct device *dev, void *base)
74{
75 dev->archdata.dma_data.iommu_table_base = base;
76}
77
78static inline void *get_iommu_table_base(struct device *dev)
79{
80 return dev->archdata.dma_data.iommu_table_base;
81}
82
73/* Frees table for an individual device node */ 83/* Frees table for an individual device node */
74extern void iommu_free_table(struct iommu_table *tbl, const char *node_name); 84extern void iommu_free_table(struct iommu_table *tbl, const char *node_name);
75 85
diff --git a/arch/powerpc/kernel/dma-iommu.c b/arch/powerpc/kernel/dma-iommu.c
index 87ddb3fb948c..37771a518119 100644
--- a/arch/powerpc/kernel/dma-iommu.c
+++ b/arch/powerpc/kernel/dma-iommu.c
@@ -18,7 +18,7 @@
18static void *dma_iommu_alloc_coherent(struct device *dev, size_t size, 18static void *dma_iommu_alloc_coherent(struct device *dev, size_t size,
19 dma_addr_t *dma_handle, gfp_t flag) 19 dma_addr_t *dma_handle, gfp_t flag)
20{ 20{
21 return iommu_alloc_coherent(dev, dev->archdata.dma_data, size, 21 return iommu_alloc_coherent(dev, get_iommu_table_base(dev), size,
22 dma_handle, device_to_mask(dev), flag, 22 dma_handle, device_to_mask(dev), flag,
23 dev_to_node(dev)); 23 dev_to_node(dev));
24} 24}
@@ -26,7 +26,7 @@ static void *dma_iommu_alloc_coherent(struct device *dev, size_t size,
26static void dma_iommu_free_coherent(struct device *dev, size_t size, 26static void dma_iommu_free_coherent(struct device *dev, size_t size,
27 void *vaddr, dma_addr_t dma_handle) 27 void *vaddr, dma_addr_t dma_handle)
28{ 28{
29 iommu_free_coherent(dev->archdata.dma_data, size, vaddr, dma_handle); 29 iommu_free_coherent(get_iommu_table_base(dev), size, vaddr, dma_handle);
30} 30}
31 31
32/* Creates TCEs for a user provided buffer. The user buffer must be 32/* Creates TCEs for a user provided buffer. The user buffer must be
@@ -39,8 +39,8 @@ static dma_addr_t dma_iommu_map_page(struct device *dev, struct page *page,
39 enum dma_data_direction direction, 39 enum dma_data_direction direction,
40 struct dma_attrs *attrs) 40 struct dma_attrs *attrs)
41{ 41{
42 return iommu_map_page(dev, dev->archdata.dma_data, page, offset, size, 42 return iommu_map_page(dev, get_iommu_table_base(dev), page, offset,
43 device_to_mask(dev), direction, attrs); 43 size, device_to_mask(dev), direction, attrs);
44} 44}
45 45
46 46
@@ -48,7 +48,7 @@ static void dma_iommu_unmap_page(struct device *dev, dma_addr_t dma_handle,
48 size_t size, enum dma_data_direction direction, 48 size_t size, enum dma_data_direction direction,
49 struct dma_attrs *attrs) 49 struct dma_attrs *attrs)
50{ 50{
51 iommu_unmap_page(dev->archdata.dma_data, dma_handle, size, direction, 51 iommu_unmap_page(get_iommu_table_base(dev), dma_handle, size, direction,
52 attrs); 52 attrs);
53} 53}
54 54
@@ -57,7 +57,7 @@ static int dma_iommu_map_sg(struct device *dev, struct scatterlist *sglist,
57 int nelems, enum dma_data_direction direction, 57 int nelems, enum dma_data_direction direction,
58 struct dma_attrs *attrs) 58 struct dma_attrs *attrs)
59{ 59{
60 return iommu_map_sg(dev, dev->archdata.dma_data, sglist, nelems, 60 return iommu_map_sg(dev, get_iommu_table_base(dev), sglist, nelems,
61 device_to_mask(dev), direction, attrs); 61 device_to_mask(dev), direction, attrs);
62} 62}
63 63
@@ -65,14 +65,14 @@ static void dma_iommu_unmap_sg(struct device *dev, struct scatterlist *sglist,
65 int nelems, enum dma_data_direction direction, 65 int nelems, enum dma_data_direction direction,
66 struct dma_attrs *attrs) 66 struct dma_attrs *attrs)
67{ 67{
68 iommu_unmap_sg(dev->archdata.dma_data, sglist, nelems, direction, 68 iommu_unmap_sg(get_iommu_table_base(dev), sglist, nelems, direction,
69 attrs); 69 attrs);
70} 70}
71 71
72/* We support DMA to/from any memory page via the iommu */ 72/* We support DMA to/from any memory page via the iommu */
73static int dma_iommu_dma_supported(struct device *dev, u64 mask) 73static int dma_iommu_dma_supported(struct device *dev, u64 mask)
74{ 74{
75 struct iommu_table *tbl = dev->archdata.dma_data; 75 struct iommu_table *tbl = get_iommu_table_base(dev);
76 76
77 if (!tbl || tbl->it_offset > mask) { 77 if (!tbl || tbl->it_offset > mask) {
78 printk(KERN_INFO 78 printk(KERN_INFO
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index e9f4840096b3..bb8209e34931 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -1117,7 +1117,7 @@ void __devinit pcibios_setup_bus_devices(struct pci_bus *bus)
1117 1117
1118 /* Hook up default DMA ops */ 1118 /* Hook up default DMA ops */
1119 sd->dma_ops = pci_dma_ops; 1119 sd->dma_ops = pci_dma_ops;
1120 sd->dma_data = (void *)PCI_DRAM_OFFSET; 1120 set_dma_offset(&dev->dev, PCI_DRAM_OFFSET);
1121 1121
1122 /* Additional platform DMA/iommu setup */ 1122 /* Additional platform DMA/iommu setup */
1123 if (ppc_md.pci_dma_dev_setup) 1123 if (ppc_md.pci_dma_dev_setup)
diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c
index 1b4f674ad7c4..77f64218abf3 100644
--- a/arch/powerpc/kernel/vio.c
+++ b/arch/powerpc/kernel/vio.c
@@ -1235,7 +1235,7 @@ struct vio_dev *vio_register_device_node(struct device_node *of_node)
1235 vio_cmo_set_dma_ops(viodev); 1235 vio_cmo_set_dma_ops(viodev);
1236 else 1236 else
1237 viodev->dev.archdata.dma_ops = &dma_iommu_ops; 1237 viodev->dev.archdata.dma_ops = &dma_iommu_ops;
1238 viodev->dev.archdata.dma_data = vio_build_iommu_table(viodev); 1238 set_iommu_table_base(&viodev->dev, vio_build_iommu_table(viodev));
1239 set_dev_node(&viodev->dev, of_node_to_nid(of_node)); 1239 set_dev_node(&viodev->dev, of_node_to_nid(of_node));
1240 1240
1241 /* init generic 'struct device' fields: */ 1241 /* init generic 'struct device' fields: */
diff --git a/arch/powerpc/platforms/cell/beat_iommu.c b/arch/powerpc/platforms/cell/beat_iommu.c
index 93b0efddd658..39d361c5c6d2 100644
--- a/arch/powerpc/platforms/cell/beat_iommu.c
+++ b/arch/powerpc/platforms/cell/beat_iommu.c
@@ -77,7 +77,7 @@ static void __init celleb_init_direct_mapping(void)
77static void celleb_dma_dev_setup(struct device *dev) 77static void celleb_dma_dev_setup(struct device *dev)
78{ 78{
79 dev->archdata.dma_ops = get_pci_dma_ops(); 79 dev->archdata.dma_ops = get_pci_dma_ops();
80 dev->archdata.dma_data = (void *)celleb_dma_direct_offset; 80 set_dma_offset(dev, celleb_dma_direct_offset);
81} 81}
82 82
83static void celleb_pci_dma_dev_setup(struct pci_dev *pdev) 83static void celleb_pci_dma_dev_setup(struct pci_dev *pdev)
diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c
index 416db17eb18f..ca5bfdfe47f2 100644
--- a/arch/powerpc/platforms/cell/iommu.c
+++ b/arch/powerpc/platforms/cell/iommu.c
@@ -657,15 +657,13 @@ static void cell_dma_dev_setup_fixed(struct device *dev);
657 657
658static void cell_dma_dev_setup(struct device *dev) 658static void cell_dma_dev_setup(struct device *dev)
659{ 659{
660 struct dev_archdata *archdata = &dev->archdata;
661
662 /* Order is important here, these are not mutually exclusive */ 660 /* Order is important here, these are not mutually exclusive */
663 if (get_dma_ops(dev) == &dma_iommu_fixed_ops) 661 if (get_dma_ops(dev) == &dma_iommu_fixed_ops)
664 cell_dma_dev_setup_fixed(dev); 662 cell_dma_dev_setup_fixed(dev);
665 else if (get_pci_dma_ops() == &dma_iommu_ops) 663 else if (get_pci_dma_ops() == &dma_iommu_ops)
666 archdata->dma_data = cell_get_iommu_table(dev); 664 set_iommu_table_base(dev, cell_get_iommu_table(dev));
667 else if (get_pci_dma_ops() == &dma_direct_ops) 665 else if (get_pci_dma_ops() == &dma_direct_ops)
668 archdata->dma_data = (void *)cell_dma_direct_offset; 666 set_dma_offset(dev, cell_dma_direct_offset);
669 else 667 else
670 BUG(); 668 BUG();
671} 669}
@@ -973,11 +971,10 @@ static int dma_set_mask_and_switch(struct device *dev, u64 dma_mask)
973 971
974static void cell_dma_dev_setup_fixed(struct device *dev) 972static void cell_dma_dev_setup_fixed(struct device *dev)
975{ 973{
976 struct dev_archdata *archdata = &dev->archdata;
977 u64 addr; 974 u64 addr;
978 975
979 addr = cell_iommu_get_fixed_address(dev) + dma_iommu_fixed_base; 976 addr = cell_iommu_get_fixed_address(dev) + dma_iommu_fixed_base;
980 archdata->dma_data = (void *)addr; 977 set_dma_offset(dev, addr);
981 978
982 dev_dbg(dev, "iommu: fixed addr = %llx\n", addr); 979 dev_dbg(dev, "iommu: fixed addr = %llx\n", addr);
983} 980}
diff --git a/arch/powerpc/platforms/iseries/iommu.c b/arch/powerpc/platforms/iseries/iommu.c
index 6c1e1011959e..9d53cb481a7c 100644
--- a/arch/powerpc/platforms/iseries/iommu.c
+++ b/arch/powerpc/platforms/iseries/iommu.c
@@ -193,7 +193,7 @@ static void pci_dma_dev_setup_iseries(struct pci_dev *pdev)
193 pdn->iommu_table = iommu_init_table(tbl, -1); 193 pdn->iommu_table = iommu_init_table(tbl, -1);
194 else 194 else
195 kfree(tbl); 195 kfree(tbl);
196 pdev->dev.archdata.dma_data = pdn->iommu_table; 196 set_iommu_table_base(&pdev->dev, pdn->iommu_table);
197} 197}
198#else 198#else
199#define pci_dma_dev_setup_iseries NULL 199#define pci_dma_dev_setup_iseries NULL
diff --git a/arch/powerpc/platforms/pasemi/iommu.c b/arch/powerpc/platforms/pasemi/iommu.c
index a0ff03a3d8da..7b1d608ea3c8 100644
--- a/arch/powerpc/platforms/pasemi/iommu.c
+++ b/arch/powerpc/platforms/pasemi/iommu.c
@@ -189,7 +189,7 @@ static void pci_dma_dev_setup_pasemi(struct pci_dev *dev)
189 } 189 }
190#endif 190#endif
191 191
192 dev->dev.archdata.dma_data = &iommu_table_iobmap; 192 set_iommu_table_base(&dev->dev, &iommu_table_iobmap);
193} 193}
194 194
195static void pci_dma_bus_setup_null(struct pci_bus *b) { } 195static void pci_dma_bus_setup_null(struct pci_bus *b) { }
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
index 661c8e02bcba..1a0000a4b6d6 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -482,7 +482,7 @@ static void pci_dma_dev_setup_pSeries(struct pci_dev *dev)
482 phb->node); 482 phb->node);
483 iommu_table_setparms(phb, dn, tbl); 483 iommu_table_setparms(phb, dn, tbl);
484 PCI_DN(dn)->iommu_table = iommu_init_table(tbl, phb->node); 484 PCI_DN(dn)->iommu_table = iommu_init_table(tbl, phb->node);
485 dev->dev.archdata.dma_data = PCI_DN(dn)->iommu_table; 485 set_iommu_table_base(&dev->dev, PCI_DN(dn)->iommu_table);
486 return; 486 return;
487 } 487 }
488 488
@@ -494,7 +494,7 @@ static void pci_dma_dev_setup_pSeries(struct pci_dev *dev)
494 dn = dn->parent; 494 dn = dn->parent;
495 495
496 if (dn && PCI_DN(dn)) 496 if (dn && PCI_DN(dn))
497 dev->dev.archdata.dma_data = PCI_DN(dn)->iommu_table; 497 set_iommu_table_base(&dev->dev, PCI_DN(dn)->iommu_table);
498 else 498 else
499 printk(KERN_WARNING "iommu: Device %s has no iommu table\n", 499 printk(KERN_WARNING "iommu: Device %s has no iommu table\n",
500 pci_name(dev)); 500 pci_name(dev));
@@ -538,7 +538,7 @@ static void pci_dma_dev_setup_pSeriesLP(struct pci_dev *dev)
538 */ 538 */
539 if (dma_window == NULL || pdn->parent == NULL) { 539 if (dma_window == NULL || pdn->parent == NULL) {
540 pr_debug(" no dma window for device, linking to parent\n"); 540 pr_debug(" no dma window for device, linking to parent\n");
541 dev->dev.archdata.dma_data = PCI_DN(pdn)->iommu_table; 541 set_iommu_table_base(&dev->dev, PCI_DN(pdn)->iommu_table);
542 return; 542 return;
543 } 543 }
544 544
@@ -554,7 +554,7 @@ static void pci_dma_dev_setup_pSeriesLP(struct pci_dev *dev)
554 pr_debug(" found DMA window, table: %p\n", pci->iommu_table); 554 pr_debug(" found DMA window, table: %p\n", pci->iommu_table);
555 } 555 }
556 556
557 dev->dev.archdata.dma_data = pci->iommu_table; 557 set_iommu_table_base(&dev->dev, pci->iommu_table);
558} 558}
559#else /* CONFIG_PCI */ 559#else /* CONFIG_PCI */
560#define pci_dma_bus_setup_pSeries NULL 560#define pci_dma_bus_setup_pSeries NULL
diff --git a/arch/powerpc/sysdev/dart_iommu.c b/arch/powerpc/sysdev/dart_iommu.c
index 89639ecbf381..ae3c4db86fe8 100644
--- a/arch/powerpc/sysdev/dart_iommu.c
+++ b/arch/powerpc/sysdev/dart_iommu.c
@@ -297,7 +297,7 @@ static void pci_dma_dev_setup_dart(struct pci_dev *dev)
297 /* We only have one iommu table on the mac for now, which makes 297 /* We only have one iommu table on the mac for now, which makes
298 * things simple. Setup all PCI devices to point to this table 298 * things simple. Setup all PCI devices to point to this table
299 */ 299 */
300 dev->dev.archdata.dma_data = &iommu_table_dart; 300 set_iommu_table_base(&dev->dev, &iommu_table_dart);
301} 301}
302 302
303static void pci_dma_bus_setup_dart(struct pci_bus *bus) 303static void pci_dma_bus_setup_dart(struct pci_bus *bus)